diff --git a/.gitignore b/.gitignore index a9a2852411..d318c02456 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,7 @@ runtime/Cpp/runtime/cmake_install.cmake runtime/Cpp/runtime/libantlr4-runtime.4.10.1.dylib runtime/Cpp/runtime/libantlr4-runtime.a runtime/Cpp/runtime/libantlr4-runtime.dylib +/runtime/Cpp/runtime/libantlr4-runtime.4.12.0.dylib + +# Go test and performance trace files +**/*.pprof \ No newline at end of file diff --git a/runtime/Go/antlr/internal/testrig/README.adoc b/runtime/Go/antlr/internal/testrig/README.adoc new file mode 100644 index 0000000000..b0aa899d00 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/README.adoc @@ -0,0 +1,3 @@ +# Test rig for go + +This test rig will build and run the grammar file test.g4 with the `input` file and turn on all tracing options. \ No newline at end of file diff --git a/runtime/Go/antlr/internal/testrig/antlr/generate.go b/runtime/Go/antlr/internal/testrig/antlr/generate.go new file mode 100644 index 0000000000..3318ee1907 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/antlr/generate.go @@ -0,0 +1,3 @@ +package antlr + +//go:generate ./generate.sh diff --git a/runtime/Go/antlr/internal/testrig/antlr/generate.sh b/runtime/Go/antlr/internal/testrig/antlr/generate.sh new file mode 100755 index 0000000000..3f33ed9e60 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/antlr/generate.sh @@ -0,0 +1,5 @@ +#!/bin/zsh + +alias antlr4='java -Xmx500M -cp "./antlr4-4.12.1-SNAPSHOT-complete.jar:$CLASSPATH" org.antlr.v4.Tool' + +antlr4 -Dlanguage=Go -visitor -listener -package test -o ../test *.g4 \ No newline at end of file diff --git a/runtime/Go/antlr/internal/testrig/antlr/test.g4 b/runtime/Go/antlr/internal/testrig/antlr/test.g4 new file mode 100644 index 0000000000..4af9bd52c0 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/antlr/test.g4 @@ -0,0 +1,14 @@ +grammar test; + +stat: expression + | IDENTIFIER ';' + ; + +expression + : expression (AND expression)+ + | IDENTIFIER + ; + +AND : 'and' ; +IDENTIFIER : [a-zA-Z_]+ ; +WS : [ \t\r\n]+ -> skip ; diff --git a/runtime/Go/antlr/internal/testrig/go.mod b/runtime/Go/antlr/internal/testrig/go.mod new file mode 100644 index 0000000000..43dcced6bc --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/go.mod @@ -0,0 +1,15 @@ +module testrig + +go 1.20 + +replace github.com/antlr/antlr4/runtime/Go/antlr/v4 => ../../v4 + +require ( + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df + github.com/pyroscope-io/client v0.6.0 +) + +require ( + github.com/pyroscope-io/godeltaprof v0.1.0 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect +) diff --git a/runtime/Go/antlr/internal/testrig/go.sum b/runtime/Go/antlr/internal/testrig/go.sum new file mode 100644 index 0000000000..54688cce8f --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/go.sum @@ -0,0 +1,6 @@ +github.com/pyroscope-io/client v0.6.0 h1:rcUFgcnfmuyVYDYT+4d0zfqc8YedOyruHSsUb9ImaBw= +github.com/pyroscope-io/client v0.6.0/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= +github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= +github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= diff --git a/runtime/Go/antlr/internal/testrig/input b/runtime/Go/antlr/internal/testrig/input new file mode 100644 index 0000000000..1dc60c7504 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/input @@ -0,0 +1 @@ +a and b diff --git a/runtime/Go/antlr/internal/testrig/test.go b/runtime/Go/antlr/internal/testrig/test.go new file mode 100644 index 0000000000..b964536821 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "testrig/test" +) + +func main() { + testRun("input") +} + +func testRun(inf string) { + + // Pre-initialize so that we can distinguish this initialization from the lexing nad parsing rules + test.TestLexerInit() + test.TestParserInit() + + input, _ := antlr.NewFileStream(inf) + lexer := test.NewtestLexer(input) + stream := antlr.NewCommonTokenStream(lexer, 0) + p := test.NewtestParser(stream) + p.Stat() +} diff --git a/runtime/Go/antlr/internal/testrig/test/test.interp b/runtime/Go/antlr/internal/testrig/test/test.interp new file mode 100644 index 0000000000..a4dd108473 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test.interp @@ -0,0 +1,21 @@ +token literal names: +null +';' +'and' +null +null + +token symbolic names: +null +null +AND +IDENTIFIER +WS + +rule names: +stat +expression + + +atn: +[4, 1, 4, 25, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 3, 0, 8, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 16, 8, 1, 11, 1, 12, 1, 17, 5, 1, 20, 8, 1, 10, 1, 12, 1, 23, 9, 1, 1, 1, 0, 1, 2, 2, 0, 2, 0, 0, 25, 0, 7, 1, 0, 0, 0, 2, 9, 1, 0, 0, 0, 4, 8, 3, 2, 1, 0, 5, 6, 5, 3, 0, 0, 6, 8, 5, 1, 0, 0, 7, 4, 1, 0, 0, 0, 7, 5, 1, 0, 0, 0, 8, 1, 1, 0, 0, 0, 9, 10, 6, 1, -1, 0, 10, 11, 5, 3, 0, 0, 11, 21, 1, 0, 0, 0, 12, 15, 10, 2, 0, 0, 13, 14, 5, 2, 0, 0, 14, 16, 3, 2, 1, 0, 15, 13, 1, 0, 0, 0, 16, 17, 1, 0, 0, 0, 17, 15, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 20, 1, 0, 0, 0, 19, 12, 1, 0, 0, 0, 20, 23, 1, 0, 0, 0, 21, 19, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 3, 1, 0, 0, 0, 23, 21, 1, 0, 0, 0, 3, 7, 17, 21] \ No newline at end of file diff --git a/runtime/Go/antlr/internal/testrig/test/test.tokens b/runtime/Go/antlr/internal/testrig/test/test.tokens new file mode 100644 index 0000000000..d5fdd325a0 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test.tokens @@ -0,0 +1,6 @@ +T__0=1 +AND=2 +IDENTIFIER=3 +WS=4 +';'=1 +'and'=2 diff --git a/runtime/Go/antlr/internal/testrig/test/testLexer.interp b/runtime/Go/antlr/internal/testrig/test/testLexer.interp new file mode 100644 index 0000000000..cc85c34228 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/testLexer.interp @@ -0,0 +1,29 @@ +token literal names: +null +';' +'and' +null +null + +token symbolic names: +null +null +AND +IDENTIFIER +WS + +rule names: +T__0 +AND +IDENTIFIER +WS + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 4, 27, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 17, 8, 2, 11, 2, 12, 2, 18, 1, 3, 4, 3, 22, 8, 3, 11, 3, 12, 3, 23, 1, 3, 1, 3, 0, 0, 4, 1, 1, 3, 2, 5, 3, 7, 4, 1, 0, 2, 3, 0, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 28, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 1, 9, 1, 0, 0, 0, 3, 11, 1, 0, 0, 0, 5, 16, 1, 0, 0, 0, 7, 21, 1, 0, 0, 0, 9, 10, 5, 59, 0, 0, 10, 2, 1, 0, 0, 0, 11, 12, 5, 97, 0, 0, 12, 13, 5, 110, 0, 0, 13, 14, 5, 100, 0, 0, 14, 4, 1, 0, 0, 0, 15, 17, 7, 0, 0, 0, 16, 15, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 6, 1, 0, 0, 0, 20, 22, 7, 1, 0, 0, 21, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 21, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 25, 1, 0, 0, 0, 25, 26, 6, 3, 0, 0, 26, 8, 1, 0, 0, 0, 3, 0, 18, 23, 1, 6, 0, 0] \ No newline at end of file diff --git a/runtime/Go/antlr/internal/testrig/test/testLexer.tokens b/runtime/Go/antlr/internal/testrig/test/testLexer.tokens new file mode 100644 index 0000000000..d5fdd325a0 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/testLexer.tokens @@ -0,0 +1,6 @@ +T__0=1 +AND=2 +IDENTIFIER=3 +WS=4 +';'=1 +'and'=2 diff --git a/runtime/Go/antlr/internal/testrig/test/test_base_listener.go b/runtime/Go/antlr/internal/testrig/test/test_base_listener.go new file mode 100644 index 0000000000..ea9dd71906 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_base_listener.go @@ -0,0 +1,33 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test // test +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" + +// BasetestListener is a complete listener for a parse tree produced by testParser. +type BasetestListener struct{} + +var _ testListener = &BasetestListener{} + +// VisitTerminal is called when a terminal node is visited. +func (s *BasetestListener) VisitTerminal(node antlr.TerminalNode) {} + +// VisitErrorNode is called when an error node is visited. +func (s *BasetestListener) VisitErrorNode(node antlr.ErrorNode) {} + +// EnterEveryRule is called when any rule is entered. +func (s *BasetestListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} + +// ExitEveryRule is called when any rule is exited. +func (s *BasetestListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} + +// EnterStat is called when production stat is entered. +func (s *BasetestListener) EnterStat(ctx *StatContext) {} + +// ExitStat is called when production stat is exited. +func (s *BasetestListener) ExitStat(ctx *StatContext) {} + +// EnterExpression is called when production expression is entered. +func (s *BasetestListener) EnterExpression(ctx *ExpressionContext) {} + +// ExitExpression is called when production expression is exited. +func (s *BasetestListener) ExitExpression(ctx *ExpressionContext) {} diff --git a/runtime/Go/antlr/internal/testrig/test/test_base_visitor.go b/runtime/Go/antlr/internal/testrig/test/test_base_visitor.go new file mode 100644 index 0000000000..0acd854c17 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_base_visitor.go @@ -0,0 +1,16 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test // test +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" + +type BasetestVisitor struct { + *antlr.BaseParseTreeVisitor +} + +func (v *BasetestVisitor) VisitStat(ctx *StatContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasetestVisitor) VisitExpression(ctx *ExpressionContext) interface{} { + return v.VisitChildren(ctx) +} diff --git a/runtime/Go/antlr/internal/testrig/test/test_lexer.go b/runtime/Go/antlr/internal/testrig/test/test_lexer.go new file mode 100644 index 0000000000..8a4cbeed17 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_lexer.go @@ -0,0 +1,114 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test + +import ( + "fmt" + "sync" + "unicode" + + "github.com/antlr/antlr4/runtime/Go/antlr/v4" +) + +// Suppress unused import error +var _ = fmt.Printf +var _ = sync.Once{} +var _ = unicode.IsLetter + +type testLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +var testlexerLexerStaticData struct { + once sync.Once + serializedATN []int32 + channelNames []string + modeNames []string + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func testlexerLexerInit() { + staticData := &testlexerLexerStaticData + staticData.channelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + } + staticData.modeNames = []string{ + "DEFAULT_MODE", + } + staticData.literalNames = []string{ + "", "';'", "'and'", + } + staticData.symbolicNames = []string{ + "", "", "AND", "IDENTIFIER", "WS", + } + staticData.ruleNames = []string{ + "T__0", "AND", "IDENTIFIER", "WS", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 0, 4, 27, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 17, 8, 2, 11, 2, 12, 2, 18, + 1, 3, 4, 3, 22, 8, 3, 11, 3, 12, 3, 23, 1, 3, 1, 3, 0, 0, 4, 1, 1, 3, 2, + 5, 3, 7, 4, 1, 0, 2, 3, 0, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, + 32, 32, 28, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, + 1, 0, 0, 0, 1, 9, 1, 0, 0, 0, 3, 11, 1, 0, 0, 0, 5, 16, 1, 0, 0, 0, 7, + 21, 1, 0, 0, 0, 9, 10, 5, 59, 0, 0, 10, 2, 1, 0, 0, 0, 11, 12, 5, 97, 0, + 0, 12, 13, 5, 110, 0, 0, 13, 14, 5, 100, 0, 0, 14, 4, 1, 0, 0, 0, 15, 17, + 7, 0, 0, 0, 16, 15, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, + 18, 19, 1, 0, 0, 0, 19, 6, 1, 0, 0, 0, 20, 22, 7, 1, 0, 0, 21, 20, 1, 0, + 0, 0, 22, 23, 1, 0, 0, 0, 23, 21, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 25, + 1, 0, 0, 0, 25, 26, 6, 3, 0, 0, 26, 8, 1, 0, 0, 0, 3, 0, 18, 23, 1, 6, + 0, 0, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// testLexerInit initializes any static state used to implement testLexer. By default the +// static state used to implement the lexer is lazily initialized during the first call to +// NewtestLexer(). You can call this function if you wish to initialize the static state ahead +// of time. +func TestLexerInit() { + staticData := &testlexerLexerStaticData + staticData.once.Do(testlexerLexerInit) +} + +// NewtestLexer produces a new lexer instance for the optional input antlr.CharStream. +func NewtestLexer(input antlr.CharStream) *testLexer { + TestLexerInit() + l := new(testLexer) + l.BaseLexer = antlr.NewBaseLexer(input) + staticData := &testlexerLexerStaticData + l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + l.channelNames = staticData.channelNames + l.modeNames = staticData.modeNames + l.RuleNames = staticData.ruleNames + l.LiteralNames = staticData.literalNames + l.SymbolicNames = staticData.symbolicNames + l.GrammarFileName = "test.g4" + // TODO: l.EOF = antlr.TokenEOF + + return l +} + +// testLexer tokens. +const ( + testLexerT__0 = 1 + testLexerAND = 2 + testLexerIDENTIFIER = 3 + testLexerWS = 4 +) diff --git a/runtime/Go/antlr/internal/testrig/test/test_listener.go b/runtime/Go/antlr/internal/testrig/test/test_listener.go new file mode 100644 index 0000000000..55179eac12 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_listener.go @@ -0,0 +1,21 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test // test +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" + +// testListener is a complete listener for a parse tree produced by testParser. +type testListener interface { + antlr.ParseTreeListener + + // EnterStat is called when entering the stat production. + EnterStat(c *StatContext) + + // EnterExpression is called when entering the expression production. + EnterExpression(c *ExpressionContext) + + // ExitStat is called when exiting the stat production. + ExitStat(c *StatContext) + + // ExitExpression is called when exiting the expression production. + ExitExpression(c *ExpressionContext) +} diff --git a/runtime/Go/antlr/internal/testrig/test/test_parser.go b/runtime/Go/antlr/internal/testrig/test/test_parser.go new file mode 100644 index 0000000000..b24e32ddfb --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_parser.go @@ -0,0 +1,490 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test // test +import ( + "fmt" + "strconv" + "sync" + + "github.com/antlr/antlr4/runtime/Go/antlr/v4" +) + +// Suppress unused import errors +var _ = fmt.Printf +var _ = strconv.Itoa +var _ = sync.Once{} + +type testParser struct { + *antlr.BaseParser +} + +var testParserStaticData struct { + once sync.Once + serializedATN []int32 + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func testParserInit() { + staticData := &testParserStaticData + staticData.literalNames = []string{ + "", "';'", "'and'", + } + staticData.symbolicNames = []string{ + "", "", "AND", "IDENTIFIER", "WS", + } + staticData.ruleNames = []string{ + "stat", "expression", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 1, 4, 25, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 3, 0, 8, 8, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 16, 8, 1, 11, 1, 12, 1, 17, 5, 1, + 20, 8, 1, 10, 1, 12, 1, 23, 9, 1, 1, 1, 0, 1, 2, 2, 0, 2, 0, 0, 25, 0, + 7, 1, 0, 0, 0, 2, 9, 1, 0, 0, 0, 4, 8, 3, 2, 1, 0, 5, 6, 5, 3, 0, 0, 6, + 8, 5, 1, 0, 0, 7, 4, 1, 0, 0, 0, 7, 5, 1, 0, 0, 0, 8, 1, 1, 0, 0, 0, 9, + 10, 6, 1, -1, 0, 10, 11, 5, 3, 0, 0, 11, 21, 1, 0, 0, 0, 12, 15, 10, 2, + 0, 0, 13, 14, 5, 2, 0, 0, 14, 16, 3, 2, 1, 0, 15, 13, 1, 0, 0, 0, 16, 17, + 1, 0, 0, 0, 17, 15, 1, 0, 0, 0, 17, 18, 1, 0, 0, 0, 18, 20, 1, 0, 0, 0, + 19, 12, 1, 0, 0, 0, 20, 23, 1, 0, 0, 0, 21, 19, 1, 0, 0, 0, 21, 22, 1, + 0, 0, 0, 22, 3, 1, 0, 0, 0, 23, 21, 1, 0, 0, 0, 3, 7, 17, 21, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// testParserInit initializes any static state used to implement testParser. By default the +// static state used to implement the parser is lazily initialized during the first call to +// NewtestParser(). You can call this function if you wish to initialize the static state ahead +// of time. +func TestParserInit() { + staticData := &testParserStaticData + staticData.once.Do(testParserInit) +} + +// NewtestParser produces a new parser instance for the optional input antlr.TokenStream. +func NewtestParser(input antlr.TokenStream) *testParser { + TestParserInit() + this := new(testParser) + this.BaseParser = antlr.NewBaseParser(input) + staticData := &testParserStaticData + this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + this.RuleNames = staticData.ruleNames + this.LiteralNames = staticData.literalNames + this.SymbolicNames = staticData.symbolicNames + this.GrammarFileName = "test.g4" + + return this +} + +// testParser tokens. +const ( + testParserEOF = antlr.TokenEOF + testParserT__0 = 1 + testParserAND = 2 + testParserIDENTIFIER = 3 + testParserWS = 4 +) + +// testParser rules. +const ( + testParserRULE_stat = 0 + testParserRULE_expression = 1 +) + +// IStatContext is an interface to support dynamic dispatch. +type IStatContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + Expression() IExpressionContext + IDENTIFIER() antlr.TerminalNode + + // IsStatContext differentiates from other interfaces. + IsStatContext() +} + +type StatContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyStatContext() *StatContext { + var p = new(StatContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = testParserRULE_stat + return p +} + +func (*StatContext) IsStatContext() {} + +func NewStatContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StatContext { + var p = new(StatContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = testParserRULE_stat + + return p +} + +func (s *StatContext) GetParser() antlr.Parser { return s.parser } + +func (s *StatContext) Expression() IExpressionContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExpressionContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExpressionContext) +} + +func (s *StatContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(testParserIDENTIFIER, 0) +} + +func (s *StatContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *StatContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *StatContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(testListener); ok { + listenerT.EnterStat(s) + } +} + +func (s *StatContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(testListener); ok { + listenerT.ExitStat(s) + } +} + +func (s *StatContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case testVisitor: + return t.VisitStat(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *testParser) Stat() (localctx IStatContext) { + this := p + _ = this + + localctx = NewStatContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 0, testParserRULE_stat) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.SetState(7) + p.GetErrorHandler().Sync(p) + switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) { + case 1: + p.EnterOuterAlt(localctx, 1) + { + p.SetState(4) + p.expression(0) + } + + case 2: + p.EnterOuterAlt(localctx, 2) + { + p.SetState(5) + p.Match(testParserIDENTIFIER) + } + { + p.SetState(6) + p.Match(testParserT__0) + } + + } + + return localctx +} + +// IExpressionContext is an interface to support dynamic dispatch. +type IExpressionContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // Getter signatures + IDENTIFIER() antlr.TerminalNode + AllExpression() []IExpressionContext + Expression(i int) IExpressionContext + AllAND() []antlr.TerminalNode + AND(i int) antlr.TerminalNode + + // IsExpressionContext differentiates from other interfaces. + IsExpressionContext() +} + +type ExpressionContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyExpressionContext() *ExpressionContext { + var p = new(ExpressionContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = testParserRULE_expression + return p +} + +func (*ExpressionContext) IsExpressionContext() {} + +func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext { + var p = new(ExpressionContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = testParserRULE_expression + + return p +} + +func (s *ExpressionContext) GetParser() antlr.Parser { return s.parser } + +func (s *ExpressionContext) IDENTIFIER() antlr.TerminalNode { + return s.GetToken(testParserIDENTIFIER, 0) +} + +func (s *ExpressionContext) AllExpression() []IExpressionContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExpressionContext); ok { + len++ + } + } + + tst := make([]IExpressionContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExpressionContext); ok { + tst[i] = t.(IExpressionContext) + i++ + } + } + + return tst +} + +func (s *ExpressionContext) Expression(i int) IExpressionContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExpressionContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExpressionContext) +} + +func (s *ExpressionContext) AllAND() []antlr.TerminalNode { + return s.GetTokens(testParserAND) +} + +func (s *ExpressionContext) AND(i int) antlr.TerminalNode { + return s.GetToken(testParserAND, i) +} + +func (s *ExpressionContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *ExpressionContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(testListener); ok { + listenerT.EnterExpression(s) + } +} + +func (s *ExpressionContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(testListener); ok { + listenerT.ExitExpression(s) + } +} + +func (s *ExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case testVisitor: + return t.VisitExpression(s) + + default: + return t.VisitChildren(s) + } +} + +func (p *testParser) Expression() (localctx IExpressionContext) { + return p.expression(0) +} + +func (p *testParser) expression(_p int) (localctx IExpressionContext) { + this := p + _ = this + + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() + _parentState := p.GetState() + localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState) + var _prevctx IExpressionContext = localctx + var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. + _startState := 2 + p.EnterRecursionRule(localctx, 2, testParserRULE_expression, _p) + + defer func() { + p.UnrollRecursionContexts(_parentctx) + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + var _alt int + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(10) + p.Match(testParserIDENTIFIER) + } + + p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) + p.SetState(21) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) + + for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + if _alt == 1 { + if p.GetParseListeners() != nil { + p.TriggerExitRuleEvent() + } + _prevctx = localctx + localctx = NewExpressionContext(p, _parentctx, _parentState) + p.PushNewRecursionContext(localctx, _startState, testParserRULE_expression) + p.SetState(12) + + if !(p.Precpred(p.GetParserRuleContext(), 2)) { + panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) + } + p.SetState(15) + p.GetErrorHandler().Sync(p) + _alt = 1 + for ok := true; ok; ok = _alt != 2 && _alt != antlr.ATNInvalidAltNumber { + switch _alt { + case 1: + { + p.SetState(13) + p.Match(testParserAND) + } + { + p.SetState(14) + p.expression(0) + } + + default: + panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) + } + + p.SetState(17) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) + } + + } + p.SetState(23) + p.GetErrorHandler().Sync(p) + _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) + } + + return localctx +} + +func (p *testParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool { + switch ruleIndex { + case 1: + var t *ExpressionContext = nil + if localctx != nil { + t = localctx.(*ExpressionContext) + } + return p.Expression_Sempred(t, predIndex) + + default: + panic("No predicate with index: " + fmt.Sprint(ruleIndex)) + } +} + +func (p *testParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool { + this := p + _ = this + + switch predIndex { + case 0: + return p.Precpred(p.GetParserRuleContext(), 2) + + default: + panic("No predicate with index: " + fmt.Sprint(predIndex)) + } +} diff --git a/runtime/Go/antlr/internal/testrig/test/test_visitor.go b/runtime/Go/antlr/internal/testrig/test/test_visitor.go new file mode 100644 index 0000000000..ee093930c5 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test/test_visitor.go @@ -0,0 +1,15 @@ +// Code generated from test.g4 by ANTLR 4.12.0. DO NOT EDIT. + +package test // test +import "github.com/antlr/antlr4/runtime/Go/antlr/v4" + +// A complete Visitor for a parse tree produced by testParser. +type testVisitor interface { + antlr.ParseTreeVisitor + + // Visit a parse tree produced by testParser#stat. + VisitStat(ctx *StatContext) interface{} + + // Visit a parse tree produced by testParser#expression. + VisitExpression(ctx *ExpressionContext) interface{} +} diff --git a/runtime/Go/antlr/internal/testrig/test_test.go b/runtime/Go/antlr/internal/testrig/test_test.go new file mode 100644 index 0000000000..6fe13be9b2 --- /dev/null +++ b/runtime/Go/antlr/internal/testrig/test_test.go @@ -0,0 +1,73 @@ +package main + +import ( + "github.com/antlr/antlr4/runtime/Go/antlr/v4" + "github.com/pyroscope-io/client/pyroscope" + "os" + "runtime" + "runtime/pprof" + "testing" +) + +func Test_mvbcheck(t *testing.T) { + + // These 2 lines are only required if you're using mutex or block profiling + // Read the explanation below for how to set these rates: + runtime.SetMutexProfileFraction(5) + runtime.SetBlockProfileRate(5) + + pyroscope.Start(pyroscope.Config{ + ApplicationName: "mvparse", + + // replace this with the address of pyroscope server + ServerAddress: "http://localhost:4040", + + // you can disable logging by setting this to nil + Logger: pyroscope.StandardLogger, + + // optionally, if authentication is enabled, specify the API key: + // AuthToken: os.Getenv("PYROSCOPE_AUTH_TOKEN"), + + // you can provide static tags via a map: + Tags: map[string]string{"hostname": "jimidle"}, + + ProfileTypes: []pyroscope.ProfileType{ + // these profile types are enabled by default: + pyroscope.ProfileCPU, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileInuseSpace, + + // these profile types are optional: + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, + }) + + type args struct { + inf string + } + tests := []struct { + name string + args args + }{ + { + name: "Speed test for sub,", + args: args{ + inf: "input", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + antlr.ParserATNSimulatorTraceATNSim = true + testRun(tt.args.inf) + }) + } + f, _ := os.Create("heatest.pprof") + pprof.Lookup("heap").WriteTo(f, 0) +} diff --git a/runtime/Go/antlr/v4/prediction_context.go b/runtime/Go/antlr/v4/prediction_context.go index 1ed15bc06a..1335007c91 100644 --- a/runtime/Go/antlr/v4/prediction_context.go +++ b/runtime/Go/antlr/v4/prediction_context.go @@ -53,7 +53,6 @@ func calculateHash(parent PredictionContext, returnState int) int { return murmurFinish(h, 2) } - // Convert a {@link RuleContext} tree to a {@link BasePredictionContext} graph. // Return {@link //EMPTY} if {@code outerContext} is empty or nil. // / @@ -401,9 +400,8 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache * M := NewArrayPredictionContext(mergedParents, mergedReturnStates) // if we created same array as a or b, return that instead - // TODO: JI track whether this is possible above during merge sort for speed - // TODO: JI VERY IMPORTANT - In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems - if M == a { + // TODO: JI track whether this is possible above during merge sort for speed and possibly avoid an allocation + if M.Equals(a) { if mergeCache != nil { mergeCache.set(a.Hash(), b.Hash(), a) } diff --git a/scripts/traceatn.sh b/scripts/traceatn.sh index eed17d2e07..bfc8998b75 100755 --- a/scripts/traceatn.sh +++ b/scripts/traceatn.sh @@ -1,15 +1,17 @@ +#! /bin/sh + # Run this so we get right jars before trying this script: # cd ANTLR-ROOT-DIR # mvn install -DskipTests=true -# cd runtime-tests +# cd runtime-testsuite # mvn install jar:test-jar -DskipTests=true # # Run script with # # traceatn.sh /tmp/JSON.g4 json /tmp/foo.json -export ANTLRJAR=~/.m2/repository/org/antlr/antlr4/4.12.0-SNAPSHOT/antlr4-4.12.0-SNAPSHOT-complete.jar -export TESTJAR=~/.m2/repository/org/antlr/antlr4-runtime-testsuite/4.12.0-SNAPSHOT/antlr4-runtime-testsuite-4.12.0-SNAPSHOT-tests.jar +export ANTLRJAR=~/.m2/repository/org/antlr/antlr4/4.12.1-SNAPSHOT/antlr4-4.12.1-SNAPSHOT-complete.jar +export TESTJAR=~/.m2/repository/org/antlr/antlr4-runtime-testsuite/4.12.1-SNAPSHOT/antlr4-runtime-testsuite-4.12.1-SNAPSHOT-tests.jar export JUPITER=~/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.9.0/junit-jupiter-api-5.9.0.jar export OPENTEST=~/.m2/repository/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar java -classpath $ANTLRJAR:$TESTJAR:$JUPITER:$OPENTEST org.antlr.v4.test.runtime.TraceATN $@