├── .gitignore ├── GoCompiler ├── ast │ ├── AstNode.go │ └── AstNodeType.go ├── calc │ ├── calculator.go │ └── calculator_test.go ├── go.mod ├── lexer │ ├── DfaState.go │ ├── SimpleLexer.go │ ├── SimpleLexer_test.go │ ├── Token.go │ ├── TokenReader.go │ ├── TokenType.go │ └── Types.go ├── main.go └── script │ ├── MyScript.go │ ├── SimpleParser.go │ └── SimpleParser_test.go ├── JavaCompiler ├── gen │ ├── antlrtest │ │ ├── CommonLexer.interp │ │ ├── CommonLexer.java │ │ ├── CommonLexer.tokens │ │ └── script │ │ │ ├── CommonLexer.interp │ │ │ ├── CommonLexer.java │ │ │ └── CommonLexer.tokens │ └── playscript │ │ ├── CommonLexer.interp │ │ ├── CommonLexer.java │ │ ├── CommonLexer.tokens │ │ ├── PlayScript.interp │ │ ├── PlayScript.tokens │ │ ├── PlayScriptBaseListener.java │ │ ├── PlayScriptBaseVisitor.java │ │ ├── PlayScriptLexer.interp │ │ ├── PlayScriptLexer.java │ │ ├── PlayScriptLexer.tokens │ │ ├── PlayScriptListener.java │ │ ├── PlayScriptParser.java │ │ └── PlayScriptVisitor.java ├── pom.xml └── src │ └── main │ ├── java │ ├── antlrtest │ │ ├── ASTEvaluator.class │ │ ├── ASTEvaluator.java │ │ ├── CommonLexer.g4 │ │ ├── Hello.class │ │ ├── Hello.g4 │ │ ├── Hello.interp │ │ ├── Hello.java │ │ ├── Hello.tokens │ │ ├── PlayScript.class │ │ ├── PlayScript.g4 │ │ ├── PlayScript.interp │ │ ├── PlayScript.java │ │ ├── PlayScript.tokens │ │ ├── PlayScriptBaseListener.class │ │ ├── PlayScriptBaseListener.java │ │ ├── PlayScriptBaseVisitor.class │ │ ├── PlayScriptBaseVisitor.java │ │ ├── PlayScriptLexer.class │ │ ├── PlayScriptLexer.interp │ │ ├── PlayScriptLexer.java │ │ ├── PlayScriptLexer.tokens │ │ ├── PlayScriptListener.class │ │ ├── PlayScriptListener.java │ │ ├── PlayScriptParser$AdditiveExpressionContext.class │ │ ├── PlayScriptParser$ArgumentExpressionListContext.class │ │ ├── PlayScriptParser$AssignmentExpressionContext.class │ │ ├── PlayScriptParser$AssignmentOperatorContext.class │ │ ├── PlayScriptParser$BlockItemContext.class │ │ ├── PlayScriptParser$BlockItemListContext.class │ │ ├── PlayScriptParser$CompoundStatementContext.class │ │ ├── PlayScriptParser$DeclarationContext.class │ │ ├── PlayScriptParser$ExpressionContext.class │ │ ├── PlayScriptParser$ExpressionStatementContext.class │ │ ├── PlayScriptParser$InitializerContext.class │ │ ├── PlayScriptParser$LiteralContext.class │ │ ├── PlayScriptParser$MultiplicativeExpressionContext.class │ │ ├── PlayScriptParser$PrimaryExpressionContext.class │ │ ├── PlayScriptParser$PrimitiveTypeContext.class │ │ ├── PlayScriptParser$StatementContext.class │ │ ├── PlayScriptParser.class │ │ ├── PlayScriptParser.java │ │ ├── PlayScriptVisitor.class │ │ ├── PlayScriptVisitor.java │ │ └── code.my │ ├── calc │ │ ├── AstNode.java │ │ ├── AstNodeType.java │ │ ├── Calculator.java │ │ └── SimpleAstNode.java │ ├── demo │ │ └── test.java │ ├── lexer │ │ ├── DfaState.java │ │ ├── SimpleLexer.java │ │ ├── SimpleToken.java │ │ ├── SimpleTokenReader.java │ │ ├── Token.java │ │ ├── TokenReader.java │ │ └── TokenType.java │ ├── playscript │ │ ├── ASTEvaluator.java │ │ ├── AnnotatedTree.java │ │ ├── BlockScope.java │ │ ├── BreakObject.java │ │ ├── ClassObject.java │ │ ├── ClassScope.java │ │ ├── CommonLexer.g4 │ │ ├── CommonLexer.interp │ │ ├── CommonLexer.java │ │ ├── CommonLexer.tokens │ │ ├── DefaultFunctionType.java │ │ ├── FunctionObject.java │ │ ├── FunctionScope.java │ │ ├── FunctionType.java │ │ ├── LValue.java │ │ ├── NameSpace.java │ │ ├── NullObject.java │ │ ├── PlayObject.java │ │ ├── PlayScript.g4 │ │ ├── PlayScript.interp │ │ ├── PlayScript.java │ │ ├── PlayScript.tokens │ │ ├── PlayScriptBaseListener.java │ │ ├── PlayScriptBaseVisitor.java │ │ ├── PlayScriptCompiler.java │ │ ├── PlayScriptLexer.interp │ │ ├── PlayScriptLexer.java │ │ ├── PlayScriptLexer.tokens │ │ ├── PlayScriptListener.java │ │ ├── PlayScriptParser.java │ │ ├── PlayScriptVisitor.java │ │ ├── PrimitiveType.java │ │ ├── RefResolver.java │ │ ├── ReturnObject.java │ │ ├── Scope.java │ │ ├── StackFrame.java │ │ ├── Symbol.java │ │ ├── Type.java │ │ ├── TypeAndScopeScanner.java │ │ ├── TypeResolver.java │ │ ├── Variable.java │ │ └── VoidType.java │ └── script │ │ ├── MyScript.java │ │ └── SimpleParser.java │ └── resources │ └── note └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Operating System Files 2 | 3 | *.DS_Store 4 | Thumbs.db 5 | *.sw? 6 | .#* 7 | *# 8 | *~ 9 | *.sublime-* 10 | 11 | # Build Artifacts 12 | 13 | .gradle/ 14 | build/ 15 | target/ 16 | bin/ 17 | dependency-reduced-pom.xml 18 | 19 | # Eclipse Project Files 20 | 21 | .classpath 22 | .project 23 | .settings/ 24 | 25 | # IntelliJ IDEA Files 26 | 27 | *.iml 28 | *.ipr 29 | *.iws 30 | *.idea 31 | -------------------------------------------------------------------------------- /GoCompiler/ast/AstNode.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | type AstNode interface { 4 | 5 | GetText() string 6 | GetType() AstNodeType 7 | GetParent() AstNode 8 | GetChilds() []AstNode 9 | AddChild(node AstNode) 10 | } 11 | 12 | func NullNode() AstNode { 13 | return NewSimpleAstNode(Null,"") 14 | } 15 | 16 | type SimpleAstNode struct{ 17 | Text string 18 | Type AstNodeType 19 | Parent AstNode 20 | Childs []AstNode 21 | } 22 | 23 | func NewSimpleAstNode(tp AstNodeType,text string) *SimpleAstNode{ 24 | return &SimpleAstNode{ 25 | Type: tp, 26 | Text: text, 27 | Parent: nil, 28 | Childs: nil, 29 | } 30 | } 31 | 32 | 33 | // 没继承接口... 34 | func (s *SimpleAstNode) GetText() string{ 35 | return s.Text 36 | } 37 | 38 | func (s *SimpleAstNode) GetType() AstNodeType{ 39 | return s.Type 40 | } 41 | 42 | func (s *SimpleAstNode) GetParent() AstNode{ 43 | return s.Parent 44 | } 45 | 46 | func (s *SimpleAstNode) GetChilds() []AstNode{ 47 | return s.Childs 48 | } 49 | 50 | func (s *SimpleAstNode) AddChild(node AstNode){ 51 | s.Childs = append(s.Childs, node) 52 | s.Parent = s 53 | } -------------------------------------------------------------------------------- /GoCompiler/ast/AstNodeType.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | type AstNodeType int 4 | 5 | const( 6 | Programm=iota //程序入口,根节点 7 | 8 | IntDeclaration //整型变量声明 9 | ExpressionStmt //表达式语句,即表达式后面跟个分号 10 | AssignmentStmt //赋值语句 11 | 12 | Primary //基础表达式 13 | Multiplicative //乘法表达式 14 | Additive //加法表达式 15 | 16 | Identifier //标识符 17 | IntLiteral //整型字面量 18 | 19 | Null 20 | ) 21 | 22 | var NodeType2Str = map[AstNodeType]string{ 23 | Programm: "Programm", 24 | Multiplicative: "Multiplicative", 25 | IntLiteral: "IntLiteral", 26 | Additive: "Additive", 27 | 28 | } 29 | -------------------------------------------------------------------------------- /GoCompiler/calc/calculator.go: -------------------------------------------------------------------------------- 1 | package calc 2 | 3 | import ( 4 | "GoCompiler/ast" 5 | "GoCompiler/lexer" 6 | "errors" 7 | "fmt" 8 | "log" 9 | "strconv" 10 | ) 11 | 12 | func run(){ 13 | code := "8-4" 14 | calc := NewMyCalculator() 15 | calc.Evaluate(code) 16 | } 17 | 18 | type Calculator interface { 19 | Additive() ast.AstNode // 加法表达式 20 | Multiplicative() ast.AstNode // 乘法表达式 21 | Primary() ast.AstNode // 常量表达式 22 | Evaluate(code string) 23 | Parse(code string) lexer.TokenReader 24 | AstDump(node ast.AstNode) 25 | EvaluateAll(node ast.AstNode) int 26 | } 27 | 28 | type MyCalculator struct { 29 | } 30 | 31 | func NewMyCalculator() *MyCalculator{ 32 | return &MyCalculator{} 33 | } 34 | 35 | func (c *MyCalculator)Evaluate(code string){ 36 | node := c.Parse(code) 37 | c.AstDump(node,"") 38 | result := c.EvaluateAll(node) 39 | fmt.Println(fmt.Sprintf("Result: %d",result)) 40 | } 41 | 42 | func (c *MyCalculator)Parse(code string) ast.AstNode { 43 | reader := lexer.Tokenize(code) 44 | node := ast.NewSimpleAstNode(ast.Programm,"Calculator") 45 | child := c.Additive(reader) 46 | if child != ast.NullNode() { 47 | node.AddChild(child) 48 | } 49 | return node 50 | } 51 | 52 | func (c *MyCalculator)AstDump(node ast.AstNode,indent string){ 53 | fmt.Println(fmt.Sprintf("%s%s: %s",indent,ast.NodeType2Str[node.GetType()],node.GetText())) 54 | for _,child := range node.GetChilds(){ 55 | c.AstDump(child,indent+"\t") 56 | } 57 | } 58 | 59 | func (c *MyCalculator) EvaluateAll(node ast.AstNode) int { 60 | result := 0 61 | switch node.GetType() { 62 | case ast.Programm: 63 | for _,child := range node.GetChilds(){ 64 | result = c.EvaluateAll(child) 65 | } 66 | break 67 | // 加法表达式 68 | case ast.Additive: 69 | child1 := node.GetChilds()[0] // 如果有子集 70 | value1 := c.EvaluateAll(child1) 71 | child2 := node.GetChilds()[1] // 如果有子集 72 | value2 := c.EvaluateAll(child2) 73 | if node.GetText() == "+" { 74 | result = value1 + value2 75 | }else if node.GetText() == "-" { 76 | result = value1 - value2 77 | } 78 | break 79 | case ast.Multiplicative: 80 | child1 := node.GetChilds()[0] // 如果有子集 81 | value1 := c.EvaluateAll(child1) 82 | child2 := node.GetChilds()[1] // 如果有子集 83 | value2 := c.EvaluateAll(child2) 84 | if node.GetText() == "*" { 85 | result = value1 * value2 86 | }else if node.GetText() == "/" { 87 | result = value1 / value2 88 | } 89 | break 90 | case ast.IntLiteral: 91 | result,_ = strconv.Atoi(node.GetText()) 92 | break 93 | } 94 | return result 95 | } 96 | 97 | func (c *MyCalculator) Additive(reader *lexer.SimpleTokenReader) ast.AstNode { 98 | child1 := c.Multiplicative(reader) 99 | node := child1 100 | if child1 != ast.NullNode() { 101 | for{ 102 | token := reader.Peek() // 预读 103 | if token != lexer.NullToken() && (token.GetType() == lexer.TokenType2Str[lexer.Plus] || token.GetType() == lexer.TokenType2Str[lexer.Minus]){ 104 | token = reader.Read() 105 | child2 := c.Multiplicative(reader) 106 | node = ast.NewSimpleAstNode(ast.Additive,token.GetText()) // + 107 | node.AddChild(child1) 108 | node.AddChild(child2) 109 | child1 = node 110 | }else { 111 | break 112 | } 113 | } 114 | } 115 | return node 116 | } 117 | 118 | // mul = int|mul*int 119 | func (c *MyCalculator)Multiplicative(reader *lexer.SimpleTokenReader) ast.AstNode { 120 | child1 := c.Primary(reader) // int 121 | node := child1 122 | token := reader.Peek() 123 | if token != lexer.NullToken() && node != ast.NullNode() { 124 | if token.GetType() == lexer.TokenType2Str[lexer.Star] || token.GetType() == lexer.TokenType2Str[lexer.Slash] { 125 | token = reader.Read() 126 | child2 := c.Multiplicative(reader) // 这里顺序有点问题 之前写错了 127 | if child2 != nil { 128 | node = ast.NewSimpleAstNode(ast.Multiplicative,token.GetText()) 129 | node.AddChild(child1) 130 | node.AddChild(child2) 131 | }else { 132 | log.Fatalln(errors.New("expect right multiplicative syntax")) 133 | } 134 | } 135 | } 136 | return node 137 | } 138 | 139 | // 常量表达式 140 | func (c *MyCalculator)Primary(reader *lexer.SimpleTokenReader) ast.AstNode { 141 | node := ast.NullNode() 142 | token := reader.Peek() 143 | if token != lexer.NullToken() { 144 | switch token.GetType() { 145 | case "IntLiteral": // 创建一个 Int 的 node 节点 146 | token = reader.Read() 147 | return ast.NewSimpleAstNode(ast.IntLiteral,token.GetText()) 148 | } 149 | } 150 | return node 151 | } 152 | 153 | 154 | -------------------------------------------------------------------------------- /GoCompiler/calc/calculator_test.go: -------------------------------------------------------------------------------- 1 | package calc 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | // 测试计算器的运行情况 8 | func TestRun(t *testing.T) { 9 | run() 10 | } -------------------------------------------------------------------------------- /GoCompiler/go.mod: -------------------------------------------------------------------------------- 1 | module GoCompiler 2 | 3 | go 1.17 4 | -------------------------------------------------------------------------------- /GoCompiler/lexer/DfaState.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | 4 | var DfaState2Str = map[EnumType]string{ 5 | GT: "GT", 6 | GE: "GT", 7 | INT: "INT", 8 | Id: "Id", 9 | Id_INT1: "Id_INT1", 10 | Id_INT2: "Id_INT2", 11 | Id_INT3: "Id_INT3", 12 | Initial: "Initial", 13 | SemiColon: "SemiColon", 14 | IntLiteral: "IntLiteral", 15 | Identifier: "Identifier", 16 | Assignment: "Assignment", 17 | 18 | Plus: "Plus", // + 19 | Minus: "Minus", // - 20 | Star: "Star", // * 21 | Slash: "Slash", // / 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /GoCompiler/lexer/SimpleLexer.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | var ( 4 | tokenText []rune // 保存临时的数据 ,我这个要数组然后一个个添加 5 | tokenList []SimpleToken // 保存解析完毕的 token 6 | token SimpleToken 7 | ) 8 | 9 | func isAlpha(ch rune) bool { 10 | return ch>= 'a' && ch <= 'z'|| ch >='A' && ch <= 'Z' 11 | } 12 | 13 | func isDigit(ch rune) bool { 14 | return ch >= '0' && ch <= '9' 15 | } 16 | 17 | func isBlank(ch rune) bool{ 18 | return ch == ' ' || ch == '\t' || ch == '\n' 19 | } 20 | 21 | func initToken(ch rune) string { 22 | // 说明不是最开头,这时候 tokenText 中是已解析完成的 23 | if len(tokenText) >0 { 24 | token.Text = string(tokenText) 25 | tokenList = append(tokenList, token) 26 | // 清零 27 | tokenText = nil 28 | token = SimpleToken{} 29 | } 30 | 31 | // 对新的 token 进行解析/或从头开始解析 32 | state := DfaState2Str[Initial] 33 | if isAlpha(ch) { 34 | // 解析到关键字开头 35 | if ch == 'i' { 36 | state = DfaState2Str[Id_INT1] 37 | }else { 38 | state = DfaState2Str[Identifier] 39 | } 40 | token.Type = TokenType2Str[Identifier] 41 | tokenText = append(tokenText, ch) 42 | }else if isDigit(ch) { 43 | state = DfaState2Str[IntLiteral] // 数字 44 | token.Type = TokenType2Str[IntLiteral] 45 | tokenText = append(tokenText, ch) 46 | }else if ch == '>' { 47 | state = DfaState2Str[GT] 48 | token.Type = TokenType2Str[GT] 49 | tokenText = append(tokenText, ch) 50 | }else if ch == '=' { 51 | state = DfaState2Str[Assignment] 52 | token.Type = TokenType2Str[Assignment] 53 | tokenText = append(tokenText, ch) 54 | }else if ch == ';' { 55 | state = DfaState2Str[SemiColon] 56 | token.Type = TokenType2Str[SemiColon] 57 | tokenText = append(tokenText, ch) 58 | }else if ch == '+' { 59 | state = DfaState2Str[Plus] 60 | token.Type = TokenType2Str[Plus] 61 | tokenText = append(tokenText, ch) 62 | }else if ch == '-' { 63 | state = DfaState2Str[Minus] 64 | token.Type = TokenType2Str[Minus] 65 | tokenText = append(tokenText, ch) 66 | }else if ch == '*' { 67 | state = DfaState2Str[Star] 68 | token.Type = TokenType2Str[Star] 69 | tokenText = append(tokenText, ch) 70 | }else if ch == '/' { 71 | state = DfaState2Str[Slash] 72 | token.Type = TokenType2Str[Slash] 73 | tokenText = append(tokenText, ch) 74 | } 75 | return state 76 | } 77 | 78 | /** 79 | 返回的应该是一个 Token ,然后我们可以定义一个 reader 去接受 80 | */ 81 | func Tokenize(code string) *SimpleTokenReader { 82 | 83 | // 变量初始化 84 | tokenText = nil 85 | token = SimpleToken{} 86 | tokenList = []SimpleToken{} 87 | codes := []rune(code) 88 | 89 | state := DfaState2Str[Initial] 90 | var ch rune 91 | for _,ch = range codes{ // range 是 index,char 92 | switch state { 93 | case "Initial": 94 | state = initToken(ch) 95 | break 96 | case "Assignment": 97 | fallthrough 98 | case "SemiColon": 99 | fallthrough 100 | case "GE": 101 | fallthrough 102 | case "Plus": // + 103 | state = initToken(ch) 104 | break 105 | case "Minus": // - 106 | state = initToken(ch) 107 | break 108 | case "Star": // * 109 | state = initToken(ch) 110 | break 111 | case "Slash": // / 112 | state = initToken(ch) 113 | break 114 | case "Identifier": 115 | if isDigit(ch) || isAlpha(ch){ 116 | tokenText = append(tokenText, ch) 117 | }else { 118 | state = initToken(ch) 119 | } 120 | break 121 | case "IntLiteral": 122 | if isDigit(ch) { 123 | tokenText = append(tokenText, ch) 124 | }else { 125 | state = initToken(ch) 126 | } 127 | break 128 | 129 | case "Id_INT1": 130 | if ch == 'n' { 131 | state = DfaState2Str[Id_INT2] 132 | token.Type = TokenType2Str[Identifier] // 可以理解为中间量 133 | tokenText = append(tokenText, ch) 134 | }else if isAlpha(ch) || isDigit(ch) { 135 | tokenText = append(tokenText, ch) 136 | }else { 137 | state = initToken(ch) 138 | } 139 | break 140 | case "Id_INT2": 141 | if ch == 't' { 142 | state = DfaState2Str[Id_INT3] 143 | token.Type = TokenType2Str[Identifier] 144 | tokenText = append(tokenText, ch) 145 | }else if isAlpha(ch) || isDigit(ch) { 146 | tokenText = append(tokenText, ch) 147 | }else { 148 | state = initToken(ch) 149 | } 150 | break 151 | 152 | case "Id_INT3": 153 | if isBlank(ch) { 154 | // int xxx 155 | token.Type = TokenType2Str[Int] 156 | state = initToken(ch) 157 | } else { 158 | // 可以确定为 变量了 159 | // 因为可以确定不是 int 所以状态机进行变更 160 | state = DfaState2Str[Identifier] 161 | tokenText = append(tokenText, ch) 162 | } 163 | break 164 | case "GT": 165 | if ch == '=' { 166 | state = DfaState2Str[GE] 167 | token.Type = TokenType2Str[GE] 168 | tokenText = append(tokenText, ch) 169 | }else { 170 | state = initToken(ch) 171 | } 172 | break 173 | 174 | default: 175 | } 176 | } 177 | // 要在 for 外面 ... 不然的话 switch break 就会早最后面 178 | if len(tokenText) >0 { 179 | initToken(ch) 180 | } 181 | return NewSimpleTokenReader(tokenList); 182 | } 183 | -------------------------------------------------------------------------------- /GoCompiler/lexer/SimpleLexer_test.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTokenize(t *testing.T) { 8 | code := "int age=18;" 9 | tokenReader := Tokenize(code) 10 | Dump(tokenReader) 11 | } 12 | -------------------------------------------------------------------------------- /GoCompiler/lexer/Token.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | type Token interface { 4 | GetType() string 5 | GetText() string 6 | } 7 | 8 | type SimpleToken struct { 9 | Type string 10 | Text string 11 | } 12 | 13 | func NewSimpleToken(t string,text string) *SimpleToken{ 14 | return &SimpleToken{ 15 | Type: t, 16 | Text: text, 17 | } 18 | } 19 | 20 | func NullToken() SimpleToken { 21 | return *NewSimpleToken("","") 22 | } 23 | 24 | func (s *SimpleToken) GetText() string { 25 | return s.Text 26 | } 27 | 28 | func (s *SimpleToken) GetType() string { 29 | return s.Type 30 | } 31 | -------------------------------------------------------------------------------- /GoCompiler/lexer/TokenReader.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | import "fmt" 4 | 5 | type TokenReader interface { 6 | Peek() EnumType 7 | Read() EnumType 8 | GetPosition() int 9 | } 10 | 11 | type SimpleTokenReader struct{ 12 | tokens []SimpleToken 13 | position int 14 | } 15 | 16 | 17 | func NewSimpleTokenReader(tokens []SimpleToken) *SimpleTokenReader{ 18 | return &SimpleTokenReader{ 19 | tokens: tokens, 20 | position: 0, 21 | } 22 | } 23 | 24 | func (s *SimpleTokenReader) getPosition() int{ 25 | return s.position 26 | } 27 | 28 | // 预读,就是读了之后坐标不进行改变 29 | func (s *SimpleTokenReader) Peek() SimpleToken{ 30 | if s.position < len(s.tokens) { 31 | return s.tokens[s.position] 32 | } 33 | return NullToken() 34 | } 35 | 36 | func (s *SimpleTokenReader) Read() SimpleToken{ 37 | if s.position < len(s.tokens) { 38 | token := s.tokens[s.position] 39 | s.position ++ 40 | return token 41 | } 42 | return NullToken() 43 | } 44 | 45 | func (s *SimpleTokenReader) UnRead() { 46 | if s.position >= 0 { 47 | s.position -- 48 | } 49 | } 50 | 51 | func Dump(reader *SimpleTokenReader){ 52 | for _,token := range reader.tokens{ 53 | fmt.Println(fmt.Sprintf("%s\t%s",token.GetType(),token.GetText())) 54 | } 55 | } 56 | /** 57 | tokenize 返回的是 Token 结构体,需要一个 TokenReader 来接收 58 | */ 59 | 60 | -------------------------------------------------------------------------------- /GoCompiler/lexer/TokenType.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | var TokenType2Str = map[EnumType]string{ 4 | Plus: "Plus", 5 | Minus: "Minus", 6 | Star: "Star", 7 | Slash: "Slash", 8 | GE: "GE", 9 | GT: "GT", 10 | EQ: "EQ", 11 | LE: "LE", 12 | LT: "LT", 13 | If: "If", 14 | Else: "Else", 15 | Int: "Int", 16 | SemiColon: "SemiColon", 17 | LeftParen: "LeftParen", 18 | RightParen: "RightParen", 19 | Assignment: "Assignment", 20 | Identifier: "Identifier", 21 | IntLiteral: "IntLiteral", 22 | StringLiteral: "StringLiteral", 23 | } 24 | -------------------------------------------------------------------------------- /GoCompiler/lexer/Types.go: -------------------------------------------------------------------------------- 1 | package lexer 2 | 3 | type EnumType int 4 | 5 | const ( 6 | Plus=iota // + 7 | Minus // - 8 | Star // * 9 | Slash // / 10 | 11 | GE // >= 12 | GT // > 13 | EQ // == 14 | LE // <= 15 | LT // < 16 | 17 | SemiColon // ; 18 | LeftParen // ( 19 | RightParen// ) 20 | 21 | Assignment // = 22 | 23 | If 24 | Else 25 | 26 | Int 27 | 28 | Identifier //标识符 29 | 30 | IntLiteral //整型字面量 31 | StringLiteral //字符串字面量 32 | 33 | 34 | // 状态机状态 35 | Initial 36 | 37 | // 保留字,int 这里只做int, if else if 这些不去管 38 | INT // 识别出来是 int 类型 39 | Id_INT1 // => n 40 | Id_INT2 // => t 41 | Id_INT3 // blankt/switch 42 | 43 | // 用户定义的变量 44 | Id 45 | ) 46 | -------------------------------------------------------------------------------- /GoCompiler/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /GoCompiler/script/MyScript.go: -------------------------------------------------------------------------------- 1 | package script 2 | -------------------------------------------------------------------------------- /GoCompiler/script/SimpleParser.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "GoCompiler/ast" 5 | "GoCompiler/lexer" 6 | "errors" 7 | "fmt" 8 | "log" 9 | "strconv" 10 | ) 11 | 12 | var ( 13 | varName = "" 14 | variables = make(map[string]int) 15 | ) 16 | 17 | func run(){ 18 | code := "num=1+2+3*6;" 19 | parse := NewSimpleParser() 20 | parse.Evaluate(code) 21 | 22 | // 要实现一个命令行的脚本 23 | } 24 | 25 | type SimpleParser interface { 26 | Additive() ast.AstNode // 加法表达式 27 | Multiplicative() ast.AstNode // 乘法表达式 28 | Primary() ast.AstNode // 常量表达式 29 | Evaluate(code string) 30 | Parse(code string) lexer.TokenReader 31 | AstDump(node ast.AstNode) 32 | EvaluateAll(node ast.AstNode) int 33 | } 34 | 35 | type MySimpleParser struct { 36 | } 37 | 38 | func NewSimpleParser() *MySimpleParser{ 39 | return &MySimpleParser{ 40 | } 41 | } 42 | 43 | func (c *MySimpleParser)Evaluate(code string){ 44 | node := c.Parse(code) 45 | c.AstDump(node,"") 46 | result := c.EvaluateAll(node) 47 | fmt.Println(fmt.Sprintf("Result: %d",result)) 48 | } 49 | 50 | 51 | func (c *MySimpleParser)Parse(code string) ast.AstNode { 52 | var node ast.AstNode 53 | tokens := lexer.Tokenize(code) 54 | //lexer.Dump(tokens) 55 | token := tokens.Peek() 56 | // 根据输入的不同情况来建立对应的语法树 57 | if (token != lexer.NullToken()){ 58 | if token.GetType() == "Identifier" { 59 | node = c.assignmentStatement(tokens) // num = xxx 60 | }else if token.GetType() == "IntLiteral" { 61 | node = c.Additive(tokens) 62 | }else if token.GetType() == "Int" { 63 | node = c.intDeclare(tokens) // int num = xxx 64 | } 65 | } 66 | return node; 67 | } 68 | 69 | func (c *MySimpleParser)AstDump(node ast.AstNode,indent string){ 70 | fmt.Println(fmt.Sprintf("%s%s: %s",indent,ast.NodeType2Str[node.GetType()],node.GetText())) 71 | for _,child := range node.GetChilds(){ 72 | c.AstDump(child,indent+"\t") 73 | } 74 | } 75 | 76 | func (c *MySimpleParser) EvaluateAll(node ast.AstNode) int { 77 | result := 0 78 | switch node.GetType() { 79 | case ast.Identifier: 80 | varName = node.GetText() 81 | // if varName exist 82 | if _,ok := variables[varName]; ok { 83 | result = variables[varName] 84 | }else { 85 | for _,child := range node.GetChilds(){ 86 | result = c.EvaluateAll(child) 87 | } 88 | } 89 | break 90 | // 加法表达式 91 | case ast.AssignmentStmt: 92 | if node.GetText() != "" { 93 | varName = node.GetText() 94 | variables[varName] = 0 95 | }else { 96 | errors.New(fmt.Sprintf("unknown variable: %s\n",varName)) 97 | } 98 | break 99 | case ast.Additive: 100 | child1 := node.GetChilds()[0] // 如果有子集 101 | value1 := c.EvaluateAll(child1) 102 | child2 := node.GetChilds()[1] // 如果有子集 103 | value2 := c.EvaluateAll(child2) 104 | if node.GetText() == "+" { 105 | result = value1 + value2 106 | }else if node.GetText() == "-" { 107 | result = value1 - value2 108 | } 109 | break 110 | case ast.Multiplicative: 111 | child1 := node.GetChilds()[0] // 如果有子集 112 | value1 := c.EvaluateAll(child1) 113 | child2 := node.GetChilds()[1] // 如果有子集 114 | value2 := c.EvaluateAll(child2) 115 | if node.GetText() == "*" { 116 | result = value1 * value2 117 | }else if node.GetText() == "/" { 118 | result = value1 / value2 119 | } 120 | break 121 | case ast.IntLiteral: 122 | // num = xxx 123 | // 1+2+3+4+5..; 124 | result,_ = strconv.Atoi(node.GetText()) 125 | if varName != "" { // 如果变量存在就从变量表里面进行获取 126 | value,_ := variables[varName] 127 | value = result + value 128 | variables[varName] = value 129 | } 130 | break 131 | } 132 | return result 133 | } 134 | 135 | /** 136 | num = 1+1+1; 137 | */ 138 | func (c *MySimpleParser) assignmentStatement(tokens *lexer.SimpleTokenReader) ast.AstNode{ 139 | node := ast.NullNode() 140 | token := tokens.Peek() 141 | // 识别到了变量 142 | if token != lexer.NullToken() && token.GetType() == "Identifier" { 143 | tokens.Read() 144 | node = ast.NewSimpleAstNode(ast.Identifier,token.GetType()) 145 | token = tokens.Peek() 146 | if token != lexer.NullToken() && token.GetType() == "Assignment" { 147 | tokens.Read() 148 | token = tokens.Peek() 149 | if token != lexer.NullToken() && token.GetType() == "IntLiteral"{ 150 | child := c.Additive(tokens) 151 | if child != ast.NullNode() { 152 | node.AddChild(child) 153 | token = tokens.Peek() 154 | if token != lexer.NullToken() && token.GetType() == "SemiColon" { 155 | tokens.Read() 156 | }else { 157 | // 抛出报错 即期望有分号 158 | errors.New("invalid statement, expecting semicolon") 159 | } 160 | } 161 | } 162 | }else { 163 | // num; 164 | tokens.UnRead() 165 | } 166 | } 167 | return node 168 | } 169 | 170 | func (c *MySimpleParser) intDeclare(tokens *lexer.SimpleTokenReader) ast.AstNode{ 171 | node := ast.NullNode() 172 | token := tokens.Peek() 173 | if token != lexer.NullToken() && token.GetType() == "Int"{ // 这种标识量直接消耗就好了 174 | tokens.Read() 175 | token = tokens.Peek() 176 | // 从变量开始创建树 177 | if token != lexer.NullToken() && token.GetType() == "Identifier"{ 178 | tokens.Read() 179 | node = ast.NewSimpleAstNode(ast.Identifier,token.GetType()) 180 | token = tokens.Peek() 181 | if token != lexer.NullToken() && token.GetType() == "Assignment" { 182 | tokens.Read() 183 | token = tokens.Peek() 184 | if token != lexer.NullToken() && token.GetType() == "IntLiteral"{ 185 | child := c.Additive(tokens) 186 | if child != ast.NullNode() { 187 | node.AddChild(child) 188 | token = tokens.Peek() 189 | if token != lexer.NullToken() && token.GetType() == "SemiColon" { 190 | tokens.Read() 191 | }else { 192 | // 抛出报错 即期望有分号 193 | errors.New("invalid statement, expecting semicolon") 194 | } 195 | } 196 | } 197 | }else { 198 | // 回退 199 | tokens.UnRead() 200 | node = ast.NullNode() // 在 int num 中如果不为 等号 node 设为 null 201 | } 202 | } 203 | } 204 | return node 205 | } 206 | 207 | func (c *MySimpleParser) Additive(reader *lexer.SimpleTokenReader) ast.AstNode { 208 | child1 := c.Multiplicative(reader) 209 | node := child1 210 | if child1 != ast.NullNode() { 211 | for{ 212 | token := reader.Peek() // 预读 213 | if token != lexer.NullToken() && (token.GetType() == lexer.TokenType2Str[lexer.Plus] || token.GetType() == lexer.TokenType2Str[lexer.Minus]){ 214 | token = reader.Read() 215 | child2 := c.Multiplicative(reader) 216 | node = ast.NewSimpleAstNode(ast.Additive,token.GetText()) // + 217 | node.AddChild(child1) 218 | node.AddChild(child2) 219 | child1 = node 220 | }else { 221 | break 222 | } 223 | } 224 | } 225 | return node 226 | } 227 | 228 | // mul = int|mul*int 229 | func (c *MySimpleParser)Multiplicative(reader *lexer.SimpleTokenReader) ast.AstNode { 230 | child1 := c.Primary(reader) // int 231 | node := child1 232 | token := reader.Peek() 233 | if token != lexer.NullToken() && node != ast.NullNode() { 234 | if token.GetType() == lexer.TokenType2Str[lexer.Star] || token.GetType() == lexer.TokenType2Str[lexer.Slash] { 235 | token = reader.Read() 236 | child2 := c.Multiplicative(reader) // 这里顺序有点问题 之前写错了 237 | if child2 != nil { 238 | node = ast.NewSimpleAstNode(ast.Multiplicative,token.GetText()) 239 | node.AddChild(child1) 240 | node.AddChild(child2) 241 | }else { 242 | log.Fatalln(errors.New("expect right multiplicative syntax")) 243 | } 244 | } 245 | } 246 | return node 247 | } 248 | 249 | // 常量表达式 250 | func (c *MySimpleParser)Primary(reader *lexer.SimpleTokenReader) ast.AstNode { 251 | node := ast.NullNode() 252 | token := reader.Peek() 253 | if token != lexer.NullToken() { 254 | switch token.GetType() { 255 | case "IntLiteral": // 创建一个 Int 的 node 节点 256 | token = reader.Read() 257 | return ast.NewSimpleAstNode(ast.IntLiteral,token.GetText()) 258 | } 259 | } 260 | return node 261 | } 262 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /GoCompiler/script/SimpleParser_test.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import "testing" 4 | 5 | func TestRun(t *testing.T) { 6 | run() 7 | } 8 | -------------------------------------------------------------------------------- /JavaCompiler/gen/antlrtest/CommonLexer.tokens: -------------------------------------------------------------------------------- 1 | BOOLEAN=1 2 | BREAK=2 3 | BYTE=3 4 | CASE=4 5 | CATCH=5 6 | CHAR=6 7 | CLASS=7 8 | CONST=8 9 | CONTINUE=9 10 | DEFAULT=10 11 | DO=11 12 | DOUBLE=12 13 | ELSE=13 14 | ENUM=14 15 | EXTENDS=15 16 | FINAL=16 17 | FINALLY=17 18 | FLOAT=18 19 | FOR=19 20 | IF=20 21 | IMPLEMENTS=21 22 | IMPORT=22 23 | INSTANCEOF=23 24 | INT=24 25 | INTERFACE=25 26 | LONG=26 27 | NATIVE=27 28 | NEW=28 29 | PACKAGE=29 30 | PRIVATE=30 31 | PROTECTED=31 32 | PUBLIC=32 33 | RETURN=33 34 | SHORT=34 35 | SUPER=35 36 | SWITCH=36 37 | THIS=37 38 | VOID=38 39 | WHILE=39 40 | IntegerLiteral=40 41 | FloatingPointLiteral=41 42 | BooleanLiteral=42 43 | CharacterLiteral=43 44 | StringLiteral=44 45 | NullLiteral=45 46 | LPAREN=46 47 | RPAREN=47 48 | LBRACE=48 49 | RBRACE=49 50 | LBRACK=50 51 | RBRACK=51 52 | SEMI=52 53 | COMMA=53 54 | DOT=54 55 | ELLIPSIS=55 56 | AT=56 57 | COLONCOLON=57 58 | ASSIGN=58 59 | GT=59 60 | LT=60 61 | BANG=61 62 | TILDE=62 63 | QUESTION=63 64 | COLON=64 65 | ARROW=65 66 | EQUAL=66 67 | LE=67 68 | GE=68 69 | NOTEQUAL=69 70 | AND=70 71 | OR=71 72 | INC=72 73 | DEC=73 74 | ADD=74 75 | SUB=75 76 | MUL=76 77 | DIV=77 78 | BITAND=78 79 | BITOR=79 80 | CARET=80 81 | MOD=81 82 | ADD_ASSIGN=82 83 | SUB_ASSIGN=83 84 | MUL_ASSIGN=84 85 | DIV_ASSIGN=85 86 | AND_ASSIGN=86 87 | OR_ASSIGN=87 88 | XOR_ASSIGN=88 89 | MOD_ASSIGN=89 90 | LSHIFT_ASSIGN=90 91 | RSHIFT_ASSIGN=91 92 | URSHIFT_ASSIGN=92 93 | Identifier=93 94 | WS=94 95 | COMMENT=95 96 | LINE_COMMENT=96 97 | 'boolean'=1 98 | 'break'=2 99 | 'byte'=3 100 | 'case'=4 101 | 'catch'=5 102 | 'char'=6 103 | 'class'=7 104 | 'const'=8 105 | 'continue'=9 106 | 'default'=10 107 | 'do'=11 108 | 'double'=12 109 | 'else'=13 110 | 'enum'=14 111 | 'extends'=15 112 | 'final'=16 113 | 'finally'=17 114 | 'float'=18 115 | 'for'=19 116 | 'if'=20 117 | 'implements'=21 118 | 'import'=22 119 | 'instanceof'=23 120 | 'int'=24 121 | 'interface'=25 122 | 'long'=26 123 | 'native'=27 124 | 'new'=28 125 | 'package'=29 126 | 'private'=30 127 | 'protected'=31 128 | 'public'=32 129 | 'return'=33 130 | 'short'=34 131 | 'super'=35 132 | 'switch'=36 133 | 'this'=37 134 | 'void'=38 135 | 'while'=39 136 | 'null'=45 137 | '('=46 138 | ')'=47 139 | '{'=48 140 | '}'=49 141 | '['=50 142 | ']'=51 143 | ';'=52 144 | ','=53 145 | '.'=54 146 | '...'=55 147 | '@'=56 148 | '::'=57 149 | '='=58 150 | '>'=59 151 | '<'=60 152 | '!'=61 153 | '~'=62 154 | '?'=63 155 | ':'=64 156 | '->'=65 157 | '=='=66 158 | '<='=67 159 | '>='=68 160 | '!='=69 161 | '&&'=70 162 | '||'=71 163 | '++'=72 164 | '--'=73 165 | '+'=74 166 | '-'=75 167 | '*'=76 168 | '/'=77 169 | '&'=78 170 | '|'=79 171 | '^'=80 172 | '%'=81 173 | '+='=82 174 | '-='=83 175 | '*='=84 176 | '/='=85 177 | '&='=86 178 | '|='=87 179 | '^='=88 180 | '%='=89 181 | '<<='=90 182 | '>>='=91 183 | '>>>='=92 184 | -------------------------------------------------------------------------------- /JavaCompiler/gen/antlrtest/script/CommonLexer.tokens: -------------------------------------------------------------------------------- 1 | BOOLEAN=1 2 | BREAK=2 3 | BYTE=3 4 | CASE=4 5 | CATCH=5 6 | CHAR=6 7 | CLASS=7 8 | CONST=8 9 | CONTINUE=9 10 | DEFAULT=10 11 | DO=11 12 | DOUBLE=12 13 | ELSE=13 14 | ENUM=14 15 | EXTENDS=15 16 | FINAL=16 17 | FINALLY=17 18 | FLOAT=18 19 | FOR=19 20 | IF=20 21 | IMPLEMENTS=21 22 | IMPORT=22 23 | INSTANCEOF=23 24 | INT=24 25 | INTERFACE=25 26 | LONG=26 27 | NATIVE=27 28 | NEW=28 29 | PACKAGE=29 30 | PRIVATE=30 31 | PROTECTED=31 32 | PUBLIC=32 33 | RETURN=33 34 | SHORT=34 35 | SUPER=35 36 | SWITCH=36 37 | THIS=37 38 | VOID=38 39 | WHILE=39 40 | IntegerLiteral=40 41 | FloatingPointLiteral=41 42 | BooleanLiteral=42 43 | CharacterLiteral=43 44 | StringLiteral=44 45 | NullLiteral=45 46 | LPAREN=46 47 | RPAREN=47 48 | LBRACE=48 49 | RBRACE=49 50 | LBRACK=50 51 | RBRACK=51 52 | SEMI=52 53 | COMMA=53 54 | DOT=54 55 | ELLIPSIS=55 56 | AT=56 57 | COLONCOLON=57 58 | ASSIGN=58 59 | GT=59 60 | LT=60 61 | BANG=61 62 | TILDE=62 63 | QUESTION=63 64 | COLON=64 65 | ARROW=65 66 | EQUAL=66 67 | LE=67 68 | GE=68 69 | NOTEQUAL=69 70 | AND=70 71 | OR=71 72 | INC=72 73 | DEC=73 74 | ADD=74 75 | SUB=75 76 | MUL=76 77 | DIV=77 78 | BITAND=78 79 | BITOR=79 80 | CARET=80 81 | MOD=81 82 | ADD_ASSIGN=82 83 | SUB_ASSIGN=83 84 | MUL_ASSIGN=84 85 | DIV_ASSIGN=85 86 | AND_ASSIGN=86 87 | OR_ASSIGN=87 88 | XOR_ASSIGN=88 89 | MOD_ASSIGN=89 90 | LSHIFT_ASSIGN=90 91 | RSHIFT_ASSIGN=91 92 | URSHIFT_ASSIGN=92 93 | Identifier=93 94 | WS=94 95 | COMMENT=95 96 | LINE_COMMENT=96 97 | 'boolean'=1 98 | 'break'=2 99 | 'byte'=3 100 | 'case'=4 101 | 'catch'=5 102 | 'char'=6 103 | 'class'=7 104 | 'const'=8 105 | 'continue'=9 106 | 'default'=10 107 | 'do'=11 108 | 'double'=12 109 | 'else'=13 110 | 'enum'=14 111 | 'extends'=15 112 | 'final'=16 113 | 'finally'=17 114 | 'float'=18 115 | 'for'=19 116 | 'if'=20 117 | 'implements'=21 118 | 'import'=22 119 | 'instanceof'=23 120 | 'int'=24 121 | 'interface'=25 122 | 'long'=26 123 | 'native'=27 124 | 'new'=28 125 | 'package'=29 126 | 'private'=30 127 | 'protected'=31 128 | 'public'=32 129 | 'return'=33 130 | 'short'=34 131 | 'super'=35 132 | 'switch'=36 133 | 'this'=37 134 | 'void'=38 135 | 'while'=39 136 | 'null'=45 137 | '('=46 138 | ')'=47 139 | '{'=48 140 | '}'=49 141 | '['=50 142 | ']'=51 143 | ';'=52 144 | ','=53 145 | '.'=54 146 | '...'=55 147 | '@'=56 148 | '::'=57 149 | '='=58 150 | '>'=59 151 | '<'=60 152 | '!'=61 153 | '~'=62 154 | '?'=63 155 | ':'=64 156 | '->'=65 157 | '=='=66 158 | '<='=67 159 | '>='=68 160 | '!='=69 161 | '&&'=70 162 | '||'=71 163 | '++'=72 164 | '--'=73 165 | '+'=74 166 | '-'=75 167 | '*'=76 168 | '/'=77 169 | '&'=78 170 | '|'=79 171 | '^'=80 172 | '%'=81 173 | '+='=82 174 | '-='=83 175 | '*='=84 176 | '/='=85 177 | '&='=86 178 | '|='=87 179 | '^='=88 180 | '%='=89 181 | '<<='=90 182 | '>>='=91 183 | '>>>='=92 184 | -------------------------------------------------------------------------------- /JavaCompiler/gen/playscript/CommonLexer.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/gen/playscript/PlayScript.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/gen/playscript/PlayScriptLexer.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | Bianyi 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 8 13 | 8 14 | 15 | 16 | 17 | 18 | 19 | org.antlr 20 | antlr4-runtime 21 | 4.9.3 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/ASTEvaluator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/ASTEvaluator.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/ASTEvaluator.java: -------------------------------------------------------------------------------- 1 | package antlrtest; 2 | 3 | import antlrtest.PlayScriptParser.AdditiveExpressionContext; 4 | import antlrtest.PlayScriptParser.LiteralContext; 5 | import antlrtest.PlayScriptParser.MultiplicativeExpressionContext; 6 | import antlrtest.PlayScriptParser.PrimaryExpressionContext; 7 | 8 | /** 9 | * 一个Vistor类,只简单的实现了整数的加减乘除。 10 | */ 11 | public class ASTEvaluator extends PlayScriptBaseVisitor { 12 | 13 | /** 14 | * 相当于最后面的那个 switch case 根据不同表达式来进行不同的运算 15 | * 相当于遍历树节点的每个 node 然后根据node的对应类型进行运算 16 | * @param ctx 17 | * @return 18 | */ 19 | 20 | @Override 21 | public Integer visitAdditiveExpression(AdditiveExpressionContext ctx) { 22 | if (ctx.ADD() != null || ctx.SUB() != null) { 23 | Integer left = visitAdditiveExpression(ctx.additiveExpression()); 24 | Integer right = visitMultiplicativeExpression(ctx.multiplicativeExpression()); 25 | if (ctx.ADD() != null) { 26 | return left + right; 27 | } else { 28 | return left - right; 29 | } 30 | } else { 31 | return visitMultiplicativeExpression(ctx.multiplicativeExpression()); 32 | } 33 | } 34 | 35 | @Override 36 | public Integer visitMultiplicativeExpression(MultiplicativeExpressionContext ctx) { 37 | if (ctx.MUL() != null || ctx.DIV() != null || ctx.MOD() != null) { 38 | Integer left = visitMultiplicativeExpression(ctx.multiplicativeExpression()); 39 | Integer right = visitPrimaryExpression(ctx.primaryExpression()); 40 | if (ctx.MUL() != null) { 41 | return left * right; 42 | } else if (ctx.DIV() != null) { 43 | return left / right; 44 | } else { 45 | return left % right; 46 | } 47 | } else { 48 | return visitPrimaryExpression(ctx.primaryExpression()); 49 | } 50 | } 51 | 52 | @Override 53 | public Integer visitPrimaryExpression(PrimaryExpressionContext ctx) { 54 | if (ctx.literal() != null) { 55 | return visitLiteral(ctx.literal()); 56 | } 57 | return 0; 58 | } 59 | 60 | @Override 61 | public Integer visitLiteral(LiteralContext ctx) { 62 | if (ctx.IntegerLiteral() !=null){ 63 | return Integer.valueOf(ctx.IntegerLiteral().getText()); 64 | } 65 | return 0; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/CommonLexer.g4: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD licence"] 3 | 版权说明 4 | 本文件的大部分内容来自:https://github.com/antlr/grammars-v4/blob/master/java/JavaLexer.g4 5 | 在此基础上进行了一些修改。 6 | 修改者:宫文学 2019年 7 | 8 | 原文件采用BSD licence,本文件仍然采用BSD licence. 9 | 原文件的版权声明如下: 10 | */ 11 | 12 | /* 13 | [The "BSD licence"] 14 | Copyright (c) 2013 Terence Parr, Sam Harwell 15 | Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8) 16 | All rights reserved. 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions 19 | are met: 20 | 1. Redistributions of source code must retain the above copyright 21 | notice, this list of conditions and the following disclaimer. 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in the 24 | documentation and/or other materials provided with the distribution. 25 | 3. The name of the author may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | 40 | lexer grammar CommonLexer; //lexer关键字意味着这是一个词法规则 41 | 42 | 43 | //ABSTRACT : 'abstract'; 44 | //ASSERT : 'assert'; 45 | BOOLEAN : 'boolean'; 46 | BREAK : 'break'; 47 | BYTE : 'byte'; 48 | CASE : 'case'; 49 | CATCH : 'catch'; 50 | CHAR : 'char'; 51 | CLASS : 'class'; 52 | CONST : 'const'; 53 | CONTINUE : 'continue'; 54 | DEFAULT : 'default'; 55 | DO : 'do'; 56 | DOUBLE : 'double'; 57 | ELSE : 'else'; 58 | ENUM : 'enum'; 59 | EXTENDS : 'extends'; 60 | FINAL : 'final'; 61 | FINALLY : 'finally'; 62 | FLOAT : 'float'; 63 | FOR : 'for'; 64 | IF : 'if'; 65 | //GOTO : 'goto'; 66 | IMPLEMENTS : 'implements'; 67 | IMPORT : 'import'; 68 | INSTANCEOF : 'instanceof'; 69 | INT : 'int'; 70 | INTERFACE : 'interface'; 71 | LONG : 'long'; 72 | NATIVE : 'native'; 73 | NEW : 'new'; 74 | PACKAGE : 'package'; 75 | PRIVATE : 'private'; 76 | PROTECTED : 'protected'; 77 | PUBLIC : 'public'; 78 | RETURN : 'return'; 79 | SHORT : 'short'; 80 | //STATIC : 'static'; 81 | //STRICTFP : 'strictfp'; 82 | SUPER : 'super'; 83 | SWITCH : 'switch'; 84 | //SYNCHRONIZED : 'synchronized'; 85 | THIS : 'this'; 86 | //THROW : 'throw'; 87 | //THROWS : 'throws'; 88 | //TRANSIENT : 'transient'; 89 | //TRY : 'try'; 90 | VOID : 'void'; 91 | //VOLATILE : 'volatile'; 92 | WHILE : 'while'; 93 | 94 | IntegerLiteral 95 | : DecimalIntegerLiteral 96 | | HexIntegerLiteral 97 | | OctalIntegerLiteral 98 | | BinaryIntegerLiteral 99 | ; 100 | 101 | fragment 102 | DecimalIntegerLiteral 103 | : DecimalNumeral IntegerTypeSuffix? 104 | ; 105 | 106 | fragment 107 | HexIntegerLiteral 108 | : HexNumeral IntegerTypeSuffix? 109 | ; 110 | 111 | fragment 112 | OctalIntegerLiteral 113 | : OctalNumeral IntegerTypeSuffix? 114 | ; 115 | 116 | fragment 117 | BinaryIntegerLiteral 118 | : BinaryNumeral IntegerTypeSuffix? 119 | ; 120 | 121 | fragment 122 | IntegerTypeSuffix 123 | : [lL] 124 | ; 125 | 126 | fragment 127 | DecimalNumeral 128 | : '0' 129 | | NonZeroDigit (Digits? | Underscores Digits) 130 | ; 131 | 132 | fragment 133 | Digits 134 | : Digit (DigitsAndUnderscores? Digit)? 135 | ; 136 | 137 | fragment 138 | Digit 139 | : '0' 140 | | NonZeroDigit 141 | ; 142 | 143 | fragment 144 | NonZeroDigit 145 | : [1-9] 146 | ; 147 | 148 | fragment 149 | DigitsAndUnderscores 150 | : DigitOrUnderscore+ 151 | ; 152 | 153 | fragment 154 | DigitOrUnderscore 155 | : Digit 156 | | '_' 157 | ; 158 | 159 | fragment 160 | Underscores 161 | : '_'+ 162 | ; 163 | 164 | fragment 165 | HexNumeral 166 | : '0' [xX] HexDigits 167 | ; 168 | 169 | fragment 170 | HexDigits 171 | : HexDigit (HexDigitsAndUnderscores? HexDigit)? 172 | ; 173 | 174 | fragment 175 | HexDigit 176 | : [0-9a-fA-F] 177 | ; 178 | 179 | fragment 180 | HexDigitsAndUnderscores 181 | : HexDigitOrUnderscore+ 182 | ; 183 | 184 | fragment 185 | HexDigitOrUnderscore 186 | : HexDigit 187 | | '_' 188 | ; 189 | 190 | fragment 191 | OctalNumeral 192 | : '0' Underscores? OctalDigits 193 | ; 194 | 195 | fragment 196 | OctalDigits 197 | : OctalDigit (OctalDigitsAndUnderscores? OctalDigit)? 198 | ; 199 | 200 | fragment 201 | OctalDigit 202 | : [0-7] 203 | ; 204 | 205 | fragment 206 | OctalDigitsAndUnderscores 207 | : OctalDigitOrUnderscore+ 208 | ; 209 | 210 | fragment 211 | OctalDigitOrUnderscore 212 | : OctalDigit 213 | | '_' 214 | ; 215 | 216 | fragment 217 | BinaryNumeral 218 | : '0' [bB] BinaryDigits 219 | ; 220 | 221 | fragment 222 | BinaryDigits 223 | : BinaryDigit (BinaryDigitsAndUnderscores? BinaryDigit)? 224 | ; 225 | 226 | fragment 227 | BinaryDigit 228 | : [01] 229 | ; 230 | 231 | fragment 232 | BinaryDigitsAndUnderscores 233 | : BinaryDigitOrUnderscore+ 234 | ; 235 | 236 | fragment 237 | BinaryDigitOrUnderscore 238 | : BinaryDigit 239 | | '_' 240 | ; 241 | 242 | // §3.10.2 Floating-Point Literals 243 | 244 | FloatingPointLiteral 245 | : DecimalFloatingPointLiteral 246 | | HexadecimalFloatingPointLiteral 247 | ; 248 | 249 | fragment 250 | DecimalFloatingPointLiteral 251 | : Digits '.' Digits? ExponentPart? FloatTypeSuffix? 252 | | '.' Digits ExponentPart? FloatTypeSuffix? 253 | | Digits ExponentPart FloatTypeSuffix? 254 | | Digits FloatTypeSuffix 255 | ; 256 | 257 | fragment 258 | ExponentPart 259 | : ExponentIndicator SignedInteger 260 | ; 261 | 262 | fragment 263 | ExponentIndicator 264 | : [eE] 265 | ; 266 | 267 | fragment 268 | SignedInteger 269 | : Sign? Digits 270 | ; 271 | 272 | fragment 273 | Sign 274 | : [+-] 275 | ; 276 | 277 | fragment 278 | FloatTypeSuffix 279 | : [fFdD] 280 | ; 281 | 282 | fragment 283 | HexadecimalFloatingPointLiteral 284 | : HexSignificand BinaryExponent FloatTypeSuffix? 285 | ; 286 | 287 | fragment 288 | HexSignificand 289 | : HexNumeral '.'? 290 | | '0' [xX] HexDigits? '.' HexDigits 291 | ; 292 | 293 | fragment 294 | BinaryExponent 295 | : BinaryExponentIndicator SignedInteger 296 | ; 297 | 298 | fragment 299 | BinaryExponentIndicator 300 | : [pP] 301 | ; 302 | 303 | // §3.10.3 Boolean Literals 304 | 305 | BooleanLiteral 306 | : 'true' 307 | | 'false' 308 | ; 309 | 310 | // §3.10.4 Character Literals 311 | 312 | CharacterLiteral 313 | : '\'' SingleCharacter '\'' 314 | | '\'' EscapeSequence '\'' 315 | ; 316 | 317 | fragment 318 | SingleCharacter 319 | : ~['\\\r\n] 320 | ; 321 | 322 | // §3.10.5 String Literals 323 | 324 | StringLiteral 325 | : '"' StringCharacters? '"' 326 | ; 327 | 328 | fragment 329 | StringCharacters 330 | : StringCharacter+ 331 | ; 332 | 333 | fragment 334 | StringCharacter 335 | : ~["\\\r\n] 336 | | EscapeSequence 337 | ; 338 | 339 | // §3.10.6 Escape Sequences for Character and String Literals 340 | 341 | fragment 342 | EscapeSequence 343 | : '\\' [btnfr"'\\] 344 | | OctalEscape 345 | | UnicodeEscape // This is not in the spec but prevents having to preprocess the input 346 | ; 347 | 348 | fragment 349 | OctalEscape 350 | : '\\' OctalDigit 351 | | '\\' OctalDigit OctalDigit 352 | | '\\' ZeroToThree OctalDigit OctalDigit 353 | ; 354 | 355 | fragment 356 | ZeroToThree 357 | : [0-3] 358 | ; 359 | 360 | // This is not in the spec but prevents having to preprocess the input 361 | fragment 362 | UnicodeEscape 363 | : '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit 364 | ; 365 | 366 | // §3.10.7 The Null Literal 367 | 368 | NullLiteral 369 | : 'null' 370 | ; 371 | 372 | 373 | 374 | LPAREN : '('; 375 | RPAREN : ')'; 376 | LBRACE : '{'; 377 | RBRACE : '}'; 378 | LBRACK : '['; 379 | RBRACK : ']'; 380 | SEMI : ';'; 381 | COMMA : ','; 382 | DOT : '.'; 383 | ELLIPSIS : '...'; 384 | AT : '@'; 385 | COLONCOLON : '::'; 386 | 387 | 388 | // §3.12 Operators 389 | 390 | ASSIGN : '='; 391 | GT : '>'; 392 | LT : '<'; 393 | BANG : '!'; 394 | TILDE : '~'; 395 | QUESTION : '?'; 396 | COLON : ':'; 397 | ARROW : '->'; 398 | EQUAL : '=='; 399 | LE : '<='; 400 | GE : '>='; 401 | NOTEQUAL : '!='; 402 | AND : '&&'; 403 | OR : '||'; 404 | INC : '++'; 405 | DEC : '--'; 406 | ADD : '+'; 407 | SUB : '-'; 408 | MUL : '*'; 409 | DIV : '/'; 410 | BITAND : '&'; 411 | BITOR : '|'; 412 | CARET : '^'; 413 | MOD : '%'; 414 | //LSHIFT : '<<'; 415 | //RSHIFT : '>>'; 416 | //URSHIFT : '>>>'; 417 | 418 | ADD_ASSIGN : '+='; 419 | SUB_ASSIGN : '-='; 420 | MUL_ASSIGN : '*='; 421 | DIV_ASSIGN : '/='; 422 | AND_ASSIGN : '&='; 423 | OR_ASSIGN : '|='; 424 | XOR_ASSIGN : '^='; 425 | MOD_ASSIGN : '%='; 426 | LSHIFT_ASSIGN : '<<='; 427 | RSHIFT_ASSIGN : '>>='; 428 | URSHIFT_ASSIGN : '>>>='; 429 | 430 | // §3.8 Identifiers (must appear after all keywords in the grammar) 431 | 432 | Identifier 433 | : Letter LetterOrDigit* 434 | ; 435 | 436 | fragment 437 | Letter 438 | : [a-zA-Z$_] // these are the "java letters" below 0x7F 439 | | // covers all characters above 0x7F which are not a surrogate 440 | ~[\u0000-\u007F\uD800-\uDBFF] 441 | {Character.isJavaIdentifierStart(_input.LA(-1))}? 442 | | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 443 | [\uD800-\uDBFF] [\uDC00-\uDFFF] 444 | {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? 445 | ; 446 | 447 | fragment 448 | LetterOrDigit 449 | : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0x7F 450 | | // covers all characters above 0x7F which are not a surrogate 451 | ~[\u0000-\u007F\uD800-\uDBFF] 452 | {Character.isJavaIdentifierPart(_input.LA(-1))}? 453 | | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 454 | [\uD800-\uDBFF] [\uDC00-\uDFFF] 455 | {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? 456 | ; 457 | 458 | // 459 | // Whitespace and comments 460 | // 461 | 462 | WS : [ \t\r\n\u000C]+ -> skip 463 | ; 464 | 465 | COMMENT 466 | : '/*' .*? '*/' -> channel(HIDDEN) 467 | ; 468 | 469 | LINE_COMMENT 470 | : '//' ~[\r\n]* -> channel(HIDDEN) 471 | ; 472 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/Hello.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/Hello.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/Hello.g4: -------------------------------------------------------------------------------- 1 | 2 | lexer grammar Hello; //lexer关键字意味着这是一个词法规则文件,要与文件名相同。 3 | 4 | //关键字 5 | If : 'if' | '如果'; //可以在程序里用‘如果’来代替'if' 6 | Int : 'int'; 7 | 8 | //常量 9 | IntLiteral: [0-9]+; 10 | StringLiteral: '"' .*? '"' ; //字符串常量 11 | 12 | //操作符 13 | AssignmentOP: '=' ; 14 | RelationalOP: '=='|'>'|'>='|'<' |'<=' ; 15 | Star: '*'; 16 | Plus: '+'; 17 | Sharp: '#'; 18 | SemiColon: ';'; 19 | Dot: '.'; 20 | Comm: ','; 21 | LeftBracket : '['; 22 | RightBracket: ']'; 23 | LeftBrace: '{'; 24 | RightBrace: '}'; 25 | LeftParen: '('; 26 | RightParen: ')'; 27 | 28 | //标识符 29 | Id : [a-zA-Z_] ([a-zA-Z_] | [0-9])*; 30 | 31 | //空白字符,抛弃 32 | Whitespace: [ \t]+ -> skip; 33 | Newline: ( '\r' '\n'?|'\n')-> skip; -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/Hello.interp: -------------------------------------------------------------------------------- 1 | token literal names: 2 | null 3 | null 4 | 'int' 5 | null 6 | null 7 | '=' 8 | null 9 | '*' 10 | '+' 11 | '#' 12 | ';' 13 | '.' 14 | ',' 15 | '[' 16 | ']' 17 | '{' 18 | '}' 19 | '(' 20 | ')' 21 | null 22 | null 23 | null 24 | 25 | token symbolic names: 26 | null 27 | If 28 | Int 29 | IntLiteral 30 | StringLiteral 31 | AssignmentOP 32 | RelationalOP 33 | Star 34 | Plus 35 | Sharp 36 | SemiColon 37 | Dot 38 | Comm 39 | LeftBracket 40 | RightBracket 41 | LeftBrace 42 | RightBrace 43 | LeftParen 44 | RightParen 45 | Id 46 | Whitespace 47 | Newline 48 | 49 | rule names: 50 | If 51 | Int 52 | IntLiteral 53 | StringLiteral 54 | AssignmentOP 55 | RelationalOP 56 | Star 57 | Plus 58 | Sharp 59 | SemiColon 60 | Dot 61 | Comm 62 | LeftBracket 63 | RightBracket 64 | LeftBrace 65 | RightBrace 66 | LeftParen 67 | RightParen 68 | Id 69 | Whitespace 70 | Newline 71 | 72 | channel names: 73 | DEFAULT_TOKEN_CHANNEL 74 | HIDDEN 75 | 76 | mode names: 77 | DEFAULT_MODE 78 | 79 | atn: 80 | [3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 23, 128, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 50, 10, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 4, 57, 10, 4, 13, 4, 14, 4, 58, 3, 5, 3, 5, 7, 5, 63, 10, 5, 12, 5, 14, 5, 66, 11, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 80, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 7, 20, 108, 10, 20, 12, 20, 14, 20, 111, 11, 20, 3, 21, 6, 21, 114, 10, 21, 13, 21, 14, 21, 115, 3, 21, 3, 21, 3, 22, 3, 22, 5, 22, 122, 10, 22, 3, 22, 5, 22, 125, 10, 22, 3, 22, 3, 22, 3, 64, 2, 23, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 3, 2, 6, 3, 2, 50, 59, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 4, 2, 11, 11, 34, 34, 2, 138, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 3, 49, 3, 2, 2, 2, 5, 51, 3, 2, 2, 2, 7, 56, 3, 2, 2, 2, 9, 60, 3, 2, 2, 2, 11, 69, 3, 2, 2, 2, 13, 79, 3, 2, 2, 2, 15, 81, 3, 2, 2, 2, 17, 83, 3, 2, 2, 2, 19, 85, 3, 2, 2, 2, 21, 87, 3, 2, 2, 2, 23, 89, 3, 2, 2, 2, 25, 91, 3, 2, 2, 2, 27, 93, 3, 2, 2, 2, 29, 95, 3, 2, 2, 2, 31, 97, 3, 2, 2, 2, 33, 99, 3, 2, 2, 2, 35, 101, 3, 2, 2, 2, 37, 103, 3, 2, 2, 2, 39, 105, 3, 2, 2, 2, 41, 113, 3, 2, 2, 2, 43, 124, 3, 2, 2, 2, 45, 46, 7, 107, 2, 2, 46, 50, 7, 104, 2, 2, 47, 48, 7, 22916, 2, 2, 48, 50, 7, 26526, 2, 2, 49, 45, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 50, 4, 3, 2, 2, 2, 51, 52, 7, 107, 2, 2, 52, 53, 7, 112, 2, 2, 53, 54, 7, 118, 2, 2, 54, 6, 3, 2, 2, 2, 55, 57, 9, 2, 2, 2, 56, 55, 3, 2, 2, 2, 57, 58, 3, 2, 2, 2, 58, 56, 3, 2, 2, 2, 58, 59, 3, 2, 2, 2, 59, 8, 3, 2, 2, 2, 60, 64, 7, 36, 2, 2, 61, 63, 11, 2, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 65, 67, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 68, 7, 36, 2, 2, 68, 10, 3, 2, 2, 2, 69, 70, 7, 63, 2, 2, 70, 12, 3, 2, 2, 2, 71, 72, 7, 63, 2, 2, 72, 80, 7, 63, 2, 2, 73, 80, 7, 64, 2, 2, 74, 75, 7, 64, 2, 2, 75, 80, 7, 63, 2, 2, 76, 80, 7, 62, 2, 2, 77, 78, 7, 62, 2, 2, 78, 80, 7, 63, 2, 2, 79, 71, 3, 2, 2, 2, 79, 73, 3, 2, 2, 2, 79, 74, 3, 2, 2, 2, 79, 76, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 80, 14, 3, 2, 2, 2, 81, 82, 7, 44, 2, 2, 82, 16, 3, 2, 2, 2, 83, 84, 7, 45, 2, 2, 84, 18, 3, 2, 2, 2, 85, 86, 7, 37, 2, 2, 86, 20, 3, 2, 2, 2, 87, 88, 7, 61, 2, 2, 88, 22, 3, 2, 2, 2, 89, 90, 7, 48, 2, 2, 90, 24, 3, 2, 2, 2, 91, 92, 7, 46, 2, 2, 92, 26, 3, 2, 2, 2, 93, 94, 7, 93, 2, 2, 94, 28, 3, 2, 2, 2, 95, 96, 7, 95, 2, 2, 96, 30, 3, 2, 2, 2, 97, 98, 7, 125, 2, 2, 98, 32, 3, 2, 2, 2, 99, 100, 7, 127, 2, 2, 100, 34, 3, 2, 2, 2, 101, 102, 7, 42, 2, 2, 102, 36, 3, 2, 2, 2, 103, 104, 7, 43, 2, 2, 104, 38, 3, 2, 2, 2, 105, 109, 9, 3, 2, 2, 106, 108, 9, 4, 2, 2, 107, 106, 3, 2, 2, 2, 108, 111, 3, 2, 2, 2, 109, 107, 3, 2, 2, 2, 109, 110, 3, 2, 2, 2, 110, 40, 3, 2, 2, 2, 111, 109, 3, 2, 2, 2, 112, 114, 9, 5, 2, 2, 113, 112, 3, 2, 2, 2, 114, 115, 3, 2, 2, 2, 115, 113, 3, 2, 2, 2, 115, 116, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 118, 8, 21, 2, 2, 118, 42, 3, 2, 2, 2, 119, 121, 7, 15, 2, 2, 120, 122, 7, 12, 2, 2, 121, 120, 3, 2, 2, 2, 121, 122, 3, 2, 2, 2, 122, 125, 3, 2, 2, 2, 123, 125, 7, 12, 2, 2, 124, 119, 3, 2, 2, 2, 124, 123, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 127, 8, 22, 2, 2, 127, 44, 3, 2, 2, 2, 12, 2, 49, 58, 64, 79, 107, 109, 115, 121, 124, 3, 8, 2, 2] -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/Hello.java: -------------------------------------------------------------------------------- 1 | // Generated from Hello.g4 by ANTLR 4.9.3 2 | import org.antlr.v4.runtime.Lexer; 3 | import org.antlr.v4.runtime.CharStream; 4 | import org.antlr.v4.runtime.Token; 5 | import org.antlr.v4.runtime.TokenStream; 6 | import org.antlr.v4.runtime.*; 7 | import org.antlr.v4.runtime.atn.*; 8 | import org.antlr.v4.runtime.dfa.DFA; 9 | import org.antlr.v4.runtime.misc.*; 10 | 11 | @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) 12 | public class Hello extends Lexer { 13 | static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); } 14 | 15 | protected static final DFA[] _decisionToDFA; 16 | protected static final PredictionContextCache _sharedContextCache = 17 | new PredictionContextCache(); 18 | public static final int 19 | If=1, Int=2, IntLiteral=3, StringLiteral=4, AssignmentOP=5, RelationalOP=6, 20 | Star=7, Plus=8, Sharp=9, SemiColon=10, Dot=11, Comm=12, LeftBracket=13, 21 | RightBracket=14, LeftBrace=15, RightBrace=16, LeftParen=17, RightParen=18, 22 | Id=19, Whitespace=20, Newline=21; 23 | public static String[] channelNames = { 24 | "DEFAULT_TOKEN_CHANNEL", "HIDDEN" 25 | }; 26 | 27 | public static String[] modeNames = { 28 | "DEFAULT_MODE" 29 | }; 30 | 31 | private static String[] makeRuleNames() { 32 | return new String[] { 33 | "If", "Int", "IntLiteral", "StringLiteral", "AssignmentOP", "RelationalOP", 34 | "Star", "Plus", "Sharp", "SemiColon", "Dot", "Comm", "LeftBracket", "RightBracket", 35 | "LeftBrace", "RightBrace", "LeftParen", "RightParen", "Id", "Whitespace", 36 | "Newline" 37 | }; 38 | } 39 | public static final String[] ruleNames = makeRuleNames(); 40 | 41 | private static String[] makeLiteralNames() { 42 | return new String[] { 43 | null, null, "'int'", null, null, "'='", null, "'*'", "'+'", "'#'", "';'", 44 | "'.'", "','", "'['", "']'", "'{'", "'}'", "'('", "')'" 45 | }; 46 | } 47 | private static final String[] _LITERAL_NAMES = makeLiteralNames(); 48 | private static String[] makeSymbolicNames() { 49 | return new String[] { 50 | null, "If", "Int", "IntLiteral", "StringLiteral", "AssignmentOP", "RelationalOP", 51 | "Star", "Plus", "Sharp", "SemiColon", "Dot", "Comm", "LeftBracket", "RightBracket", 52 | "LeftBrace", "RightBrace", "LeftParen", "RightParen", "Id", "Whitespace", 53 | "Newline" 54 | }; 55 | } 56 | private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); 57 | public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); 58 | 59 | /** 60 | * @deprecated Use {@link #VOCABULARY} instead. 61 | */ 62 | @Deprecated 63 | public static final String[] tokenNames; 64 | static { 65 | tokenNames = new String[_SYMBOLIC_NAMES.length]; 66 | for (int i = 0; i < tokenNames.length; i++) { 67 | tokenNames[i] = VOCABULARY.getLiteralName(i); 68 | if (tokenNames[i] == null) { 69 | tokenNames[i] = VOCABULARY.getSymbolicName(i); 70 | } 71 | 72 | if (tokenNames[i] == null) { 73 | tokenNames[i] = ""; 74 | } 75 | } 76 | } 77 | 78 | @Override 79 | @Deprecated 80 | public String[] getTokenNames() { 81 | return tokenNames; 82 | } 83 | 84 | @Override 85 | 86 | public Vocabulary getVocabulary() { 87 | return VOCABULARY; 88 | } 89 | 90 | 91 | public Hello(CharStream input) { 92 | super(input); 93 | _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); 94 | } 95 | 96 | @Override 97 | public String getGrammarFileName() { return "Hello.g4"; } 98 | 99 | @Override 100 | public String[] getRuleNames() { return ruleNames; } 101 | 102 | @Override 103 | public String getSerializedATN() { return _serializedATN; } 104 | 105 | @Override 106 | public String[] getChannelNames() { return channelNames; } 107 | 108 | @Override 109 | public String[] getModeNames() { return modeNames; } 110 | 111 | @Override 112 | public ATN getATN() { return _ATN; } 113 | 114 | public static final String _serializedATN = 115 | "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\27\u0080\b\1\4\2"+ 116 | "\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+ 117 | "\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ 118 | "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\3\2\3\2\3\2\3\2\5\2\62\n"+ 119 | "\2\3\3\3\3\3\3\3\3\3\4\6\49\n\4\r\4\16\4:\3\5\3\5\7\5?\n\5\f\5\16\5B\13"+ 120 | "\5\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7P\n\7\3\b\3\b\3"+ 121 | "\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20"+ 122 | "\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\7\24l\n\24\f\24\16\24o\13\24"+ 123 | "\3\25\6\25r\n\25\r\25\16\25s\3\25\3\25\3\26\3\26\5\26z\n\26\3\26\5\26"+ 124 | "}\n\26\3\26\3\26\3@\2\27\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f"+ 125 | "\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27\3\2\6\3\2\62;\5"+ 126 | "\2C\\aac|\6\2\62;C\\aac|\4\2\13\13\"\"\2\u008a\2\3\3\2\2\2\2\5\3\2\2\2"+ 127 | "\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3"+ 128 | "\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2"+ 129 | "\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2"+ 130 | "\2\2\2)\3\2\2\2\2+\3\2\2\2\3\61\3\2\2\2\5\63\3\2\2\2\78\3\2\2\2\t<\3\2"+ 131 | "\2\2\13E\3\2\2\2\rO\3\2\2\2\17Q\3\2\2\2\21S\3\2\2\2\23U\3\2\2\2\25W\3"+ 132 | "\2\2\2\27Y\3\2\2\2\31[\3\2\2\2\33]\3\2\2\2\35_\3\2\2\2\37a\3\2\2\2!c\3"+ 133 | "\2\2\2#e\3\2\2\2%g\3\2\2\2\'i\3\2\2\2)q\3\2\2\2+|\3\2\2\2-.\7k\2\2.\62"+ 134 | "\7h\2\2/\60\7\u5984\2\2\60\62\7\u679e\2\2\61-\3\2\2\2\61/\3\2\2\2\62\4"+ 135 | "\3\2\2\2\63\64\7k\2\2\64\65\7p\2\2\65\66\7v\2\2\66\6\3\2\2\2\679\t\2\2"+ 136 | "\28\67\3\2\2\29:\3\2\2\2:8\3\2\2\2:;\3\2\2\2;\b\3\2\2\2<@\7$\2\2=?\13"+ 137 | "\2\2\2>=\3\2\2\2?B\3\2\2\2@A\3\2\2\2@>\3\2\2\2AC\3\2\2\2B@\3\2\2\2CD\7"+ 138 | "$\2\2D\n\3\2\2\2EF\7?\2\2F\f\3\2\2\2GH\7?\2\2HP\7?\2\2IP\7@\2\2JK\7@\2"+ 139 | "\2KP\7?\2\2LP\7>\2\2MN\7>\2\2NP\7?\2\2OG\3\2\2\2OI\3\2\2\2OJ\3\2\2\2O"+ 140 | "L\3\2\2\2OM\3\2\2\2P\16\3\2\2\2QR\7,\2\2R\20\3\2\2\2ST\7-\2\2T\22\3\2"+ 141 | "\2\2UV\7%\2\2V\24\3\2\2\2WX\7=\2\2X\26\3\2\2\2YZ\7\60\2\2Z\30\3\2\2\2"+ 142 | "[\\\7.\2\2\\\32\3\2\2\2]^\7]\2\2^\34\3\2\2\2_`\7_\2\2`\36\3\2\2\2ab\7"+ 143 | "}\2\2b \3\2\2\2cd\7\177\2\2d\"\3\2\2\2ef\7*\2\2f$\3\2\2\2gh\7+\2\2h&\3"+ 144 | "\2\2\2im\t\3\2\2jl\t\4\2\2kj\3\2\2\2lo\3\2\2\2mk\3\2\2\2mn\3\2\2\2n(\3"+ 145 | "\2\2\2om\3\2\2\2pr\t\5\2\2qp\3\2\2\2rs\3\2\2\2sq\3\2\2\2st\3\2\2\2tu\3"+ 146 | "\2\2\2uv\b\25\2\2v*\3\2\2\2wy\7\17\2\2xz\7\f\2\2yx\3\2\2\2yz\3\2\2\2z"+ 147 | "}\3\2\2\2{}\7\f\2\2|w\3\2\2\2|{\3\2\2\2}~\3\2\2\2~\177\b\26\2\2\177,\3"+ 148 | "\2\2\2\f\2\61:@Okmsy|\3\b\2\2"; 149 | public static final ATN _ATN = 150 | new ATNDeserializer().deserialize(_serializedATN.toCharArray()); 151 | static { 152 | _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; 153 | for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { 154 | _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); 155 | } 156 | } 157 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/Hello.tokens: -------------------------------------------------------------------------------- 1 | If=1 2 | Int=2 3 | IntLiteral=3 4 | StringLiteral=4 5 | AssignmentOP=5 6 | RelationalOP=6 7 | Star=7 8 | Plus=8 9 | Sharp=9 10 | SemiColon=10 11 | Dot=11 12 | Comm=12 13 | LeftBracket=13 14 | RightBracket=14 15 | LeftBrace=15 16 | RightBrace=16 17 | LeftParen=17 18 | RightParen=18 19 | Id=19 20 | Whitespace=20 21 | Newline=21 22 | 'int'=2 23 | '='=5 24 | '*'=7 25 | '+'=8 26 | '#'=9 27 | ';'=10 28 | '.'=11 29 | ','=12 30 | '['=13 31 | ']'=14 32 | '{'=15 33 | '}'=16 34 | '('=17 35 | ')'=18 36 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScript.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScript.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScript.g4: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD licence"] 3 | 版权说明 4 | 本文件的大部分内容来自:https://github.com/antlr/grammars-v4/blob/master/java/JavaParser.g4 5 | 在此基础上进行了一些修改。 6 | 修改者:宫文学 2019年 7 | 8 | 原文件采用BSD licence,本文件仍然采用BSD licence. 9 | 原文件的版权声明如下: 10 | */ 11 | 12 | /* 13 | [The "BSD licence"] 14 | Copyright (c) 2013 Terence Parr, Sam Harwell 15 | Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8) 16 | All rights reserved. 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions 19 | are met: 20 | 1. Redistributions of source code must retain the above copyright 21 | notice, this list of conditions and the following disclaimer. 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in the 24 | documentation and/or other materials provided with the distribution. 25 | 3. The name of the author may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /* 40 | 用Antlr的语法重新实现了02~05讲的语法规则。 41 | Antlr可以支持左递归的语法规则,参见additiveExpression和multiplicativeExpression规则。 42 | */ 43 | grammar PlayScript; 44 | 45 | import CommonLexer; //导入词法定义 46 | 47 | @header { 48 | package antlrtest; 49 | } 50 | 51 | literal 52 | : IntegerLiteral 53 | | FloatingPointLiteral 54 | | BooleanLiteral 55 | | CharacterLiteral 56 | | StringLiteral 57 | | NullLiteral 58 | ; 59 | 60 | primitiveType 61 | : 'Number' 62 | | 'String' 63 | | 'var' 64 | ; 65 | 66 | statement 67 | : expressionStatement 68 | | compoundStatement 69 | //| selectionStatement 70 | //| iterationStatement 71 | ; 72 | 73 | expressionStatement 74 | : expression? ';' 75 | ; 76 | 77 | declaration 78 | : primitiveType Identifier 79 | | primitiveType Identifier initializer 80 | ; 81 | 82 | initializer 83 | : assignmentOperator assignmentExpression 84 | //| LeftBrace initializerList RightBrace 85 | //| LeftBrace initializerList Comm RightBrace 86 | ; 87 | 88 | 89 | expression 90 | : assignmentExpression 91 | | expression ',' assignmentExpression 92 | ; 93 | 94 | assignmentExpression 95 | : additiveExpression 96 | | Identifier assignmentOperator additiveExpression 97 | ; 98 | 99 | assignmentOperator 100 | : '=' 101 | | '*=' 102 | | '/=' 103 | | '%=' 104 | | '+=' 105 | | '-=' 106 | | '<<=' 107 | | '>>=' 108 | | '>>>=' 109 | | '&=' 110 | | '^=' 111 | | '|=' 112 | ; 113 | 114 | //加法表达式,Antlr能够支持左递归 115 | additiveExpression 116 | : multiplicativeExpression 117 | | additiveExpression '+' multiplicativeExpression 118 | | additiveExpression '-' multiplicativeExpression 119 | ; 120 | 121 | //乘法表达式,Antlr能够支持左递归 122 | multiplicativeExpression 123 | : primaryExpression 124 | | multiplicativeExpression '*' primaryExpression 125 | | multiplicativeExpression '/' primaryExpression 126 | | multiplicativeExpression '%' primaryExpression 127 | ; 128 | 129 | primaryExpression 130 | : Identifier 131 | | literal 132 | | Identifier '(' argumentExpressionList? ')' 133 | | '(' expression ')' 134 | ; 135 | 136 | argumentExpressionList 137 | : assignmentExpression 138 | | argumentExpressionList ',' assignmentExpression 139 | ; 140 | 141 | compoundStatement 142 | : '{' blockItemList? '}' 143 | ; 144 | 145 | blockItemList 146 | : blockItem 147 | | blockItemList blockItem 148 | ; 149 | 150 | blockItem 151 | : statement 152 | | declaration 153 | ; -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScript.interp: -------------------------------------------------------------------------------- 1 | token literal names: 2 | null 3 | 'Number' 4 | 'String' 5 | 'var' 6 | 'boolean' 7 | 'break' 8 | 'byte' 9 | 'case' 10 | 'catch' 11 | 'char' 12 | 'class' 13 | 'const' 14 | 'continue' 15 | 'default' 16 | 'do' 17 | 'double' 18 | 'else' 19 | 'enum' 20 | 'extends' 21 | 'final' 22 | 'finally' 23 | 'float' 24 | 'for' 25 | 'if' 26 | 'implements' 27 | 'import' 28 | 'instanceof' 29 | 'int' 30 | 'interface' 31 | 'long' 32 | 'native' 33 | 'new' 34 | 'package' 35 | 'private' 36 | 'protected' 37 | 'public' 38 | 'return' 39 | 'short' 40 | 'super' 41 | 'switch' 42 | 'this' 43 | 'void' 44 | 'while' 45 | null 46 | null 47 | null 48 | null 49 | null 50 | 'null' 51 | '(' 52 | ')' 53 | '{' 54 | '}' 55 | '[' 56 | ']' 57 | ';' 58 | ',' 59 | '.' 60 | '...' 61 | '@' 62 | '::' 63 | '=' 64 | '>' 65 | '<' 66 | '!' 67 | '~' 68 | '?' 69 | ':' 70 | '->' 71 | '==' 72 | '<=' 73 | '>=' 74 | '!=' 75 | '&&' 76 | '||' 77 | '++' 78 | '--' 79 | '+' 80 | '-' 81 | '*' 82 | '/' 83 | '&' 84 | '|' 85 | '^' 86 | '%' 87 | '+=' 88 | '-=' 89 | '*=' 90 | '/=' 91 | '&=' 92 | '|=' 93 | '^=' 94 | '%=' 95 | '<<=' 96 | '>>=' 97 | '>>>=' 98 | null 99 | null 100 | null 101 | null 102 | 103 | token symbolic names: 104 | null 105 | null 106 | null 107 | null 108 | BOOLEAN 109 | BREAK 110 | BYTE 111 | CASE 112 | CATCH 113 | CHAR 114 | CLASS 115 | CONST 116 | CONTINUE 117 | DEFAULT 118 | DO 119 | DOUBLE 120 | ELSE 121 | ENUM 122 | EXTENDS 123 | FINAL 124 | FINALLY 125 | FLOAT 126 | FOR 127 | IF 128 | IMPLEMENTS 129 | IMPORT 130 | INSTANCEOF 131 | INT 132 | INTERFACE 133 | LONG 134 | NATIVE 135 | NEW 136 | PACKAGE 137 | PRIVATE 138 | PROTECTED 139 | PUBLIC 140 | RETURN 141 | SHORT 142 | SUPER 143 | SWITCH 144 | THIS 145 | VOID 146 | WHILE 147 | IntegerLiteral 148 | FloatingPointLiteral 149 | BooleanLiteral 150 | CharacterLiteral 151 | StringLiteral 152 | NullLiteral 153 | LPAREN 154 | RPAREN 155 | LBRACE 156 | RBRACE 157 | LBRACK 158 | RBRACK 159 | SEMI 160 | COMMA 161 | DOT 162 | ELLIPSIS 163 | AT 164 | COLONCOLON 165 | ASSIGN 166 | GT 167 | LT 168 | BANG 169 | TILDE 170 | QUESTION 171 | COLON 172 | ARROW 173 | EQUAL 174 | LE 175 | GE 176 | NOTEQUAL 177 | AND 178 | OR 179 | INC 180 | DEC 181 | ADD 182 | SUB 183 | MUL 184 | DIV 185 | BITAND 186 | BITOR 187 | CARET 188 | MOD 189 | ADD_ASSIGN 190 | SUB_ASSIGN 191 | MUL_ASSIGN 192 | DIV_ASSIGN 193 | AND_ASSIGN 194 | OR_ASSIGN 195 | XOR_ASSIGN 196 | MOD_ASSIGN 197 | LSHIFT_ASSIGN 198 | RSHIFT_ASSIGN 199 | URSHIFT_ASSIGN 200 | Identifier 201 | WS 202 | COMMENT 203 | LINE_COMMENT 204 | 205 | rule names: 206 | literal 207 | primitiveType 208 | statement 209 | expressionStatement 210 | declaration 211 | initializer 212 | expression 213 | assignmentExpression 214 | assignmentOperator 215 | additiveExpression 216 | multiplicativeExpression 217 | primaryExpression 218 | argumentExpressionList 219 | compoundStatement 220 | blockItemList 221 | blockItem 222 | 223 | 224 | atn: 225 | [3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 101, 156, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 5, 4, 41, 10, 4, 3, 5, 5, 5, 44, 10, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 55, 10, 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 7, 8, 66, 10, 8, 12, 8, 14, 8, 69, 11, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 76, 10, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 7, 11, 89, 10, 11, 12, 11, 14, 11, 92, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 106, 10, 12, 12, 12, 14, 12, 109, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 116, 10, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 123, 10, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 7, 14, 131, 10, 14, 12, 14, 14, 14, 134, 11, 14, 3, 15, 3, 15, 5, 15, 138, 10, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 147, 10, 16, 12, 16, 14, 16, 150, 11, 16, 3, 17, 3, 17, 5, 17, 154, 10, 17, 3, 17, 2, 7, 14, 20, 22, 26, 30, 18, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 2, 5, 3, 2, 45, 50, 3, 2, 3, 5, 4, 2, 63, 63, 87, 97, 2, 157, 2, 34, 3, 2, 2, 2, 4, 36, 3, 2, 2, 2, 6, 40, 3, 2, 2, 2, 8, 43, 3, 2, 2, 2, 10, 54, 3, 2, 2, 2, 12, 56, 3, 2, 2, 2, 14, 59, 3, 2, 2, 2, 16, 75, 3, 2, 2, 2, 18, 77, 3, 2, 2, 2, 20, 79, 3, 2, 2, 2, 22, 93, 3, 2, 2, 2, 24, 122, 3, 2, 2, 2, 26, 124, 3, 2, 2, 2, 28, 135, 3, 2, 2, 2, 30, 141, 3, 2, 2, 2, 32, 153, 3, 2, 2, 2, 34, 35, 9, 2, 2, 2, 35, 3, 3, 2, 2, 2, 36, 37, 9, 3, 2, 2, 37, 5, 3, 2, 2, 2, 38, 41, 5, 8, 5, 2, 39, 41, 5, 28, 15, 2, 40, 38, 3, 2, 2, 2, 40, 39, 3, 2, 2, 2, 41, 7, 3, 2, 2, 2, 42, 44, 5, 14, 8, 2, 43, 42, 3, 2, 2, 2, 43, 44, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 46, 7, 57, 2, 2, 46, 9, 3, 2, 2, 2, 47, 48, 5, 4, 3, 2, 48, 49, 7, 98, 2, 2, 49, 55, 3, 2, 2, 2, 50, 51, 5, 4, 3, 2, 51, 52, 7, 98, 2, 2, 52, 53, 5, 12, 7, 2, 53, 55, 3, 2, 2, 2, 54, 47, 3, 2, 2, 2, 54, 50, 3, 2, 2, 2, 55, 11, 3, 2, 2, 2, 56, 57, 5, 18, 10, 2, 57, 58, 5, 16, 9, 2, 58, 13, 3, 2, 2, 2, 59, 60, 8, 8, 1, 2, 60, 61, 5, 16, 9, 2, 61, 67, 3, 2, 2, 2, 62, 63, 12, 3, 2, 2, 63, 64, 7, 58, 2, 2, 64, 66, 5, 16, 9, 2, 65, 62, 3, 2, 2, 2, 66, 69, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 15, 3, 2, 2, 2, 69, 67, 3, 2, 2, 2, 70, 76, 5, 20, 11, 2, 71, 72, 7, 98, 2, 2, 72, 73, 5, 18, 10, 2, 73, 74, 5, 20, 11, 2, 74, 76, 3, 2, 2, 2, 75, 70, 3, 2, 2, 2, 75, 71, 3, 2, 2, 2, 76, 17, 3, 2, 2, 2, 77, 78, 9, 4, 2, 2, 78, 19, 3, 2, 2, 2, 79, 80, 8, 11, 1, 2, 80, 81, 5, 22, 12, 2, 81, 90, 3, 2, 2, 2, 82, 83, 12, 4, 2, 2, 83, 84, 7, 79, 2, 2, 84, 89, 5, 22, 12, 2, 85, 86, 12, 3, 2, 2, 86, 87, 7, 80, 2, 2, 87, 89, 5, 22, 12, 2, 88, 82, 3, 2, 2, 2, 88, 85, 3, 2, 2, 2, 89, 92, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 21, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 93, 94, 8, 12, 1, 2, 94, 95, 5, 24, 13, 2, 95, 107, 3, 2, 2, 2, 96, 97, 12, 5, 2, 2, 97, 98, 7, 81, 2, 2, 98, 106, 5, 24, 13, 2, 99, 100, 12, 4, 2, 2, 100, 101, 7, 82, 2, 2, 101, 106, 5, 24, 13, 2, 102, 103, 12, 3, 2, 2, 103, 104, 7, 86, 2, 2, 104, 106, 5, 24, 13, 2, 105, 96, 3, 2, 2, 2, 105, 99, 3, 2, 2, 2, 105, 102, 3, 2, 2, 2, 106, 109, 3, 2, 2, 2, 107, 105, 3, 2, 2, 2, 107, 108, 3, 2, 2, 2, 108, 23, 3, 2, 2, 2, 109, 107, 3, 2, 2, 2, 110, 123, 7, 98, 2, 2, 111, 123, 5, 2, 2, 2, 112, 113, 7, 98, 2, 2, 113, 115, 7, 51, 2, 2, 114, 116, 5, 26, 14, 2, 115, 114, 3, 2, 2, 2, 115, 116, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 123, 7, 52, 2, 2, 118, 119, 7, 51, 2, 2, 119, 120, 5, 14, 8, 2, 120, 121, 7, 52, 2, 2, 121, 123, 3, 2, 2, 2, 122, 110, 3, 2, 2, 2, 122, 111, 3, 2, 2, 2, 122, 112, 3, 2, 2, 2, 122, 118, 3, 2, 2, 2, 123, 25, 3, 2, 2, 2, 124, 125, 8, 14, 1, 2, 125, 126, 5, 16, 9, 2, 126, 132, 3, 2, 2, 2, 127, 128, 12, 3, 2, 2, 128, 129, 7, 58, 2, 2, 129, 131, 5, 16, 9, 2, 130, 127, 3, 2, 2, 2, 131, 134, 3, 2, 2, 2, 132, 130, 3, 2, 2, 2, 132, 133, 3, 2, 2, 2, 133, 27, 3, 2, 2, 2, 134, 132, 3, 2, 2, 2, 135, 137, 7, 53, 2, 2, 136, 138, 5, 30, 16, 2, 137, 136, 3, 2, 2, 2, 137, 138, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 140, 7, 54, 2, 2, 140, 29, 3, 2, 2, 2, 141, 142, 8, 16, 1, 2, 142, 143, 5, 32, 17, 2, 143, 148, 3, 2, 2, 2, 144, 145, 12, 3, 2, 2, 145, 147, 5, 32, 17, 2, 146, 144, 3, 2, 2, 2, 147, 150, 3, 2, 2, 2, 148, 146, 3, 2, 2, 2, 148, 149, 3, 2, 2, 2, 149, 31, 3, 2, 2, 2, 150, 148, 3, 2, 2, 2, 151, 154, 5, 6, 4, 2, 152, 154, 5, 10, 6, 2, 153, 151, 3, 2, 2, 2, 153, 152, 3, 2, 2, 2, 154, 33, 3, 2, 2, 2, 17, 40, 43, 54, 67, 75, 88, 90, 105, 107, 115, 122, 132, 137, 148, 153] -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScript.java: -------------------------------------------------------------------------------- 1 | package antlrtest; 2 | 3 | import org.antlr.v4.runtime.CharStream; 4 | import org.antlr.v4.runtime.CharStreams; 5 | import org.antlr.v4.runtime.CommonTokenStream; 6 | import org.antlr.v4.runtime.tree.ParseTree; 7 | 8 | public class PlayScript { 9 | public static void main(String[] args) { 10 | String script = "2+6/3"; 11 | 12 | // 词法分析 13 | PlayScriptLexer lexer = new PlayScriptLexer(CharStreams.fromString(script)); 14 | CommonTokenStream tokens = new CommonTokenStream(lexer); // 返回 tokens ,可进行 token 的读写 15 | 16 | // 语法分析,将 tokens 传入到表达式,让表达式来进行计算 17 | PlayScriptParser parser = new PlayScriptParser(tokens); // 对语法进行解析 18 | ParseTree tree = parser.additiveExpression(); // 调用表达式 加法表达式,返回树 19 | 20 | // 遍历树节点进行运算 21 | //打印语法树 22 | System.out.println("The lisp style ast of : " + script); 23 | System.out.println(tree.toStringTree(parser)); // 打印树结构 24 | 25 | 26 | // antlr 能将 词法分析、语法分析、语法树都进行实现.... 27 | 28 | //解释执行 29 | ASTEvaluator visitor = new ASTEvaluator(); 30 | Integer result = visitor.visit(tree); 31 | System.out.println("\nValue of : " + script); 32 | System.out.println(result); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScript.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | BOOLEAN=4 5 | BREAK=5 6 | BYTE=6 7 | CASE=7 8 | CATCH=8 9 | CHAR=9 10 | CLASS=10 11 | CONST=11 12 | CONTINUE=12 13 | DEFAULT=13 14 | DO=14 15 | DOUBLE=15 16 | ELSE=16 17 | ENUM=17 18 | EXTENDS=18 19 | FINAL=19 20 | FINALLY=20 21 | FLOAT=21 22 | FOR=22 23 | IF=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | SUPER=38 39 | SWITCH=39 40 | THIS=40 41 | VOID=41 42 | WHILE=42 43 | IntegerLiteral=43 44 | FloatingPointLiteral=44 45 | BooleanLiteral=45 46 | CharacterLiteral=46 47 | StringLiteral=47 48 | NullLiteral=48 49 | LPAREN=49 50 | RPAREN=50 51 | LBRACE=51 52 | RBRACE=52 53 | LBRACK=53 54 | RBRACK=54 55 | SEMI=55 56 | COMMA=56 57 | DOT=57 58 | ELLIPSIS=58 59 | AT=59 60 | COLONCOLON=60 61 | ASSIGN=61 62 | GT=62 63 | LT=63 64 | BANG=64 65 | TILDE=65 66 | QUESTION=66 67 | COLON=67 68 | ARROW=68 69 | EQUAL=69 70 | LE=70 71 | GE=71 72 | NOTEQUAL=72 73 | AND=73 74 | OR=74 75 | INC=75 76 | DEC=76 77 | ADD=77 78 | SUB=78 79 | MUL=79 80 | DIV=80 81 | BITAND=81 82 | BITOR=82 83 | CARET=83 84 | MOD=84 85 | ADD_ASSIGN=85 86 | SUB_ASSIGN=86 87 | MUL_ASSIGN=87 88 | DIV_ASSIGN=88 89 | AND_ASSIGN=89 90 | OR_ASSIGN=90 91 | XOR_ASSIGN=91 92 | MOD_ASSIGN=92 93 | LSHIFT_ASSIGN=93 94 | RSHIFT_ASSIGN=94 95 | URSHIFT_ASSIGN=95 96 | Identifier=96 97 | WS=97 98 | COMMENT=98 99 | LINE_COMMENT=99 100 | 'Number'=1 101 | 'String'=2 102 | 'var'=3 103 | 'boolean'=4 104 | 'break'=5 105 | 'byte'=6 106 | 'case'=7 107 | 'catch'=8 108 | 'char'=9 109 | 'class'=10 110 | 'const'=11 111 | 'continue'=12 112 | 'default'=13 113 | 'do'=14 114 | 'double'=15 115 | 'else'=16 116 | 'enum'=17 117 | 'extends'=18 118 | 'final'=19 119 | 'finally'=20 120 | 'float'=21 121 | 'for'=22 122 | 'if'=23 123 | 'implements'=24 124 | 'import'=25 125 | 'instanceof'=26 126 | 'int'=27 127 | 'interface'=28 128 | 'long'=29 129 | 'native'=30 130 | 'new'=31 131 | 'package'=32 132 | 'private'=33 133 | 'protected'=34 134 | 'public'=35 135 | 'return'=36 136 | 'short'=37 137 | 'super'=38 138 | 'switch'=39 139 | 'this'=40 140 | 'void'=41 141 | 'while'=42 142 | 'null'=48 143 | '('=49 144 | ')'=50 145 | '{'=51 146 | '}'=52 147 | '['=53 148 | ']'=54 149 | ';'=55 150 | ','=56 151 | '.'=57 152 | '...'=58 153 | '@'=59 154 | '::'=60 155 | '='=61 156 | '>'=62 157 | '<'=63 158 | '!'=64 159 | '~'=65 160 | '?'=66 161 | ':'=67 162 | '->'=68 163 | '=='=69 164 | '<='=70 165 | '>='=71 166 | '!='=72 167 | '&&'=73 168 | '||'=74 169 | '++'=75 170 | '--'=76 171 | '+'=77 172 | '-'=78 173 | '*'=79 174 | '/'=80 175 | '&'=81 176 | '|'=82 177 | '^'=83 178 | '%'=84 179 | '+='=85 180 | '-='=86 181 | '*='=87 182 | '/='=88 183 | '&='=89 184 | '|='=90 185 | '^='=91 186 | '%='=92 187 | '<<='=93 188 | '>>='=94 189 | '>>>='=95 190 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptBaseListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptBaseListener.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptBaseListener.java: -------------------------------------------------------------------------------- 1 | // Generated from PlayScript.g4 by ANTLR 4.9.3 2 | 3 | package antlrtest; 4 | 5 | 6 | import org.antlr.v4.runtime.ParserRuleContext; 7 | import org.antlr.v4.runtime.tree.ErrorNode; 8 | import org.antlr.v4.runtime.tree.TerminalNode; 9 | 10 | /** 11 | * This class provides an empty implementation of {@link PlayScriptListener}, 12 | * which can be extended to create a listener which only needs to handle a subset 13 | * of the available methods. 14 | */ 15 | public class PlayScriptBaseListener implements PlayScriptListener { 16 | /** 17 | * {@inheritDoc} 18 | * 19 | *

The default implementation does nothing.

20 | */ 21 | @Override public void enterLiteral(PlayScriptParser.LiteralContext ctx) { } 22 | /** 23 | * {@inheritDoc} 24 | * 25 | *

The default implementation does nothing.

26 | */ 27 | @Override public void exitLiteral(PlayScriptParser.LiteralContext ctx) { } 28 | /** 29 | * {@inheritDoc} 30 | * 31 | *

The default implementation does nothing.

32 | */ 33 | @Override public void enterPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx) { } 34 | /** 35 | * {@inheritDoc} 36 | * 37 | *

The default implementation does nothing.

38 | */ 39 | @Override public void exitPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx) { } 40 | /** 41 | * {@inheritDoc} 42 | * 43 | *

The default implementation does nothing.

44 | */ 45 | @Override public void enterStatement(PlayScriptParser.StatementContext ctx) { } 46 | /** 47 | * {@inheritDoc} 48 | * 49 | *

The default implementation does nothing.

50 | */ 51 | @Override public void exitStatement(PlayScriptParser.StatementContext ctx) { } 52 | /** 53 | * {@inheritDoc} 54 | * 55 | *

The default implementation does nothing.

56 | */ 57 | @Override public void enterExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx) { } 58 | /** 59 | * {@inheritDoc} 60 | * 61 | *

The default implementation does nothing.

62 | */ 63 | @Override public void exitExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx) { } 64 | /** 65 | * {@inheritDoc} 66 | * 67 | *

The default implementation does nothing.

68 | */ 69 | @Override public void enterDeclaration(PlayScriptParser.DeclarationContext ctx) { } 70 | /** 71 | * {@inheritDoc} 72 | * 73 | *

The default implementation does nothing.

74 | */ 75 | @Override public void exitDeclaration(PlayScriptParser.DeclarationContext ctx) { } 76 | /** 77 | * {@inheritDoc} 78 | * 79 | *

The default implementation does nothing.

80 | */ 81 | @Override public void enterInitializer(PlayScriptParser.InitializerContext ctx) { } 82 | /** 83 | * {@inheritDoc} 84 | * 85 | *

The default implementation does nothing.

86 | */ 87 | @Override public void exitInitializer(PlayScriptParser.InitializerContext ctx) { } 88 | /** 89 | * {@inheritDoc} 90 | * 91 | *

The default implementation does nothing.

92 | */ 93 | @Override public void enterExpression(PlayScriptParser.ExpressionContext ctx) { } 94 | /** 95 | * {@inheritDoc} 96 | * 97 | *

The default implementation does nothing.

98 | */ 99 | @Override public void exitExpression(PlayScriptParser.ExpressionContext ctx) { } 100 | /** 101 | * {@inheritDoc} 102 | * 103 | *

The default implementation does nothing.

104 | */ 105 | @Override public void enterAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx) { } 106 | /** 107 | * {@inheritDoc} 108 | * 109 | *

The default implementation does nothing.

110 | */ 111 | @Override public void exitAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx) { } 112 | /** 113 | * {@inheritDoc} 114 | * 115 | *

The default implementation does nothing.

116 | */ 117 | @Override public void enterAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx) { } 118 | /** 119 | * {@inheritDoc} 120 | * 121 | *

The default implementation does nothing.

122 | */ 123 | @Override public void exitAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx) { } 124 | /** 125 | * {@inheritDoc} 126 | * 127 | *

The default implementation does nothing.

128 | */ 129 | @Override public void enterAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx) { } 130 | /** 131 | * {@inheritDoc} 132 | * 133 | *

The default implementation does nothing.

134 | */ 135 | @Override public void exitAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx) { } 136 | /** 137 | * {@inheritDoc} 138 | * 139 | *

The default implementation does nothing.

140 | */ 141 | @Override public void enterMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx) { } 142 | /** 143 | * {@inheritDoc} 144 | * 145 | *

The default implementation does nothing.

146 | */ 147 | @Override public void exitMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx) { } 148 | /** 149 | * {@inheritDoc} 150 | * 151 | *

The default implementation does nothing.

152 | */ 153 | @Override public void enterPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx) { } 154 | /** 155 | * {@inheritDoc} 156 | * 157 | *

The default implementation does nothing.

158 | */ 159 | @Override public void exitPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx) { } 160 | /** 161 | * {@inheritDoc} 162 | * 163 | *

The default implementation does nothing.

164 | */ 165 | @Override public void enterArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx) { } 166 | /** 167 | * {@inheritDoc} 168 | * 169 | *

The default implementation does nothing.

170 | */ 171 | @Override public void exitArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx) { } 172 | /** 173 | * {@inheritDoc} 174 | * 175 | *

The default implementation does nothing.

176 | */ 177 | @Override public void enterCompoundStatement(PlayScriptParser.CompoundStatementContext ctx) { } 178 | /** 179 | * {@inheritDoc} 180 | * 181 | *

The default implementation does nothing.

182 | */ 183 | @Override public void exitCompoundStatement(PlayScriptParser.CompoundStatementContext ctx) { } 184 | /** 185 | * {@inheritDoc} 186 | * 187 | *

The default implementation does nothing.

188 | */ 189 | @Override public void enterBlockItemList(PlayScriptParser.BlockItemListContext ctx) { } 190 | /** 191 | * {@inheritDoc} 192 | * 193 | *

The default implementation does nothing.

194 | */ 195 | @Override public void exitBlockItemList(PlayScriptParser.BlockItemListContext ctx) { } 196 | /** 197 | * {@inheritDoc} 198 | * 199 | *

The default implementation does nothing.

200 | */ 201 | @Override public void enterBlockItem(PlayScriptParser.BlockItemContext ctx) { } 202 | /** 203 | * {@inheritDoc} 204 | * 205 | *

The default implementation does nothing.

206 | */ 207 | @Override public void exitBlockItem(PlayScriptParser.BlockItemContext ctx) { } 208 | 209 | /** 210 | * {@inheritDoc} 211 | * 212 | *

The default implementation does nothing.

213 | */ 214 | @Override public void enterEveryRule(ParserRuleContext ctx) { } 215 | /** 216 | * {@inheritDoc} 217 | * 218 | *

The default implementation does nothing.

219 | */ 220 | @Override public void exitEveryRule(ParserRuleContext ctx) { } 221 | /** 222 | * {@inheritDoc} 223 | * 224 | *

The default implementation does nothing.

225 | */ 226 | @Override public void visitTerminal(TerminalNode node) { } 227 | /** 228 | * {@inheritDoc} 229 | * 230 | *

The default implementation does nothing.

231 | */ 232 | @Override public void visitErrorNode(ErrorNode node) { } 233 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptBaseVisitor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptBaseVisitor.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptBaseVisitor.java: -------------------------------------------------------------------------------- 1 | // Generated from PlayScript.g4 by ANTLR 4.9.3 2 | 3 | package antlrtest; 4 | 5 | import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; 6 | 7 | /** 8 | * This class provides an empty implementation of {@link PlayScriptVisitor}, 9 | * which can be extended to create a visitor which only needs to handle a subset 10 | * of the available methods. 11 | * 12 | * @param The return type of the visit operation. Use {@link Void} for 13 | * operations with no return type. 14 | */ 15 | public class PlayScriptBaseVisitor extends AbstractParseTreeVisitor implements PlayScriptVisitor { 16 | /** 17 | * {@inheritDoc} 18 | * 19 | *

The default implementation returns the result of calling 20 | * {@link #visitChildren} on {@code ctx}.

21 | */ 22 | @Override public T visitLiteral(PlayScriptParser.LiteralContext ctx) { return visitChildren(ctx); } 23 | /** 24 | * {@inheritDoc} 25 | * 26 | *

The default implementation returns the result of calling 27 | * {@link #visitChildren} on {@code ctx}.

28 | */ 29 | @Override public T visitPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx) { return visitChildren(ctx); } 30 | /** 31 | * {@inheritDoc} 32 | * 33 | *

The default implementation returns the result of calling 34 | * {@link #visitChildren} on {@code ctx}.

35 | */ 36 | @Override public T visitStatement(PlayScriptParser.StatementContext ctx) { return visitChildren(ctx); } 37 | /** 38 | * {@inheritDoc} 39 | * 40 | *

The default implementation returns the result of calling 41 | * {@link #visitChildren} on {@code ctx}.

42 | */ 43 | @Override public T visitExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx) { return visitChildren(ctx); } 44 | /** 45 | * {@inheritDoc} 46 | * 47 | *

The default implementation returns the result of calling 48 | * {@link #visitChildren} on {@code ctx}.

49 | */ 50 | @Override public T visitDeclaration(PlayScriptParser.DeclarationContext ctx) { return visitChildren(ctx); } 51 | /** 52 | * {@inheritDoc} 53 | * 54 | *

The default implementation returns the result of calling 55 | * {@link #visitChildren} on {@code ctx}.

56 | */ 57 | @Override public T visitInitializer(PlayScriptParser.InitializerContext ctx) { return visitChildren(ctx); } 58 | /** 59 | * {@inheritDoc} 60 | * 61 | *

The default implementation returns the result of calling 62 | * {@link #visitChildren} on {@code ctx}.

63 | */ 64 | @Override public T visitExpression(PlayScriptParser.ExpressionContext ctx) { return visitChildren(ctx); } 65 | /** 66 | * {@inheritDoc} 67 | * 68 | *

The default implementation returns the result of calling 69 | * {@link #visitChildren} on {@code ctx}.

70 | */ 71 | @Override public T visitAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx) { return visitChildren(ctx); } 72 | /** 73 | * {@inheritDoc} 74 | * 75 | *

The default implementation returns the result of calling 76 | * {@link #visitChildren} on {@code ctx}.

77 | */ 78 | @Override public T visitAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx) { return visitChildren(ctx); } 79 | /** 80 | * {@inheritDoc} 81 | * 82 | *

The default implementation returns the result of calling 83 | * {@link #visitChildren} on {@code ctx}.

84 | */ 85 | @Override public T visitAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx) { return visitChildren(ctx); } 86 | /** 87 | * {@inheritDoc} 88 | * 89 | *

The default implementation returns the result of calling 90 | * {@link #visitChildren} on {@code ctx}.

91 | */ 92 | @Override public T visitMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx) { return visitChildren(ctx); } 93 | /** 94 | * {@inheritDoc} 95 | * 96 | *

The default implementation returns the result of calling 97 | * {@link #visitChildren} on {@code ctx}.

98 | */ 99 | @Override public T visitPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx) { return visitChildren(ctx); } 100 | /** 101 | * {@inheritDoc} 102 | * 103 | *

The default implementation returns the result of calling 104 | * {@link #visitChildren} on {@code ctx}.

105 | */ 106 | @Override public T visitArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx) { return visitChildren(ctx); } 107 | /** 108 | * {@inheritDoc} 109 | * 110 | *

The default implementation returns the result of calling 111 | * {@link #visitChildren} on {@code ctx}.

112 | */ 113 | @Override public T visitCompoundStatement(PlayScriptParser.CompoundStatementContext ctx) { return visitChildren(ctx); } 114 | /** 115 | * {@inheritDoc} 116 | * 117 | *

The default implementation returns the result of calling 118 | * {@link #visitChildren} on {@code ctx}.

119 | */ 120 | @Override public T visitBlockItemList(PlayScriptParser.BlockItemListContext ctx) { return visitChildren(ctx); } 121 | /** 122 | * {@inheritDoc} 123 | * 124 | *

The default implementation returns the result of calling 125 | * {@link #visitChildren} on {@code ctx}.

126 | */ 127 | @Override public T visitBlockItem(PlayScriptParser.BlockItemContext ctx) { return visitChildren(ctx); } 128 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptLexer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptLexer.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptLexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | BOOLEAN=4 5 | BREAK=5 6 | BYTE=6 7 | CASE=7 8 | CATCH=8 9 | CHAR=9 10 | CLASS=10 11 | CONST=11 12 | CONTINUE=12 13 | DEFAULT=13 14 | DO=14 15 | DOUBLE=15 16 | ELSE=16 17 | ENUM=17 18 | EXTENDS=18 19 | FINAL=19 20 | FINALLY=20 21 | FLOAT=21 22 | FOR=22 23 | IF=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | SUPER=38 39 | SWITCH=39 40 | THIS=40 41 | VOID=41 42 | WHILE=42 43 | IntegerLiteral=43 44 | FloatingPointLiteral=44 45 | BooleanLiteral=45 46 | CharacterLiteral=46 47 | StringLiteral=47 48 | NullLiteral=48 49 | LPAREN=49 50 | RPAREN=50 51 | LBRACE=51 52 | RBRACE=52 53 | LBRACK=53 54 | RBRACK=54 55 | SEMI=55 56 | COMMA=56 57 | DOT=57 58 | ELLIPSIS=58 59 | AT=59 60 | COLONCOLON=60 61 | ASSIGN=61 62 | GT=62 63 | LT=63 64 | BANG=64 65 | TILDE=65 66 | QUESTION=66 67 | COLON=67 68 | ARROW=68 69 | EQUAL=69 70 | LE=70 71 | GE=71 72 | NOTEQUAL=72 73 | AND=73 74 | OR=74 75 | INC=75 76 | DEC=76 77 | ADD=77 78 | SUB=78 79 | MUL=79 80 | DIV=80 81 | BITAND=81 82 | BITOR=82 83 | CARET=83 84 | MOD=84 85 | ADD_ASSIGN=85 86 | SUB_ASSIGN=86 87 | MUL_ASSIGN=87 88 | DIV_ASSIGN=88 89 | AND_ASSIGN=89 90 | OR_ASSIGN=90 91 | XOR_ASSIGN=91 92 | MOD_ASSIGN=92 93 | LSHIFT_ASSIGN=93 94 | RSHIFT_ASSIGN=94 95 | URSHIFT_ASSIGN=95 96 | Identifier=96 97 | WS=97 98 | COMMENT=98 99 | LINE_COMMENT=99 100 | 'Number'=1 101 | 'String'=2 102 | 'var'=3 103 | 'boolean'=4 104 | 'break'=5 105 | 'byte'=6 106 | 'case'=7 107 | 'catch'=8 108 | 'char'=9 109 | 'class'=10 110 | 'const'=11 111 | 'continue'=12 112 | 'default'=13 113 | 'do'=14 114 | 'double'=15 115 | 'else'=16 116 | 'enum'=17 117 | 'extends'=18 118 | 'final'=19 119 | 'finally'=20 120 | 'float'=21 121 | 'for'=22 122 | 'if'=23 123 | 'implements'=24 124 | 'import'=25 125 | 'instanceof'=26 126 | 'int'=27 127 | 'interface'=28 128 | 'long'=29 129 | 'native'=30 130 | 'new'=31 131 | 'package'=32 132 | 'private'=33 133 | 'protected'=34 134 | 'public'=35 135 | 'return'=36 136 | 'short'=37 137 | 'super'=38 138 | 'switch'=39 139 | 'this'=40 140 | 'void'=41 141 | 'while'=42 142 | 'null'=48 143 | '('=49 144 | ')'=50 145 | '{'=51 146 | '}'=52 147 | '['=53 148 | ']'=54 149 | ';'=55 150 | ','=56 151 | '.'=57 152 | '...'=58 153 | '@'=59 154 | '::'=60 155 | '='=61 156 | '>'=62 157 | '<'=63 158 | '!'=64 159 | '~'=65 160 | '?'=66 161 | ':'=67 162 | '->'=68 163 | '=='=69 164 | '<='=70 165 | '>='=71 166 | '!='=72 167 | '&&'=73 168 | '||'=74 169 | '++'=75 170 | '--'=76 171 | '+'=77 172 | '-'=78 173 | '*'=79 174 | '/'=80 175 | '&'=81 176 | '|'=82 177 | '^'=83 178 | '%'=84 179 | '+='=85 180 | '-='=86 181 | '*='=87 182 | '/='=88 183 | '&='=89 184 | '|='=90 185 | '^='=91 186 | '%='=92 187 | '<<='=93 188 | '>>='=94 189 | '>>>='=95 190 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptListener.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptListener.java: -------------------------------------------------------------------------------- 1 | // Generated from PlayScript.g4 by ANTLR 4.9.3 2 | 3 | package antlrtest; 4 | 5 | import org.antlr.v4.runtime.tree.ParseTreeListener; 6 | 7 | /** 8 | * This interface defines a complete listener for a parse tree produced by 9 | * {@link PlayScriptParser}. 10 | */ 11 | public interface PlayScriptListener extends ParseTreeListener { 12 | /** 13 | * Enter a parse tree produced by {@link PlayScriptParser#literal}. 14 | * @param ctx the parse tree 15 | */ 16 | void enterLiteral(PlayScriptParser.LiteralContext ctx); 17 | /** 18 | * Exit a parse tree produced by {@link PlayScriptParser#literal}. 19 | * @param ctx the parse tree 20 | */ 21 | void exitLiteral(PlayScriptParser.LiteralContext ctx); 22 | /** 23 | * Enter a parse tree produced by {@link PlayScriptParser#primitiveType}. 24 | * @param ctx the parse tree 25 | */ 26 | void enterPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx); 27 | /** 28 | * Exit a parse tree produced by {@link PlayScriptParser#primitiveType}. 29 | * @param ctx the parse tree 30 | */ 31 | void exitPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx); 32 | /** 33 | * Enter a parse tree produced by {@link PlayScriptParser#statement}. 34 | * @param ctx the parse tree 35 | */ 36 | void enterStatement(PlayScriptParser.StatementContext ctx); 37 | /** 38 | * Exit a parse tree produced by {@link PlayScriptParser#statement}. 39 | * @param ctx the parse tree 40 | */ 41 | void exitStatement(PlayScriptParser.StatementContext ctx); 42 | /** 43 | * Enter a parse tree produced by {@link PlayScriptParser#expressionStatement}. 44 | * @param ctx the parse tree 45 | */ 46 | void enterExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx); 47 | /** 48 | * Exit a parse tree produced by {@link PlayScriptParser#expressionStatement}. 49 | * @param ctx the parse tree 50 | */ 51 | void exitExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx); 52 | /** 53 | * Enter a parse tree produced by {@link PlayScriptParser#declaration}. 54 | * @param ctx the parse tree 55 | */ 56 | void enterDeclaration(PlayScriptParser.DeclarationContext ctx); 57 | /** 58 | * Exit a parse tree produced by {@link PlayScriptParser#declaration}. 59 | * @param ctx the parse tree 60 | */ 61 | void exitDeclaration(PlayScriptParser.DeclarationContext ctx); 62 | /** 63 | * Enter a parse tree produced by {@link PlayScriptParser#initializer}. 64 | * @param ctx the parse tree 65 | */ 66 | void enterInitializer(PlayScriptParser.InitializerContext ctx); 67 | /** 68 | * Exit a parse tree produced by {@link PlayScriptParser#initializer}. 69 | * @param ctx the parse tree 70 | */ 71 | void exitInitializer(PlayScriptParser.InitializerContext ctx); 72 | /** 73 | * Enter a parse tree produced by {@link PlayScriptParser#expression}. 74 | * @param ctx the parse tree 75 | */ 76 | void enterExpression(PlayScriptParser.ExpressionContext ctx); 77 | /** 78 | * Exit a parse tree produced by {@link PlayScriptParser#expression}. 79 | * @param ctx the parse tree 80 | */ 81 | void exitExpression(PlayScriptParser.ExpressionContext ctx); 82 | /** 83 | * Enter a parse tree produced by {@link PlayScriptParser#assignmentExpression}. 84 | * @param ctx the parse tree 85 | */ 86 | void enterAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx); 87 | /** 88 | * Exit a parse tree produced by {@link PlayScriptParser#assignmentExpression}. 89 | * @param ctx the parse tree 90 | */ 91 | void exitAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx); 92 | /** 93 | * Enter a parse tree produced by {@link PlayScriptParser#assignmentOperator}. 94 | * @param ctx the parse tree 95 | */ 96 | void enterAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx); 97 | /** 98 | * Exit a parse tree produced by {@link PlayScriptParser#assignmentOperator}. 99 | * @param ctx the parse tree 100 | */ 101 | void exitAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx); 102 | /** 103 | * Enter a parse tree produced by {@link PlayScriptParser#additiveExpression}. 104 | * @param ctx the parse tree 105 | */ 106 | void enterAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx); 107 | /** 108 | * Exit a parse tree produced by {@link PlayScriptParser#additiveExpression}. 109 | * @param ctx the parse tree 110 | */ 111 | void exitAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx); 112 | /** 113 | * Enter a parse tree produced by {@link PlayScriptParser#multiplicativeExpression}. 114 | * @param ctx the parse tree 115 | */ 116 | void enterMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx); 117 | /** 118 | * Exit a parse tree produced by {@link PlayScriptParser#multiplicativeExpression}. 119 | * @param ctx the parse tree 120 | */ 121 | void exitMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx); 122 | /** 123 | * Enter a parse tree produced by {@link PlayScriptParser#primaryExpression}. 124 | * @param ctx the parse tree 125 | */ 126 | void enterPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx); 127 | /** 128 | * Exit a parse tree produced by {@link PlayScriptParser#primaryExpression}. 129 | * @param ctx the parse tree 130 | */ 131 | void exitPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx); 132 | /** 133 | * Enter a parse tree produced by {@link PlayScriptParser#argumentExpressionList}. 134 | * @param ctx the parse tree 135 | */ 136 | void enterArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx); 137 | /** 138 | * Exit a parse tree produced by {@link PlayScriptParser#argumentExpressionList}. 139 | * @param ctx the parse tree 140 | */ 141 | void exitArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx); 142 | /** 143 | * Enter a parse tree produced by {@link PlayScriptParser#compoundStatement}. 144 | * @param ctx the parse tree 145 | */ 146 | void enterCompoundStatement(PlayScriptParser.CompoundStatementContext ctx); 147 | /** 148 | * Exit a parse tree produced by {@link PlayScriptParser#compoundStatement}. 149 | * @param ctx the parse tree 150 | */ 151 | void exitCompoundStatement(PlayScriptParser.CompoundStatementContext ctx); 152 | /** 153 | * Enter a parse tree produced by {@link PlayScriptParser#blockItemList}. 154 | * @param ctx the parse tree 155 | */ 156 | void enterBlockItemList(PlayScriptParser.BlockItemListContext ctx); 157 | /** 158 | * Exit a parse tree produced by {@link PlayScriptParser#blockItemList}. 159 | * @param ctx the parse tree 160 | */ 161 | void exitBlockItemList(PlayScriptParser.BlockItemListContext ctx); 162 | /** 163 | * Enter a parse tree produced by {@link PlayScriptParser#blockItem}. 164 | * @param ctx the parse tree 165 | */ 166 | void enterBlockItem(PlayScriptParser.BlockItemContext ctx); 167 | /** 168 | * Exit a parse tree produced by {@link PlayScriptParser#blockItem}. 169 | * @param ctx the parse tree 170 | */ 171 | void exitBlockItem(PlayScriptParser.BlockItemContext ctx); 172 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AdditiveExpressionContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AdditiveExpressionContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ArgumentExpressionListContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ArgumentExpressionListContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AssignmentExpressionContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AssignmentExpressionContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AssignmentOperatorContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$AssignmentOperatorContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$BlockItemContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$BlockItemContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$BlockItemListContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$BlockItemListContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$CompoundStatementContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$CompoundStatementContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$DeclarationContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$DeclarationContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ExpressionContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ExpressionContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ExpressionStatementContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$ExpressionStatementContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$InitializerContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$InitializerContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$LiteralContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$LiteralContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$MultiplicativeExpressionContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$MultiplicativeExpressionContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$PrimaryExpressionContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$PrimaryExpressionContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$PrimitiveTypeContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$PrimitiveTypeContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser$StatementContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser$StatementContext.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptParser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptParser.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptVisitor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KpLi0rn/LearnCompiler/fe150fb7add3dbb6dbfecbfaf08fb727d10b28fd/JavaCompiler/src/main/java/antlrtest/PlayScriptVisitor.class -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/PlayScriptVisitor.java: -------------------------------------------------------------------------------- 1 | // Generated from PlayScript.g4 by ANTLR 4.9.3 2 | 3 | package antlrtest; 4 | 5 | import org.antlr.v4.runtime.tree.ParseTreeVisitor; 6 | 7 | /** 8 | * This interface defines a complete generic visitor for a parse tree produced 9 | * by {@link PlayScriptParser}. 10 | * 11 | * @param The return type of the visit operation. Use {@link Void} for 12 | * operations with no return type. 13 | */ 14 | public interface PlayScriptVisitor extends ParseTreeVisitor { 15 | /** 16 | * Visit a parse tree produced by {@link PlayScriptParser#literal}. 17 | * @param ctx the parse tree 18 | * @return the visitor result 19 | */ 20 | T visitLiteral(PlayScriptParser.LiteralContext ctx); 21 | /** 22 | * Visit a parse tree produced by {@link PlayScriptParser#primitiveType}. 23 | * @param ctx the parse tree 24 | * @return the visitor result 25 | */ 26 | T visitPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx); 27 | /** 28 | * Visit a parse tree produced by {@link PlayScriptParser#statement}. 29 | * @param ctx the parse tree 30 | * @return the visitor result 31 | */ 32 | T visitStatement(PlayScriptParser.StatementContext ctx); 33 | /** 34 | * Visit a parse tree produced by {@link PlayScriptParser#expressionStatement}. 35 | * @param ctx the parse tree 36 | * @return the visitor result 37 | */ 38 | T visitExpressionStatement(PlayScriptParser.ExpressionStatementContext ctx); 39 | /** 40 | * Visit a parse tree produced by {@link PlayScriptParser#declaration}. 41 | * @param ctx the parse tree 42 | * @return the visitor result 43 | */ 44 | T visitDeclaration(PlayScriptParser.DeclarationContext ctx); 45 | /** 46 | * Visit a parse tree produced by {@link PlayScriptParser#initializer}. 47 | * @param ctx the parse tree 48 | * @return the visitor result 49 | */ 50 | T visitInitializer(PlayScriptParser.InitializerContext ctx); 51 | /** 52 | * Visit a parse tree produced by {@link PlayScriptParser#expression}. 53 | * @param ctx the parse tree 54 | * @return the visitor result 55 | */ 56 | T visitExpression(PlayScriptParser.ExpressionContext ctx); 57 | /** 58 | * Visit a parse tree produced by {@link PlayScriptParser#assignmentExpression}. 59 | * @param ctx the parse tree 60 | * @return the visitor result 61 | */ 62 | T visitAssignmentExpression(PlayScriptParser.AssignmentExpressionContext ctx); 63 | /** 64 | * Visit a parse tree produced by {@link PlayScriptParser#assignmentOperator}. 65 | * @param ctx the parse tree 66 | * @return the visitor result 67 | */ 68 | T visitAssignmentOperator(PlayScriptParser.AssignmentOperatorContext ctx); 69 | /** 70 | * Visit a parse tree produced by {@link PlayScriptParser#additiveExpression}. 71 | * @param ctx the parse tree 72 | * @return the visitor result 73 | */ 74 | T visitAdditiveExpression(PlayScriptParser.AdditiveExpressionContext ctx); 75 | /** 76 | * Visit a parse tree produced by {@link PlayScriptParser#multiplicativeExpression}. 77 | * @param ctx the parse tree 78 | * @return the visitor result 79 | */ 80 | T visitMultiplicativeExpression(PlayScriptParser.MultiplicativeExpressionContext ctx); 81 | /** 82 | * Visit a parse tree produced by {@link PlayScriptParser#primaryExpression}. 83 | * @param ctx the parse tree 84 | * @return the visitor result 85 | */ 86 | T visitPrimaryExpression(PlayScriptParser.PrimaryExpressionContext ctx); 87 | /** 88 | * Visit a parse tree produced by {@link PlayScriptParser#argumentExpressionList}. 89 | * @param ctx the parse tree 90 | * @return the visitor result 91 | */ 92 | T visitArgumentExpressionList(PlayScriptParser.ArgumentExpressionListContext ctx); 93 | /** 94 | * Visit a parse tree produced by {@link PlayScriptParser#compoundStatement}. 95 | * @param ctx the parse tree 96 | * @return the visitor result 97 | */ 98 | T visitCompoundStatement(PlayScriptParser.CompoundStatementContext ctx); 99 | /** 100 | * Visit a parse tree produced by {@link PlayScriptParser#blockItemList}. 101 | * @param ctx the parse tree 102 | * @return the visitor result 103 | */ 104 | T visitBlockItemList(PlayScriptParser.BlockItemListContext ctx); 105 | /** 106 | * Visit a parse tree produced by {@link PlayScriptParser#blockItem}. 107 | * @param ctx the parse tree 108 | * @return the visitor result 109 | */ 110 | T visitBlockItem(PlayScriptParser.BlockItemContext ctx); 111 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/antlrtest/code.my: -------------------------------------------------------------------------------- 1 | int age = 45; 2 | if (age >= 17+8+20){ 3 | printf("Hello old man!"); 4 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/calc/AstNode.java: -------------------------------------------------------------------------------- 1 | package calc; 2 | 3 | import lexer.TokenType; 4 | 5 | import java.util.List; 6 | 7 | public interface AstNode { 8 | 9 | public AstNode getParent(); 10 | 11 | public List getChildren(); // 子节点很有可能有多个 12 | 13 | public AstNodeType getType(); 14 | 15 | public String getText(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/calc/AstNodeType.java: -------------------------------------------------------------------------------- 1 | package calc; 2 | 3 | public enum AstNodeType{ 4 | Programm, //程序入口,根节点 5 | 6 | IntDeclaration, //整型变量声明 7 | ExpressionStmt, //表达式语句,即表达式后面跟个分号 8 | AssignmentStmt, //赋值语句 9 | 10 | Primary, //基础表达式 11 | Multiplicative, //乘法表达式 12 | Additive, //加法表达式 13 | 14 | Identifier, //标识符 15 | IntLiteral //整型字面量 16 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/calc/Calculator.java: -------------------------------------------------------------------------------- 1 | package calc; 2 | 3 | import lexer.SimpleLexer; 4 | import lexer.Token; 5 | import lexer.TokenReader; 6 | import lexer.TokenType; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Collections; 12 | 13 | @SuppressWarnings("all") 14 | public class Calculator { 15 | private HashMap variables = new HashMap(); 16 | 17 | public static void main(String[] args) throws Exception { 18 | String code = "2*3+4+5*5"; 19 | Calculator calculator = new Calculator(); 20 | calculator.evaluate(code); 21 | } 22 | 23 | /** 24 | * 利用词法分析器来处理传入的代码,处理成 tokens 25 | * 然后调用 addition 表达式来进行处理 26 | * 加法表达式 => 乘法表达式 => 基础表达式 27 | * 这些表达式都是通过深度遍历进行递归处理,直到找到终结符,即元素不可再拆分 28 | */ 29 | 30 | public void evaluate(String code) throws Exception { 31 | AstNode node = parse(code); 32 | dumpAST(node,""); 33 | evaluate(node,""); 34 | } 35 | 36 | public AstNode parse(String code) throws Exception { 37 | SimpleLexer simpleLexer = new SimpleLexer(); 38 | TokenReader tokens = simpleLexer.tokenize(code); 39 | AstNode node = prog(tokens); 40 | return node; 41 | } 42 | 43 | public AstNode prog(TokenReader tokens) throws Exception { 44 | // 创建根节点并调用 加法表达式 45 | SimpleAstNode bootNode = new SimpleAstNode(AstNodeType.Programm,"Calculator"); 46 | SimpleAstNode child = additive(tokens); 47 | if (child != null){ 48 | bootNode.addChildren(child); 49 | } 50 | return bootNode; 51 | } 52 | 53 | // 递归下降法 54 | public int evaluate(AstNode node,String indent) throws Exception{ 55 | // 求最终结果 56 | int result = 0; 57 | AstNodeType type = node.getType(); 58 | System.out.println(indent + "Calculating: " + type); 59 | switch (type){ 60 | case Programm: 61 | for(AstNode child:node.getChildren()){ 62 | result = evaluate(child,indent + "\t"); 63 | } 64 | break; 65 | case Identifier: 66 | String varName = node.getText(); 67 | if (variables.containsKey(varName)) { 68 | Integer value = variables.get(varName); 69 | if (value != null) { 70 | result = value.intValue(); 71 | } else { 72 | throw new Exception("variable " + varName + " has not been set any value"); 73 | } 74 | } 75 | else{ 76 | throw new Exception("unknown variable: " + varName); 77 | } 78 | break; 79 | case Additive: 80 | AstNode child1 = node.getChildren().get(0); 81 | // 不断进行递归求解 82 | int value1 = evaluate(child1,indent + "\t"); // 计算当前节点下的所有值的和 83 | AstNode child2 = node.getChildren().get(1); 84 | int value2 = evaluate(child2,indent + "\t"); 85 | if (node.getText().equals("+")){ // 递归最后运算对逻辑 86 | result = value1+value2; 87 | } 88 | break; 89 | case Multiplicative: 90 | child1 = node.getChildren().get(0); 91 | // 不断进行递归求解 92 | value1 = evaluate(child1,indent + "\t"); 93 | child2 = node.getChildren().get(1); 94 | value2 = evaluate(child2,indent + "\t"); 95 | if (node.getText().equals("*")){ // 递归最后运算对逻辑 96 | result = value1 * value2; 97 | } 98 | break; 99 | case IntLiteral: 100 | result = Integer.valueOf(node.getText()).intValue(); 101 | break; 102 | // case Identifier: 103 | // result = Integer.valueOf(node.getText()).intValue(); 104 | // break; 105 | default: 106 | } 107 | System.out.println(indent + "Result: " + result); 108 | return result; 109 | } 110 | 111 | 112 | /** 113 | * 加法表达式, 这样就变成左递归了... 有点牛逼,左递归 114 | * add = multiplicative (+multiplicative)* 115 | * @param tokens 116 | * @return 117 | */ 118 | public SimpleAstNode additive(TokenReader tokens) throws Exception{ 119 | SimpleAstNode child1 = multiplicative(tokens); 120 | SimpleAstNode node = child1; // 乘法子树 121 | if (child1 != null){ 122 | while(true){ 123 | Token token = tokens.peek(); 124 | if (token!=null && token.getType() == TokenType.Plus){ // + 125 | token = tokens.read(); // 对加号进行消耗 126 | SimpleAstNode child2 = multiplicative(tokens); // 127 | node = new SimpleAstNode(AstNodeType.Additive,token.getText()); // 创建 * 的节点,反之返回树,学到了 128 | node.addChildren(child1); 129 | node.addChildren(child2); 130 | child1 = node; // child1 在while中就依靠这个来变化 明白了 往节点里不停的加 + 131 | 132 | }else { 133 | break; 134 | } 135 | } 136 | 137 | } 138 | return node; 139 | } 140 | 141 | /** 142 | * 右递归,左递归换一下 additive 和 multiplicative 然后需要换一下判断条件 但是这样会导致死循环,即不断调用自身, 143 | */ 144 | 145 | // public SimpleAstNode additive(TokenReader tokens) throws Exception{ 146 | // // multiplicative + add , multiplicative 到最后为 int ,相当于 int + addexpression => 右递归 147 | // SimpleAstNode child1 = multiplicative(tokens); 148 | // SimpleAstNode node = child1; // 乘法子树 149 | // Token token = tokens.peek(); 150 | // if (token != null && child1 != null){ 151 | // if (token.getType() == TokenType.Plus) { // 如果是 + 号 152 | // token = tokens.read(); // 对加号进行消耗 153 | // SimpleAstNode child2 = additive(tokens); // 154 | // if (child2 != null){ 155 | // node = new SimpleAstNode(AstNodeType.Additive, token.getText()); // 创建 * 的节点,反之返回树,学到了 156 | // node.addChildren(child1); 157 | // node.addChildren(child2); 158 | // }else { 159 | // throw new Exception("invalid multiplicative expression, expecting the right part."); 160 | // } 161 | // } 162 | // } 163 | // return node; 164 | // } 165 | 166 | /** 167 | * 乘法表达式 168 | * @param tokens 169 | * @return 170 | */ 171 | public SimpleAstNode multiplicative(TokenReader tokens) throws Exception{ 172 | // 1*2*3 173 | SimpleAstNode child1 = primary(tokens); // 1 174 | SimpleAstNode node = child1; // 递归的思想,如果读到最里面了 就返回 int, 175 | Token token = tokens.peek(); 176 | if (token != null && child1 != null){ 177 | if (token.getType() == TokenType.Star){ 178 | token = tokens.read(); // 对 * 进行消耗,此时 token 为 * 179 | SimpleAstNode child2 = multiplicative(tokens); 180 | if (child2 != null){ 181 | node = new SimpleAstNode(AstNodeType.Multiplicative,token.getText()); // 创建 * 的节点,反之返回树,学到了 182 | node.addChildren(child1); 183 | node.addChildren(child2); 184 | } else { 185 | throw new Exception("invalid multiplicative expression, expecting the right part."); 186 | } 187 | 188 | } 189 | } 190 | return node; 191 | } 192 | 193 | /** 194 | * 基础表达式 195 | * @param tokens 196 | * @return 197 | */ 198 | public SimpleAstNode primary(TokenReader tokens){ 199 | SimpleAstNode node = null; 200 | Token token = tokens.peek(); // 对 token 进行一次预读 201 | if (token != null){ 202 | // 如果是 int 类型 203 | if (token.getType() == TokenType.IntLiteral){ 204 | token = tokens.read(); // 要对 token 进行消耗推进 205 | return new SimpleAstNode(AstNodeType.IntLiteral,token.getText()); 206 | }else if (token.getType() == TokenType.Identifier){ 207 | token = tokens.read(); 208 | return new SimpleAstNode(AstNodeType.Identifier,token.getText()); 209 | } 210 | } 211 | return node; 212 | } 213 | 214 | 215 | /** 216 | * 创建了一个 Ast节点,属性:类型、数值、父节点、子节点、添加节点 217 | */ 218 | // class SimpleAstNode implements AstNode{ 219 | // 220 | // private AstNodeType type = null; 221 | // private String text = null; 222 | // private AstNode parent = null; // 只有一个父节点 223 | // private List childrens = new ArrayList<>(); 224 | // private List readOnlyChildrens = Collections.unmodifiableList(childrens); // 创建一个可读的列表 225 | // 226 | // 227 | // public SimpleAstNode(AstNodeType type, String text) { 228 | // this.type = type; 229 | // this.text = text; 230 | // } 231 | // 232 | // @Override 233 | // public AstNode getParent() { 234 | // return parent; 235 | // } 236 | // 237 | // @Override 238 | // public List getChildren() { 239 | // return readOnlyChildrens; 240 | // } 241 | // 242 | // @Override 243 | // public AstNodeType getType() { 244 | // return type; 245 | // } 246 | // 247 | // @Override 248 | // public String getText() { 249 | // return text; 250 | // } 251 | // 252 | // public void addChildren(SimpleAstNode child){ 253 | // childrens.add(child); // 我之前为什么要多此一举... 254 | // child.parent = this; 255 | // } 256 | // } 257 | 258 | public void dumpAST(AstNode node, String indent) { 259 | System.out.println(indent + node.getType() + " " + node.getText()); 260 | for (AstNode child : node.getChildren()) { 261 | dumpAST(child, indent + "\t"); 262 | } 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/calc/SimpleAstNode.java: -------------------------------------------------------------------------------- 1 | package calc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public class SimpleAstNode implements AstNode{ 8 | 9 | private AstNodeType type = null; 10 | private String text = null; 11 | private AstNode parent = null; // 只有一个父节点 12 | private List childrens = new ArrayList<>(); 13 | private List readOnlyChildrens = Collections.unmodifiableList(childrens); // 创建一个可读的列表 14 | 15 | 16 | public SimpleAstNode(AstNodeType type, String text) { 17 | this.type = type; 18 | this.text = text; 19 | } 20 | 21 | @Override 22 | public AstNode getParent() { 23 | return parent; 24 | } 25 | 26 | @Override 27 | public List getChildren() { 28 | return readOnlyChildrens; 29 | } 30 | 31 | @Override 32 | public AstNodeType getType() { 33 | return type; 34 | } 35 | 36 | @Override 37 | public String getText() { 38 | return text; 39 | } 40 | 41 | public void addChildren(SimpleAstNode child){ 42 | childrens.add(child); // 我之前为什么要多此一举... 43 | child.parent = this; 44 | } 45 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/demo/test.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class test { 4 | public static void main(String[] args) { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/DfaState.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public enum DfaState{ 4 | // 标示状态机的初始化 5 | Initial, 6 | 7 | // 数字 8 | IntLiteral, 9 | // 符号,>= <= > < 10 | GT,GE, // GE >= 11 | Assignment, // = 12 | Plus, // + 13 | SemiColon, // ; 14 | Minus, // - 15 | Star, // * 16 | Slash, // / 17 | 18 | // 保留字,int 这里只做int, if else if 这些不去管 19 | INT, // 识别出来是 int 类型 20 | Id_INT1, // => n 21 | Id_INT2, // => t 22 | Id_INT3, // blankt/switch 23 | 24 | // 用户定义的变量 25 | Identifier,Id, 26 | } 27 | 28 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/SimpleLexer.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | import java.io.CharArrayReader; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | @SuppressWarnings("all") 8 | public class SimpleLexer { 9 | 10 | public static void main(String[] args) { 11 | SimpleLexer lexer = new SimpleLexer(); 12 | 13 | String script = "int num = 2+3;"; 14 | System.out.println("parse :" + script); 15 | SimpleTokenReader tokenReader = lexer.tokenize(script); 16 | 17 | dump(tokenReader); 18 | } 19 | 20 | 21 | // 字符判断 22 | private boolean isAlpha(int ch) { 23 | return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'; 24 | } 25 | 26 | // 数字判断 27 | private boolean isDigit(int ch) { 28 | return ch >= '0' && ch <= '9'; 29 | } 30 | 31 | // 空白字符判断, char 类型直接进行比较 32 | private boolean isBlank(int ch) { 33 | return ch == ' ' || ch == '\t' || ch == '\n'; 34 | } 35 | 36 | // 这也太妙了把... 37 | private StringBuffer tokenText = null; 38 | private List tokenList = null; 39 | private SimpleToken token = null; 40 | 41 | // 状态机的初始化/切换,传入的应该是字符 42 | // 状态机状态和 token type 大部分情况下都是相似的 43 | private DfaState initToken(char ch) { 44 | // 如果不是最开始的状态,说明上一个 token 已经解析完了 45 | if (tokenText.length() > 0) { 46 | // 上一个 token 已经解析完成了 ,把解析完成的 token 放到 list 中 47 | token.setText(tokenText.toString()); 48 | tokenList.add(token); 49 | // 重新进行置空 50 | tokenText = new StringBuffer(); 51 | token = new SimpleToken(); 52 | } 53 | 54 | DfaState newState = DfaState.Initial; 55 | if (isAlpha(ch)) { 56 | // int 单独处理 57 | if (ch == 'i') { 58 | newState = DfaState.Id_INT1; 59 | } else { 60 | newState = DfaState.Id; // 状态机的类型 61 | } 62 | token.setType(TokenType.Identifier); // token 的类型 63 | tokenText.append(ch); // 暂时存储 64 | } else if (isDigit(ch)) { 65 | newState = DfaState.IntLiteral; 66 | token.setType(TokenType.IntLiteral); 67 | tokenText.append(ch); 68 | } else if (ch == '>') { 69 | newState = DfaState.GT; 70 | token.setType(TokenType.GT); 71 | tokenText.append(ch); 72 | } else if (ch == '=') { 73 | newState = DfaState.Assignment; 74 | token.setType(TokenType.Assignment); 75 | tokenText.append(ch); 76 | } else if (ch == '+') { 77 | newState = DfaState.Plus; 78 | token.setType(TokenType.Plus); 79 | tokenText.append(ch); 80 | } else if (ch == ';') { 81 | newState = DfaState.SemiColon; 82 | token.setType(TokenType.SemiColon); 83 | tokenText.append(ch); 84 | } else if (ch == '-') { 85 | newState = DfaState.Minus; 86 | token.setType(TokenType.Minus); 87 | tokenText.append(ch); 88 | } else if (ch == '*') { 89 | newState = DfaState.Star; 90 | token.setType(TokenType.Star); 91 | tokenText.append(ch); 92 | } else if (ch == '/') { 93 | newState = DfaState.Slash; 94 | token.setType(TokenType.Slash); 95 | tokenText.append(ch); 96 | } 97 | // 如果上面三个都没有走进去的话,那么就没遇到开始状态机的机会,所以还是 init 98 | return newState; 99 | } 100 | 101 | // int age = 10 102 | public SimpleTokenReader tokenize(String code) { 103 | // 代表这开始,如果不重新进行赋值的话,那么上一句代码解析完的就会影响后面的结果 104 | tokenText = new StringBuffer(); 105 | tokenList = new ArrayList<>(); 106 | token = new SimpleToken(); 107 | CharArrayReader arrayReader = new CharArrayReader(code.toCharArray()); 108 | int ich = 0; 109 | char ch = 0; 110 | // 状态机开始 111 | DfaState state = DfaState.Initial; 112 | try { 113 | // 如果没有读到末尾就一直读 114 | while ((ich = arrayReader.read()) != -1) { 115 | // 读出来的是 ascii 码,进行类型转换 116 | ch = (char) ich; 117 | switch (state) { 118 | case Initial: 119 | state = initToken(ch); 120 | break; 121 | case Id: // 如果是标志符的话就继续读,字符串遍历不需要我们管 122 | if (isAlpha(ch) || isDigit(ch)) { 123 | tokenText.append(ch); // 然后不用做过多修改,状态机不变就行了 124 | // 如果不是状态切换 125 | } else { 126 | state = initToken(ch); 127 | } 128 | break; 129 | // >= 在这里处理 , 这里代表的是上一个 130 | case GT: 131 | if (ch == '=') { 132 | state = DfaState.GE; 133 | token.setType(TokenType.GE); 134 | tokenText.append(ch); 135 | } else { 136 | state = initToken(ch); // 让 initToken 去添加 137 | } 138 | break; 139 | // switch case 不加 break 的话 那么下面的所有 case 中的语句都会执行,直到遇到第一个 break 140 | // 所以等号会到最后一个 break 跳出,遇到符合条件的 char 状态机就会更新,如果不加这个 case 的话状态机就一直不会更新 141 | // Assignment => = => break; 空格没有对应的状态机不会进入 switch ;IntLiteral => 1 => 8 => break; 142 | case Assignment: // 由于之前这里没有加 case 而经过 = 之后状态机一直是 Assignment 然而switch 中没有,所以获取到的后面的 18 都不会在 switch 中进行处理 143 | state = initToken(ch); 144 | break; 145 | case Plus: // 防止 2 + 3 识别不出来 146 | state = initToken(ch); 147 | break; 148 | case Minus: 149 | state = initToken(ch); 150 | break; 151 | case Star: 152 | state = initToken(ch); 153 | break; 154 | case Slash: 155 | state = initToken(ch); 156 | break; 157 | case SemiColon: 158 | case IntLiteral: 159 | if (isDigit(ch)) { 160 | tokenText.append(ch); 161 | } else { 162 | state = initToken(ch); 163 | } 164 | break; 165 | // int or innnst 166 | case Id_INT1: 167 | if (ch == 'n') { 168 | state = DfaState.Id_INT2; 169 | token.setType(TokenType.Identifier); 170 | tokenText.append(ch); 171 | } else if (isAlpha(ch) || isDigit(ch)) { 172 | tokenText.append(ch); 173 | } else { 174 | state = initToken(ch); 175 | } 176 | break; 177 | case Id_INT2: 178 | if (ch == 't') { 179 | // int age ,后面需要跟空格 180 | state = DfaState.Id_INT3; 181 | token.setType(TokenType.Identifier); 182 | tokenText.append(ch); 183 | } else if (isAlpha(ch) || isDigit(ch)) { 184 | tokenText.append(ch); 185 | } else { 186 | state = initToken(ch); 187 | } 188 | break; 189 | // int age or intaged 190 | case Id_INT3: 191 | if (isBlank(ch)) { 192 | token.setType(TokenType.Int); // 前面的变量是 int 类型 193 | state = initToken(ch); 194 | } else { 195 | // intaofjdoaf 196 | state = DfaState.Id; 197 | tokenText.append(ch); 198 | } 199 | break; 200 | default: 201 | } 202 | } 203 | // 如果 tokenText > 0 那么就说明 token 还没有被放进去,因为放到 tokenlist 里面就会清空 204 | // 最后一个 token 的话要把它放到tokenlist 里面去 205 | if (tokenText.length() > 0) { 206 | initToken(ch); 207 | } 208 | 209 | } catch (Exception e) { 210 | e.printStackTrace(); 211 | } 212 | return new SimpleTokenReader(tokenList); 213 | } 214 | 215 | 216 | public static void dump(SimpleTokenReader simpleTokenReader) { 217 | 218 | System.out.println("type\ttext"); 219 | Token token = null; 220 | while ((token = simpleTokenReader.read()) != null) { 221 | System.out.println(token.getType() + "\t\t" + token.getText()); 222 | } 223 | } 224 | 225 | 226 | /** 227 | * 内部类这样外部就无法访问了 228 | */ 229 | // private class SimpleTokenReader implements TokenReader { 230 | // private List tokenList = null; 231 | // private int position = 0; 232 | // 233 | // public SimpleTokenReader(List tokenList) { 234 | // this.tokenList = tokenList; 235 | // } 236 | // 237 | // @Override 238 | // public Token read() { 239 | // // 需要做一个判断,如果读到末尾了就不读了 240 | // if (position < tokenList.size()) { 241 | // return tokenList.get(position++); 242 | // } 243 | // return null; 244 | // } 245 | // 246 | // @Override 247 | // public Token peek() { 248 | // if (position < tokenList.size()) { 249 | // return tokenList.get(position); 250 | // } 251 | // return null; 252 | // } 253 | // 254 | // @Override 255 | // public void unread() { 256 | // if (position > 0) { 257 | // position--; 258 | // } 259 | // } 260 | // 261 | // @Override 262 | // public int getPosition() { 263 | // return position; 264 | // } 265 | // 266 | // @Override 267 | // public void setPosition(int position) { 268 | // if (position >= 0 && position < tokenList.size()) 269 | // this.position = position; 270 | // } 271 | // } 272 | 273 | // 存储 token 的值 和 类型 274 | // private final class SimpleToken implements Token { 275 | // 276 | // private String text = null; 277 | // private TokenType type = null; 278 | // 279 | // @Override 280 | // public TokenType getType() { 281 | // return type; 282 | // } 283 | // 284 | // @Override 285 | // public String getText() { 286 | // return text; 287 | // } 288 | // } 289 | 290 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/SimpleToken.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public final class SimpleToken implements Token { 4 | 5 | private String text = null; 6 | private TokenType type = null; 7 | 8 | @Override 9 | public void setText(String text) { 10 | this.text = text; 11 | } 12 | 13 | @Override 14 | public void setType(TokenType type) { 15 | this.type = type; 16 | } 17 | 18 | @Override 19 | public TokenType getType() { 20 | return type; 21 | } 22 | 23 | @Override 24 | public String getText() { 25 | return text; 26 | } 27 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/SimpleTokenReader.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | import java.util.List; 4 | 5 | public class SimpleTokenReader implements TokenReader { 6 | private List tokenList = null; 7 | private int position = 0; 8 | 9 | public SimpleTokenReader(List tokenList) { 10 | this.tokenList = tokenList; 11 | } 12 | 13 | @Override 14 | public Token read() { 15 | // 需要做一个判断,如果读到末尾了就不读了 16 | if (position < tokenList.size()) { 17 | return tokenList.get(position++); 18 | } 19 | return null; 20 | } 21 | 22 | @Override 23 | public Token peek() { 24 | if (position < tokenList.size()) { 25 | return tokenList.get(position); 26 | } 27 | return null; 28 | } 29 | 30 | @Override 31 | public void unread() { 32 | if (position > 0) { 33 | position--; 34 | } 35 | } 36 | 37 | // 记录初始位置 38 | @Override 39 | public int getPosition() { 40 | return position; 41 | } 42 | 43 | // 根据初始位置进行回溯 44 | @Override 45 | public void setPosition(int position) { 46 | if (position >= 0 && position < tokenList.size()) 47 | this.position = position; 48 | } 49 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/Token.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public interface Token { 4 | /** 5 | * age=45 : type=>StringLiteral text=>45 6 | * @return 7 | */ 8 | public TokenType getType(); 9 | public String getText(); 10 | public void setType(TokenType tokenType); 11 | public void setText(String text); 12 | } 13 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/TokenReader.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | /** 4 | * 就是从 token 数组中进行遍历吧 5 | */ 6 | public interface TokenReader { 7 | /** 8 | * 返回Token流中下一个Token,并从流中取出。 如果流已经为空,返回null; 9 | */ 10 | public Token read(); 11 | 12 | /** 13 | * 返回Token流中下一个Token,但不从流中取出。 如果流已经为空,返回null; 14 | */ 15 | public Token peek(); 16 | 17 | /** 18 | * Token流回退一步。恢复原来的Token。 19 | */ 20 | public void unread(); 21 | 22 | /** 23 | * 获取Token流当前的读取位置。 24 | * @return 25 | */ 26 | public int getPosition(); 27 | 28 | /** 29 | * 设置Token流当前的读取位置 30 | * @param position 31 | */ 32 | public void setPosition(int position); 33 | } 34 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/lexer/TokenType.java: -------------------------------------------------------------------------------- 1 | package lexer; 2 | 3 | public enum TokenType { 4 | Plus, // + 5 | Minus, // - 6 | Star, // * 7 | Slash, // / 8 | 9 | GE, // >= 10 | GT, // > 11 | EQ, // == 12 | LE, // <= 13 | LT, // < 14 | 15 | SemiColon, // ; 16 | LeftParen, // ( 17 | RightParen,// ) 18 | 19 | Assignment,// = 20 | 21 | If, 22 | Else, 23 | 24 | Int, 25 | 26 | Identifier, //标识符 27 | 28 | IntLiteral, //整型字面量 29 | StringLiteral //字符串字面量 30 | } 31 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/AnnotatedTree.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | import org.antlr.v4.runtime.tree.ParseTree; 5 | 6 | import java.util.HashMap; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * 注释树 13 | * 语义分析的结果都放在这里。跟AST的节点建立关联。包括: 14 | * 1.类型信息,包括基本类型和用户自定义类型; 15 | * 2.变量和函数调用的消解; 16 | * 3.作用域Scope。在Scope中包含了该作用域的所有符号。Variable、Function、Class等都是符号。 17 | * 在这里放置的数据是需要和 ast 树产生关联 18 | */ 19 | public class AnnotatedTree { 20 | 21 | protected ParseTree ast = null; 22 | 23 | // 命名空间 24 | NameSpace nameSpace = null; //全局命名空间 25 | 26 | // 解析出来的所有类型,包括类和函数,以后还可以包括数组和枚举。类的方法也作为单独的要素放进去。 27 | protected List types = new LinkedList(); 28 | 29 | 30 | // 存放 ast 对应的 变量名的 地方,并不存储变量,只是存储变量名 31 | protected Map symbolOfNode = new HashMap<>(); 32 | 33 | // AST节点对应的Scope,如for、函数调用会启动新的Scope,每个 节点对应的 作用域 34 | protected Map node2Scope = new HashMap<>(); 35 | 36 | // 每个节点解析出来的节点 37 | protected Map typeOfNode = new HashMap<>(); 38 | 39 | 40 | public Scope enclosingScopeOfNode(ParserRuleContext node){ 41 | Scope rtn = null; 42 | ParserRuleContext parent = node.getParent(); 43 | // 如果父节点不为 null 44 | if (parent != null){ 45 | rtn = node2Scope.get(parent); 46 | if (rtn == null){ 47 | rtn = enclosingScopeOfNode(parent); 48 | } 49 | } 50 | return rtn; 51 | } 52 | 53 | /** 54 | * 递归从作用域中进行寻找,如果当前作用域中找不到那么就到上级作用域进行寻找 55 | * @param scope 56 | * @param idName 57 | * @return 58 | */ 59 | public Variable lookupVariable(Scope scope,String idName){ 60 | Variable variable = scope.getVariable(idName); 61 | if (variable == null && scope.enclosingScope != null){ 62 | variable = lookupVariable(scope.enclosingScope,idName); 63 | } 64 | return variable; 65 | } 66 | 67 | /** 68 | * 从函数作用域中寻找函数 69 | */ 70 | public FunctionScope lookupFunction(Scope scope, String idName, List paramTypes){ 71 | FunctionScope rtn = scope.getFunction(idName, paramTypes); 72 | 73 | if (rtn == null && scope.enclosingScope != null) { 74 | rtn = lookupFunction(scope.enclosingScope, idName, paramTypes); 75 | } 76 | return rtn; 77 | } 78 | 79 | protected FunctionScope lookupFunction(Scope scope, String name){ 80 | FunctionScope rtn = null; 81 | 82 | rtn = getFunctionOnlyByName(scope, name); 83 | 84 | 85 | if (rtn == null && scope.enclosingScope != null){ 86 | rtn = lookupFunction(scope.enclosingScope,name); 87 | } 88 | return rtn; 89 | } 90 | 91 | 92 | private FunctionScope getFunctionOnlyByName(Scope scope, String name){ 93 | for (Symbol s : scope.symbols){ 94 | if (s instanceof FunctionScope && s.name.equals(name)){ 95 | return (FunctionScope)s; 96 | } 97 | } 98 | return null; 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/BlockScope.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | /** 6 | * 块,但是由于名字都一样所以需要进行编号 7 | * 每个作用域都需要有自己的名字 8 | */ 9 | public class BlockScope extends Scope{ 10 | private static int index = 1; 11 | 12 | public BlockScope(){ 13 | this.name = "Block" + index++; // 放置 Scope 不重复 14 | } 15 | 16 | public BlockScope(Scope enclosingScope,ParserRuleContext ctx){ 17 | this.name = "Block" + index++; // 放置 Scope 不重复 18 | this.enclosingScope = enclosingScope; 19 | this.ctx = ctx; 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/BreakObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public final class BreakObject { 4 | private static BreakObject instance = new BreakObject(); 5 | 6 | private BreakObject(){ 7 | 8 | } 9 | 10 | //获取唯一的实例。 11 | public static BreakObject instance(){ 12 | return instance; 13 | } 14 | 15 | //在打印时输出Break。 16 | @Override 17 | public String toString() { 18 | return "Break"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/ClassObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | 4 | public class ClassObject extends PlayObject{ 5 | //类型 6 | protected Class type = null; 7 | 8 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/ClassScope.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | /** 6 | * 扫描 ast 树的时候需要创建对应的作用域 7 | * 类作用域,由于是写自己的编译器。。。 所以类的从属关系也要加进去 8 | * 类的作用域,先简单设置一下具体后面再看,他这是尼玛是完全体 一口气吃不成胖子 9 | */ 10 | public class ClassScope extends Scope{ 11 | 12 | private ClassScope parentClass = null; // 父类 13 | 14 | /** 15 | * this 指向自己的变量 16 | */ 17 | 18 | /** 19 | * 不允许有相同的类名 20 | * @param name 21 | * @param ctx 22 | */ 23 | public ClassScope(String name, ParserRuleContext ctx){ 24 | this.name = name; 25 | this.ctx = ctx; // ast 关联的节点 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/CommonLexer.g4: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD licence"] 3 | 版权说明 4 | 本文件的大部分内容来自:https://github.com/antlr/grammars-v4/blob/master/java/JavaParser.g4 5 | 在此基础上进行了一些修改。 6 | 修改者:宫文学 2019年 7 | 8 | 原文件采用BSD licence,本文件仍然采用BSD licence. 9 | 原文件的版权声明如下: 10 | */ 11 | 12 | /* 13 | [The "BSD licence"] 14 | Copyright (c) 2013 Terence Parr, Sam Harwell 15 | Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8) 16 | All rights reserved. 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions 19 | are met: 20 | 1. Redistributions of source code must retain the above copyright 21 | notice, this list of conditions and the following disclaimer. 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in the 24 | documentation and/or other materials provided with the distribution. 25 | 3. The name of the author may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | lexer grammar CommonLexer; 40 | 41 | @header { 42 | package playscript; 43 | } 44 | 45 | // Keywords 46 | 47 | ABSTRACT: 'abstract'; 48 | ASSERT: 'assert'; 49 | BOOLEAN: 'boolean'; 50 | BREAK: 'break'; 51 | BYTE: 'byte'; 52 | CASE: 'case'; 53 | CATCH: 'catch'; 54 | CHAR: 'char'; 55 | CLASS: 'class'; 56 | CONST: 'const'; 57 | CONTINUE: 'continue'; 58 | DEFAULT: 'default'; 59 | DO: 'do'; 60 | DOUBLE: 'double'; 61 | ELSE: 'else'; 62 | ENUM: 'enum'; 63 | EXTENDS: 'extends'; 64 | FINAL: 'final'; 65 | FINALLY: 'finally'; 66 | FLOAT: 'float'; 67 | FOR: 'for'; 68 | IF: 'if'; 69 | GOTO: 'goto'; 70 | IMPLEMENTS: 'implements'; 71 | IMPORT: 'import'; 72 | INSTANCEOF: 'instanceof'; 73 | INT: 'int'; 74 | INTERFACE: 'interface'; 75 | LONG: 'long'; 76 | NATIVE: 'native'; 77 | NEW: 'new'; 78 | PACKAGE: 'package'; 79 | PRIVATE: 'private'; 80 | PROTECTED: 'protected'; 81 | PUBLIC: 'public'; 82 | RETURN: 'return'; 83 | SHORT: 'short'; 84 | STATIC: 'static'; 85 | STRICTFP: 'strictfp'; 86 | SUPER: 'super'; 87 | SWITCH: 'switch'; 88 | SYNCHRONIZED: 'synchronized'; 89 | THIS: 'this'; 90 | THROW: 'throw'; 91 | THROWS: 'throws'; 92 | TRANSIENT: 'transient'; 93 | TRY: 'try'; 94 | VOID: 'void'; 95 | VOLATILE: 'volatile'; 96 | WHILE: 'while'; 97 | 98 | FUNCTION: 'function'; 99 | 100 | STRING: 'string'; //added on 2019-08-29 by Richard Gong 101 | 102 | // Literals 103 | 104 | DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?; 105 | HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?; 106 | OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?; 107 | BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?; 108 | 109 | FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart? [fFdD]? 110 | | Digits (ExponentPart [fFdD]? | [fFdD]) 111 | ; 112 | 113 | HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?; 114 | 115 | BOOL_LITERAL: 'true' 116 | | 'false' 117 | ; 118 | 119 | CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\''; 120 | 121 | STRING_LITERAL: '"' (~["\\\r\n] | EscapeSequence)* '"'; 122 | 123 | NULL_LITERAL: 'null'; 124 | 125 | // Separators 126 | 127 | LPAREN: '('; 128 | RPAREN: ')'; 129 | LBRACE: '{'; 130 | RBRACE: '}'; 131 | LBRACK: '['; 132 | RBRACK: ']'; 133 | SEMI: ';'; 134 | COMMA: ','; 135 | DOT: '.'; 136 | 137 | // Operators 138 | 139 | ASSIGN: '='; 140 | GT: '>'; 141 | LT: '<'; 142 | BANG: '!'; 143 | TILDE: '~'; 144 | QUESTION: '?'; 145 | COLON: ':'; 146 | EQUAL: '=='; 147 | LE: '<='; 148 | GE: '>='; 149 | NOTEQUAL: '!='; 150 | AND: '&&'; 151 | OR: '||'; 152 | INC: '++'; 153 | DEC: '--'; 154 | ADD: '+'; 155 | SUB: '-'; 156 | MUL: '*'; 157 | DIV: '/'; 158 | BITAND: '&'; 159 | BITOR: '|'; 160 | CARET: '^'; 161 | MOD: '%'; 162 | 163 | ADD_ASSIGN: '+='; 164 | SUB_ASSIGN: '-='; 165 | MUL_ASSIGN: '*='; 166 | DIV_ASSIGN: '/='; 167 | AND_ASSIGN: '&='; 168 | OR_ASSIGN: '|='; 169 | XOR_ASSIGN: '^='; 170 | MOD_ASSIGN: '%='; 171 | LSHIFT_ASSIGN: '<<='; 172 | RSHIFT_ASSIGN: '>>='; 173 | URSHIFT_ASSIGN: '>>>='; 174 | 175 | // Java 8 tokens 176 | 177 | ARROW: '->'; 178 | COLONCOLON: '::'; 179 | 180 | // Additional symbols not defined in the lexical specification 181 | 182 | AT: '@'; 183 | ELLIPSIS: '...'; 184 | 185 | // Whitespace and comments 186 | 187 | WS: [ \t\r\n\u000C]+ -> channel(HIDDEN); 188 | COMMENT: '/*' .*? '*/' -> channel(HIDDEN); 189 | LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); 190 | 191 | // Identifiers 192 | 193 | IDENTIFIER: Letter LetterOrDigit*; 194 | 195 | // Fragment rules 196 | 197 | fragment ExponentPart 198 | : [eE] [+-]? Digits 199 | ; 200 | 201 | fragment EscapeSequence 202 | : '\\' [btnfr"'\\] 203 | | '\\' ([0-3]? [0-7])? [0-7] 204 | | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit 205 | ; 206 | 207 | fragment HexDigits 208 | : HexDigit ((HexDigit | '_')* HexDigit)? 209 | ; 210 | 211 | fragment HexDigit 212 | : [0-9a-fA-F] 213 | ; 214 | 215 | fragment Digits 216 | : [0-9] ([0-9_]* [0-9])? 217 | ; 218 | 219 | fragment LetterOrDigit 220 | : Letter 221 | | [0-9] 222 | ; 223 | 224 | fragment Letter 225 | : [a-zA-Z$_] // these are the "java letters" below 0x7F 226 | | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate 227 | | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 228 | ; 229 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/CommonLexer.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/DefaultFunctionType.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import java.util.List; 4 | 5 | public class DefaultFunctionType implements FunctionType{ 6 | @Override 7 | public Type getReturnType() { 8 | return null; 9 | } 10 | 11 | @Override 12 | public List getParamTypes() { 13 | return null; 14 | } 15 | 16 | @Override 17 | public boolean matchParameterTypes(List paramTypes) { 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public Scope getEnclosingScope() { 28 | return null; 29 | } 30 | 31 | @Override 32 | public boolean isType(Type type) { 33 | return false; 34 | } 35 | 36 | 37 | public static boolean isType(FunctionType type1, FunctionType type2){ 38 | if (type1 == type2) return true; 39 | 40 | /** 41 | * 难道单纯的比较不行吗? 42 | */ 43 | return false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/FunctionObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | /** 4 | * 存放一个函数运行时的本地变量的值,包括参数的值。 5 | */ 6 | public class FunctionObject extends PlayObject{ 7 | //类型 8 | protected FunctionScope function = null; 9 | 10 | /** 11 | * 接收者所在的scope。缺省是function的enclosingScope,也就是词法的Scope。 12 | * 当赋值给一个函数型变量的时候,要修改receiverEnclosingScope等于这个变量的enclosingScope。 13 | */ 14 | protected Variable receiver = null; 15 | 16 | public FunctionObject (FunctionScope function){ 17 | this.function = function; 18 | } 19 | 20 | protected void setFunction(FunctionScope function){ 21 | this.function = function; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/FunctionScope.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | /** 10 | * 函数作用域 11 | */ 12 | @SuppressWarnings("all") 13 | public class FunctionScope extends Scope implements FunctionType{ 14 | 15 | protected List parameters = new LinkedList<>(); 16 | 17 | protected Type returnType = null; 18 | 19 | //闭包变量,即它所引用的外部环境变量,奥。。。 还要处理闭包 20 | protected Set closureVariables = null; 21 | 22 | 23 | private List paramTypes = null; 24 | 25 | protected FunctionScope(String name, Scope enclosingScope, ParserRuleContext ctx) { 26 | this.name = name; 27 | this.enclosingScope = enclosingScope; 28 | this.ctx = ctx; 29 | } 30 | 31 | @Override 32 | public Type getReturnType() { 33 | return returnType; 34 | } 35 | 36 | /** 37 | * 获取函数参数类型 38 | * @return 39 | */ 40 | @Override 41 | public List getParamTypes() { 42 | if (parameters == null){ 43 | paramTypes = new LinkedList<>(); 44 | } 45 | for (Variable parameter:parameters){ 46 | paramTypes.add(parameter.type); 47 | } 48 | return paramTypes; 49 | } 50 | 51 | /** 52 | * 在函数处理这边需要事先检查类型是否匹配 53 | * @param paramTypes 54 | * @return 55 | */ 56 | @Override 57 | public boolean matchParameterTypes(List paramTypes) { 58 | if (paramTypes.size() != parameters.size()){ 59 | return false; 60 | } 61 | boolean match = true; 62 | for (int i=0;i getParamTypes(); 10 | 11 | public boolean matchParameterTypes(List paramTypes); 12 | } 13 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/LValue.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public interface LValue { 4 | 5 | public Object getValue(); 6 | 7 | public void setValue(Object value); 8 | 9 | public Variable getVariable(); 10 | 11 | public PlayObject getValueContainer(); 12 | //public StackFrame getFrame(); 13 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/NameSpace.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | public class NameSpace extends BlockScope{ 6 | 7 | protected NameSpace(String name, Scope enclosingScope, ParserRuleContext ctx) { 8 | this.name = name; 9 | this.enclosingScope = enclosingScope; 10 | this.ctx = ctx; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/NullObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | 4 | /** 5 | * 用来代表null值的对象。 6 | * 采用单例模式。用instance()方法来获得一个对象实例。 7 | */ 8 | public final class NullObject extends ClassObject { 9 | private static NullObject instance = new NullObject(); 10 | 11 | private NullObject(){ 12 | 13 | } 14 | 15 | //获取唯一的实例。 16 | public static NullObject instance(){ 17 | return instance; 18 | } 19 | 20 | //在打印时输出Null。 21 | @Override 22 | public String toString() { 23 | return "Null"; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * PlayScript的对象 9 | */ 10 | public class PlayObject { 11 | //成员变量 12 | protected Map fields = new HashMap(); 13 | 14 | public Object getValue(Variable variable){ 15 | Object rtn = fields.get(variable); 16 | //TODO 父类的属性如何返回?还是说都在这里了? 17 | 18 | //替换成自己的NullObject 19 | if (rtn == null){ 20 | rtn = NullObject.instance(); 21 | } 22 | return rtn; 23 | } 24 | 25 | public void setValue(Variable variable, Object value){ 26 | fields.put(variable, value); 27 | } 28 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayScript.g4: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD licence"] 3 | 版权说明 4 | 本文件的大部分内容来自:https://github.com/antlr/grammars-v4/blob/master/java/JavaParser.g4 5 | 在此基础上进行了一些修改。 6 | 修改者:宫文学 2019年 7 | 8 | 原文件采用BSD licence,本文件仍然采用BSD licence. 9 | 原文件的版权声明如下: 10 | */ 11 | 12 | /* 13 | [The "BSD licence"] 14 | Copyright (c) 2013 Terence Parr, Sam Harwell 15 | Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8) 16 | All rights reserved. 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions 19 | are met: 20 | 1. Redistributions of source code must retain the above copyright 21 | notice, this list of conditions and the following disclaimer. 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in the 24 | documentation and/or other materials provided with the distribution. 25 | 3. The name of the author may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | grammar PlayScript; 40 | 41 | //options { tokenVocab=CommonLexer; } 42 | import CommonLexer; 43 | 44 | @header { 45 | package playscript; 46 | } 47 | 48 | classDeclaration 49 | : CLASS IDENTIFIER 50 | (EXTENDS typeType)? 51 | (IMPLEMENTS typeList)? 52 | classBody 53 | ; 54 | 55 | classBody 56 | : '{' classBodyDeclaration* '}' 57 | ; 58 | 59 | // interfaceBody 60 | // : '{' interfaceBodyDeclaration* '}' 61 | // ; 62 | 63 | classBodyDeclaration 64 | : ';' 65 | //| STATIC? block 66 | | memberDeclaration 67 | ; 68 | 69 | memberDeclaration 70 | : functionDeclaration 71 | // | genericFunctionDeclaration 72 | | fieldDeclaration 73 | // | constructorDeclaration 74 | // | genericConstructorDeclaration 75 | // | interfaceDeclaration 76 | // | annotationTypeDeclaration 77 | | classDeclaration 78 | // | enumDeclaration 79 | ; 80 | 81 | functionDeclaration 82 | : typeTypeOrVoid? IDENTIFIER formalParameters ('[' ']')* 83 | (THROWS qualifiedNameList)? 84 | functionBody 85 | ; 86 | 87 | 88 | functionBody 89 | : block 90 | | ';' 91 | ; 92 | 93 | typeTypeOrVoid 94 | : typeType 95 | | VOID 96 | ; 97 | 98 | qualifiedNameList 99 | : qualifiedName (',' qualifiedName)* 100 | ; 101 | 102 | formalParameters 103 | : '(' formalParameterList? ')' 104 | ; 105 | 106 | formalParameterList 107 | : formalParameter (',' formalParameter)* (',' lastFormalParameter)? 108 | | lastFormalParameter 109 | ; 110 | 111 | formalParameter 112 | : variableModifier* typeType variableDeclaratorId 113 | ; 114 | 115 | lastFormalParameter 116 | : variableModifier* typeType '...' variableDeclaratorId 117 | ; 118 | 119 | variableModifier 120 | : FINAL 121 | //| annotation 122 | ; 123 | 124 | qualifiedName 125 | : IDENTIFIER ('.' IDENTIFIER)* 126 | ; 127 | 128 | fieldDeclaration 129 | //: typeType variableDeclarators ';' 130 | : variableDeclarators ';' 131 | ; 132 | 133 | constructorDeclaration 134 | : IDENTIFIER formalParameters (THROWS qualifiedNameList)? constructorBody=block 135 | ; 136 | 137 | variableDeclarators 138 | : typeType variableDeclarator (',' variableDeclarator)* 139 | ; 140 | 141 | variableDeclarator 142 | : variableDeclaratorId ('=' variableInitializer)? 143 | ; 144 | 145 | variableDeclaratorId 146 | : IDENTIFIER ('[' ']')* 147 | ; 148 | 149 | variableInitializer 150 | : arrayInitializer 151 | | expression 152 | ; 153 | 154 | arrayInitializer 155 | : '{' (variableInitializer (',' variableInitializer)* (',')? )? '}' 156 | ; 157 | 158 | classOrInterfaceType 159 | : IDENTIFIER ('.' IDENTIFIER)* 160 | //: IDENTIFIER 161 | ; 162 | 163 | typeArgument 164 | : typeType 165 | | '?' ((EXTENDS | SUPER) typeType)? 166 | ; 167 | 168 | literal 169 | : integerLiteral 170 | | floatLiteral 171 | | CHAR_LITERAL 172 | | STRING_LITERAL 173 | | BOOL_LITERAL 174 | | NULL_LITERAL 175 | ; 176 | 177 | integerLiteral 178 | : DECIMAL_LITERAL 179 | | HEX_LITERAL 180 | | OCT_LITERAL 181 | | BINARY_LITERAL 182 | ; 183 | 184 | floatLiteral 185 | : FLOAT_LITERAL 186 | | HEX_FLOAT_LITERAL 187 | ; 188 | 189 | // STATEMENTS / BLOCKS 190 | prog 191 | : blockStatements 192 | ; 193 | 194 | block 195 | : '{' blockStatements '}' 196 | ; 197 | 198 | blockStatements 199 | : blockStatement* 200 | ; 201 | 202 | blockStatement 203 | : variableDeclarators ';' 204 | | statement 205 | // | localTypeDeclaration 206 | | functionDeclaration 207 | | classDeclaration 208 | ; 209 | 210 | statement 211 | : blockLabel=block 212 | // | ASSERT expression (':' expression)? ';' 213 | | IF parExpression statement (ELSE statement)? 214 | | FOR '(' forControl ')' statement 215 | | WHILE parExpression statement 216 | | DO statement WHILE parExpression ';' 217 | //| TRY block (catchClause+ finallyBlock? | finallyBlock) 218 | //| TRY resourceSpecification block catchClause* finallyBlock? 219 | | SWITCH parExpression '{' switchBlockStatementGroup* switchLabel* '}' 220 | //| SYNCHRONIZED parExpression block 221 | | RETURN expression? ';' 222 | //| THROW expression ';' 223 | | BREAK IDENTIFIER? ';' 224 | | CONTINUE IDENTIFIER? ';' 225 | | SEMI 226 | | statementExpression=expression ';' 227 | | identifierLabel=IDENTIFIER ':' statement 228 | ; 229 | 230 | /** Matches cases then statements, both of which are mandatory. 231 | * To handle empty cases at the end, we add switchLabel* to statement. 232 | */ 233 | switchBlockStatementGroup 234 | : switchLabel+ blockStatement+ 235 | ; 236 | 237 | switchLabel 238 | : CASE (constantExpression=expression | enumConstantName=IDENTIFIER) ':' 239 | | DEFAULT ':' 240 | ; 241 | 242 | forControl 243 | : enhancedForControl 244 | | forInit? ';' expression? ';' forUpdate=expressionList? 245 | ; 246 | 247 | forInit 248 | : variableDeclarators 249 | | expressionList 250 | ; 251 | 252 | enhancedForControl 253 | : typeType variableDeclaratorId ':' expression 254 | ; 255 | 256 | // EXPRESSIONS 257 | 258 | parExpression 259 | : '(' expression ')' 260 | ; 261 | 262 | expressionList 263 | : expression (',' expression)* 264 | ; 265 | 266 | functionCall 267 | : IDENTIFIER '(' expressionList? ')' 268 | | THIS '(' expressionList? ')' 269 | | SUPER '(' expressionList? ')' 270 | ; 271 | 272 | expression 273 | : primary 274 | | expression bop='.' 275 | ( IDENTIFIER 276 | | functionCall 277 | | THIS 278 | // | NEW nonWildcardTypeArguments? innerCreator 279 | // | SUPER superSuffix 280 | // | explicitGenericInvocation 281 | ) 282 | | expression '[' expression ']' 283 | | functionCall 284 | // | NEW creator //不用new关键字,而是用类名相同的函数直接生成对象。 285 | // | '(' typeType ')' expression 286 | | expression postfix=('++' | '--') 287 | | prefix=('+'|'-'|'++'|'--') expression 288 | | prefix=('~'|'!') expression 289 | | expression bop=('*'|'/'|'%') expression 290 | | expression bop=('+'|'-') expression 291 | | expression ('<' '<' | '>' '>' '>' | '>' '>') expression 292 | | expression bop=('<=' | '>=' | '>' | '<') expression 293 | | expression bop=INSTANCEOF typeType 294 | | expression bop=('==' | '!=') expression 295 | | expression bop='&' expression 296 | | expression bop='^' expression 297 | | expression bop='|' expression 298 | | expression bop='&&' expression 299 | | expression bop='||' expression 300 | | expression bop='?' expression ':' expression 301 | | expression 302 | bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=') 303 | expression 304 | // | lambdaExpression // Java8 305 | 306 | // Java 8 functionReference 307 | // | expression '::' typeArguments? IDENTIFIER 308 | // | typeType '::' (typeArguments? IDENTIFIER | NEW) 309 | // | classType '::' typeArguments? NEW 310 | ; 311 | 312 | 313 | primary 314 | : '(' expression ')' 315 | | THIS 316 | | SUPER 317 | | literal 318 | | IDENTIFIER 319 | // | typeTypeOrVoid '.' CLASS 320 | ; 321 | 322 | typeList 323 | : typeType (',' typeType)* 324 | ; 325 | 326 | typeType 327 | : (classOrInterfaceType| functionType | primitiveType) ('[' ']')* 328 | ; 329 | 330 | functionType 331 | : FUNCTION typeTypeOrVoid '(' typeList? ')' 332 | ; 333 | 334 | primitiveType 335 | : BOOLEAN 336 | | CHAR 337 | | BYTE 338 | | SHORT 339 | | INT 340 | | LONG 341 | | FLOAT 342 | | DOUBLE 343 | | STRING //added on 2019-08-29 by Richard Gong 344 | ; 345 | 346 | creator 347 | : IDENTIFIER arguments 348 | ; 349 | 350 | superSuffix 351 | : arguments 352 | | '.' IDENTIFIER arguments? 353 | ; 354 | 355 | arguments 356 | : '(' expressionList? ')' 357 | ; 358 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayScript.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public class PlayScript { 4 | public static void main(String[] args) { 5 | String script = "int b=10; int myfunc(int a) {int c=3;return a+b+c;} myfunc(2);"; 6 | /** 7 | * 函数内变量的问题,函数内部,函数外部的没有正常进行添加 8 | */ 9 | script = "int b=8;int myfunc(int a) {int c=2; return a+b+c;} myfunc(2);"; 10 | // c 没有获取到 没有添加进去 11 | // script = "int myfunc(int a) {int c=3;return a+c;} myfunc(2);"; 12 | // script = "int myfunc(int a) {return a+3;} myfunc(2);"; 13 | 14 | 15 | AnnotatedTree tree = null; 16 | PlayScriptCompiler compiler = new PlayScriptCompiler(); 17 | 18 | tree = compiler.Compile(script); 19 | Object result = compiler.Execute(tree); 20 | System.out.println(result); 21 | 22 | 23 | 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayScript.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayScriptCompiler.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.CharStreams; 4 | import org.antlr.v4.runtime.CommonTokenStream; 5 | import org.antlr.v4.runtime.tree.ParseTreeWalker; 6 | 7 | 8 | /** 9 | * 将词法 语法 语义 结合在一起 10 | */ 11 | public class PlayScriptCompiler { 12 | 13 | AnnotatedTree at = null; 14 | PlayScriptLexer lexer = null; 15 | PlayScriptParser parser = null; 16 | 17 | public AnnotatedTree Compile(String script) { 18 | at = new AnnotatedTree(); 19 | /** 20 | * 词法解析 21 | */ 22 | lexer = new PlayScriptLexer(CharStreams.fromString(script)); 23 | CommonTokenStream tokens = new CommonTokenStream(lexer); 24 | 25 | /** 26 | * 语法解析,将 Tokens 根据语法规则存放在树节点中 27 | * parser.prog() => prog 为顶节点 28 | */ 29 | parser = new PlayScriptParser(tokens); 30 | at.ast = parser.prog(); 31 | 32 | ParseTreeWalker walker = new ParseTreeWalker(); 33 | 34 | /** 35 | * pass: 类型和作用域 36 | */ 37 | TypeAndScopeScanner scopeScanner = new TypeAndScopeScanner(at); 38 | walker.walk(scopeScanner,at.ast); 39 | 40 | /** 41 | * pass: 解析变量函数声明,这里处理好了基本类型数据,函数传参数,函数返回值, 这里解析的有问题 42 | * 但是函数内部好像没有做处理 43 | */ 44 | TypeResolver typeResolver = new TypeResolver(at); 45 | walker.walk(typeResolver, at.ast); 46 | 47 | /** 48 | * 这一部分是引用的消解,主要是确定变量类型,这一步没有确定变量类型 49 | */ 50 | RefResolver resolver = new RefResolver(at); 51 | walker.walk(resolver, at.ast); 52 | 53 | // DumpAst(at); 54 | 55 | return at; 56 | } 57 | 58 | public void DumpAst(AnnotatedTree at){ 59 | if (at != null) { 60 | System.out.println(at.ast.toStringTree()); 61 | } 62 | } 63 | 64 | public Object Execute(AnnotatedTree at){ 65 | ASTEvaluator visitor = new ASTEvaluator(at); 66 | Object result = visitor.visit(at.ast); 67 | return result; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PlayScriptLexer.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | FUNCTION=51 52 | STRING=52 53 | DECIMAL_LITERAL=53 54 | HEX_LITERAL=54 55 | OCT_LITERAL=55 56 | BINARY_LITERAL=56 57 | FLOAT_LITERAL=57 58 | HEX_FLOAT_LITERAL=58 59 | BOOL_LITERAL=59 60 | CHAR_LITERAL=60 61 | STRING_LITERAL=61 62 | NULL_LITERAL=62 63 | LPAREN=63 64 | RPAREN=64 65 | LBRACE=65 66 | RBRACE=66 67 | LBRACK=67 68 | RBRACK=68 69 | SEMI=69 70 | COMMA=70 71 | DOT=71 72 | ASSIGN=72 73 | GT=73 74 | LT=74 75 | BANG=75 76 | TILDE=76 77 | QUESTION=77 78 | COLON=78 79 | EQUAL=79 80 | LE=80 81 | GE=81 82 | NOTEQUAL=82 83 | AND=83 84 | OR=84 85 | INC=85 86 | DEC=86 87 | ADD=87 88 | SUB=88 89 | MUL=89 90 | DIV=90 91 | BITAND=91 92 | BITOR=92 93 | CARET=93 94 | MOD=94 95 | ADD_ASSIGN=95 96 | SUB_ASSIGN=96 97 | MUL_ASSIGN=97 98 | DIV_ASSIGN=98 99 | AND_ASSIGN=99 100 | OR_ASSIGN=100 101 | XOR_ASSIGN=101 102 | MOD_ASSIGN=102 103 | LSHIFT_ASSIGN=103 104 | RSHIFT_ASSIGN=104 105 | URSHIFT_ASSIGN=105 106 | ARROW=106 107 | COLONCOLON=107 108 | AT=108 109 | ELLIPSIS=109 110 | WS=110 111 | COMMENT=111 112 | LINE_COMMENT=112 113 | IDENTIFIER=113 114 | 'abstract'=1 115 | 'assert'=2 116 | 'boolean'=3 117 | 'break'=4 118 | 'byte'=5 119 | 'case'=6 120 | 'catch'=7 121 | 'char'=8 122 | 'class'=9 123 | 'const'=10 124 | 'continue'=11 125 | 'default'=12 126 | 'do'=13 127 | 'double'=14 128 | 'else'=15 129 | 'enum'=16 130 | 'extends'=17 131 | 'final'=18 132 | 'finally'=19 133 | 'float'=20 134 | 'for'=21 135 | 'if'=22 136 | 'goto'=23 137 | 'implements'=24 138 | 'import'=25 139 | 'instanceof'=26 140 | 'int'=27 141 | 'interface'=28 142 | 'long'=29 143 | 'native'=30 144 | 'new'=31 145 | 'package'=32 146 | 'private'=33 147 | 'protected'=34 148 | 'public'=35 149 | 'return'=36 150 | 'short'=37 151 | 'static'=38 152 | 'strictfp'=39 153 | 'super'=40 154 | 'switch'=41 155 | 'synchronized'=42 156 | 'this'=43 157 | 'throw'=44 158 | 'throws'=45 159 | 'transient'=46 160 | 'try'=47 161 | 'void'=48 162 | 'volatile'=49 163 | 'while'=50 164 | 'function'=51 165 | 'string'=52 166 | 'null'=62 167 | '('=63 168 | ')'=64 169 | '{'=65 170 | '}'=66 171 | '['=67 172 | ']'=68 173 | ';'=69 174 | ','=70 175 | '.'=71 176 | '='=72 177 | '>'=73 178 | '<'=74 179 | '!'=75 180 | '~'=76 181 | '?'=77 182 | ':'=78 183 | '=='=79 184 | '<='=80 185 | '>='=81 186 | '!='=82 187 | '&&'=83 188 | '||'=84 189 | '++'=85 190 | '--'=86 191 | '+'=87 192 | '-'=88 193 | '*'=89 194 | '/'=90 195 | '&'=91 196 | '|'=92 197 | '^'=93 198 | '%'=94 199 | '+='=95 200 | '-='=96 201 | '*='=97 202 | '/='=98 203 | '&='=99 204 | '|='=100 205 | '^='=101 206 | '%='=102 207 | '<<='=103 208 | '>>='=104 209 | '>>>='=105 210 | '->'=106 211 | '::'=107 212 | '@'=108 213 | '...'=109 214 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/PrimitiveType.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public class PrimitiveType implements Type{ 4 | 5 | private String name = null; 6 | 7 | /** 8 | * 基础类型的罗列,奥 相当于一个类一个类型吗 9 | * @param name 10 | */ 11 | 12 | private PrimitiveType(String name){ 13 | this.name = name; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | @Override 22 | public Scope getEnclosingScope() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public String toString(){ 28 | return name; 29 | } 30 | 31 | public static PrimitiveType Integer = new PrimitiveType("Integer"); 32 | public static PrimitiveType Long = new PrimitiveType("Long"); 33 | public static PrimitiveType Float = new PrimitiveType("Float"); 34 | public static PrimitiveType Double = new PrimitiveType("Double"); 35 | public static PrimitiveType Boolean = new PrimitiveType("Boolean"); 36 | public static PrimitiveType Byte = new PrimitiveType("Byte"); 37 | public static PrimitiveType Char = new PrimitiveType("Char"); 38 | public static PrimitiveType Short = new PrimitiveType("Short"); 39 | public static PrimitiveType String = new PrimitiveType("String"); //增加String为基础类型 40 | public static PrimitiveType Null = new PrimitiveType("Null"); 41 | 42 | 43 | public static PrimitiveType getUpperType(Type type1, Type type2) { 44 | PrimitiveType type = null; 45 | if (type1 == PrimitiveType.String || type2 == PrimitiveType.String) { 46 | type = PrimitiveType.String; 47 | } else if (type1 == PrimitiveType.Double || type2 == PrimitiveType.Double) { 48 | type = PrimitiveType.Double; 49 | } else if (type1 == PrimitiveType.Float || type2 == PrimitiveType.Float) { 50 | type = PrimitiveType.Float; 51 | } else if (type1 == PrimitiveType.Long || type2 == PrimitiveType.Long) { 52 | type = PrimitiveType.Long; 53 | } else if (type1 == PrimitiveType.Integer || type2 == PrimitiveType.Integer) { 54 | type = PrimitiveType.Integer; 55 | } else if (type1 == PrimitiveType.Short || type2 == PrimitiveType.Short) { 56 | type = PrimitiveType.Short; 57 | } else { 58 | type = PrimitiveType.Byte; // TODO 以上这些规则有没有漏洞? 59 | } 60 | return type; 61 | } 62 | /** 63 | * 判断类型是否一致 64 | * @param type 目标类型 65 | * @return 66 | */ 67 | @Override 68 | public boolean isType(Type type) { 69 | return this == type; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/RefResolver.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.tree.ParseTreeWalker; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | /** 9 | * 消解主要有几个步骤 10 | * 返回值消解?函数类型消解,函数体消解 11 | * 最终消解的结果就是把对应的节点和类型对应起来 12 | * 这里我们主要有两个要做的,变量的消解,函数的消解 ,在调用函数的时候需要知道函数定义的地方 13 | */ 14 | public class RefResolver extends PlayScriptBaseListener{ 15 | 16 | private AnnotatedTree at; 17 | 18 | // 把本地变量添加到符号表,符号表其实就是一个存放变量名和对应变量地址的地方, 19 | ParseTreeWalker typeResolverWalker = new ParseTreeWalker(); 20 | TypeResolver localVariableEnter = null; 21 | 22 | public RefResolver(AnnotatedTree at){ 23 | this.at = at; 24 | this.localVariableEnter = new TypeResolver(at,true); 25 | } 26 | 27 | 28 | @Override 29 | public void enterVariableDeclarators(PlayScriptParser.VariableDeclaratorsContext ctx) { 30 | // 获取节点对应的作用域 31 | Scope scope = at.enclosingScopeOfNode(ctx); 32 | if (scope instanceof BlockScope || scope instanceof FunctionScope){ 33 | typeResolverWalker.walk(localVariableEnter, ctx); 34 | } 35 | } 36 | 37 | 38 | /** 39 | * 变量的消解主要是根据变量名选择找到对应的类型 40 | * 上一步相当于只将变量取出来了吧,比价variable只知道变量名 41 | * 但是现在我们需要把变量和对应的类型对照起来 42 | * 这里就是确认变量类型的 43 | * @param ctx 44 | */ 45 | @Override 46 | public void exitPrimary(PlayScriptParser.PrimaryContext ctx) { 47 | Scope scope = at.enclosingScopeOfNode(ctx); 48 | Type type = null; 49 | 50 | if (ctx.IDENTIFIER() != null){ 51 | String idName = ctx.IDENTIFIER().getText(); 52 | // 然后先从变量池中进行寻找 53 | Variable variable = at.lookupVariable(scope,idName); 54 | if (variable == null){ 55 | FunctionScope function = at.lookupFunction(scope, idName); 56 | if (function != null) { 57 | at.symbolOfNode.put(ctx, function); 58 | type = function; 59 | } 60 | }else { 61 | // 62 | at.symbolOfNode.put(ctx, variable); 63 | type = variable.type; 64 | } 65 | } 66 | else if (ctx.literal() != null) { 67 | type = at.typeOfNode.get(ctx.literal()); 68 | } 69 | //括号里的表达式 70 | else if (ctx.expression() != null) { 71 | type = at.typeOfNode.get(ctx.expression()); 72 | } 73 | at.typeOfNode.put(ctx,type); 74 | } 75 | 76 | 77 | /** 78 | * 获取函数参数 79 | * @param ctx 80 | * @return 81 | */ 82 | private List getParamTypes(PlayScriptParser.FunctionCallContext ctx){ 83 | List paramTypes = new LinkedList(); 84 | if (ctx.expressionList() != null) { 85 | for (PlayScriptParser.ExpressionContext exp : ctx.expressionList().expression()) { 86 | Type type = at.typeOfNode.get(exp); 87 | paramTypes.add(type); 88 | } 89 | } 90 | return paramTypes; 91 | } 92 | 93 | 94 | /** 95 | * 函数调用的变量消解... 96 | * @param ctx 97 | */ 98 | @Override 99 | public void exitFunctionCall(PlayScriptParser.FunctionCallContext ctx) { 100 | String idName = ctx.IDENTIFIER().getText(); 101 | List ParamTypes = getParamTypes(ctx); 102 | // 寻找对应的作用域 103 | Scope scope = at.enclosingScopeOfNode(ctx); 104 | FunctionScope functionScope = at.lookupFunction(scope,idName,ParamTypes); 105 | // 不为 null 说明找到了对应参数的函数,是从 symbol 中进行寻找的 106 | if (functionScope != null){ 107 | at.symbolOfNode.put(ctx,functionScope); 108 | at.typeOfNode.put(ctx,functionScope.returnType); 109 | } 110 | } 111 | 112 | 113 | 114 | //根据字面量来推断类型 115 | @Override 116 | public void exitLiteral(PlayScriptParser.LiteralContext ctx) { 117 | if (ctx.BOOL_LITERAL() != null) { 118 | at.typeOfNode.put(ctx, PrimitiveType.Boolean); 119 | } else if (ctx.CHAR_LITERAL() != null) { 120 | at.typeOfNode.put(ctx, PrimitiveType.Char); 121 | } else if (ctx.NULL_LITERAL() != null) { 122 | at.typeOfNode.put(ctx, PrimitiveType.Null); 123 | } else if (ctx.STRING_LITERAL() != null) { 124 | at.typeOfNode.put(ctx, PrimitiveType.String); 125 | } else if (ctx.integerLiteral() != null) { 126 | at.typeOfNode.put(ctx, PrimitiveType.Integer); 127 | } else if (ctx.floatLiteral() != null) { 128 | at.typeOfNode.put(ctx, PrimitiveType.Float); 129 | } 130 | } 131 | 132 | 133 | /** 134 | * 这个函数没加导致后面类型找不到, 应该是这里导致类型没对上 135 | * @param ctx 136 | */ 137 | @Override 138 | public void exitExpression(PlayScriptParser.ExpressionContext ctx) { 139 | Type type = null; 140 | 141 | //变量引用冒泡: 如果下级是一个变量,往上冒泡传递,以便在点符号表达式中使用 142 | //也包括This和Super的冒泡 143 | if (ctx.primary() != null) { 144 | Symbol symbol = at.symbolOfNode.get(ctx.primary()); 145 | at.symbolOfNode.put(ctx, symbol); 146 | } 147 | 148 | //类型推断和综合 149 | if (ctx.primary() != null) { 150 | type = at.typeOfNode.get(ctx.primary()); 151 | } else if (ctx.functionCall() != null) { 152 | type = at.typeOfNode.get(ctx.functionCall()); 153 | } else if (ctx.bop != null && ctx.expression().size() >= 2) { 154 | Type type1 = at.typeOfNode.get(ctx.expression(0)); 155 | Type type2 = at.typeOfNode.get(ctx.expression(1)); 156 | 157 | switch (ctx.bop.getType()) { 158 | case PlayScriptParser.ADD: 159 | if (type1 == PrimitiveType.String || type2 == PrimitiveType.String){ 160 | type = PrimitiveType.String; 161 | } 162 | else if (type1 instanceof PrimitiveType && type2 instanceof PrimitiveType){ 163 | //类型“向上”对齐,比如一个int和一个float,取float 164 | type = PrimitiveType.getUpperType(type1,type2); 165 | } 166 | break; 167 | case PlayScriptParser.SUB: 168 | case PlayScriptParser.MUL: 169 | case PlayScriptParser.DIV: 170 | if (type1 instanceof PrimitiveType && type2 instanceof PrimitiveType){ 171 | //类型“向上”对齐,比如一个int和一个float,取float 172 | type = PrimitiveType.getUpperType(type1,type2); 173 | } 174 | break; 175 | case PlayScriptParser.EQUAL: 176 | case PlayScriptParser.NOTEQUAL: 177 | case PlayScriptParser.LE: 178 | case PlayScriptParser.LT: 179 | case PlayScriptParser.GE: 180 | case PlayScriptParser.GT: 181 | case PlayScriptParser.AND: 182 | case PlayScriptParser.OR: 183 | case PlayScriptParser.BANG: 184 | type = PrimitiveType.Boolean; 185 | break; 186 | case PlayScriptParser.ASSIGN: 187 | case PlayScriptParser.ADD_ASSIGN: 188 | case PlayScriptParser.SUB_ASSIGN: 189 | case PlayScriptParser.MUL_ASSIGN: 190 | case PlayScriptParser.DIV_ASSIGN: 191 | case PlayScriptParser.AND_ASSIGN: 192 | case PlayScriptParser.OR_ASSIGN: 193 | case PlayScriptParser.XOR_ASSIGN: 194 | case PlayScriptParser.MOD_ASSIGN: 195 | case PlayScriptParser.LSHIFT_ASSIGN: 196 | case PlayScriptParser.RSHIFT_ASSIGN: 197 | case PlayScriptParser.URSHIFT_ASSIGN: 198 | type = type1; 199 | break; 200 | } 201 | } 202 | 203 | //类型冒泡 204 | at.typeOfNode.put(ctx, type); 205 | 206 | } 207 | 208 | @Override 209 | public void exitVariableInitializer(PlayScriptParser.VariableInitializerContext ctx) { 210 | if (ctx.expression() != null){ 211 | at.typeOfNode.put(ctx, at.typeOfNode.get(ctx.expression())); 212 | } 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/ReturnObject.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public class ReturnObject { 4 | Object returnValue = null; //真正的返回值。 5 | public ReturnObject(Object value){ 6 | this.returnValue = value; 7 | } 8 | 9 | //在打印时输出ReturnObject。 10 | @Override 11 | public String toString() { 12 | return "ReturnObject"; 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/Scope.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /** 7 | * 抽象类,命名空间 8 | * 命名空间中是需要存储变量的 9 | * 作用域其实就是块 10 | */ 11 | public abstract class Scope extends Symbol{ 12 | 13 | // 相当于符号表,所有变量都会存储在这里 14 | 15 | protected List symbols = new LinkedList<>(); // 块中存储这所有的符号 16 | 17 | /** 18 | * 向scope中添加符号,同时设置好该符号的enclosingScope 19 | * @param symbol 20 | */ 21 | protected void addSymbol(Symbol symbol){ 22 | symbols.add(symbol); 23 | symbol.enclosingScope = this; 24 | } 25 | 26 | protected Variable getVariable(String idName){ 27 | return getVariable(this,idName); 28 | } 29 | 30 | /** 31 | * 写代码别忘了目的,这里主要是为了从 scope 中找到对应名字的变量 32 | * @param scope 33 | * @param name 34 | * @return 35 | */ 36 | protected static Variable getVariable(Scope scope, String name){ 37 | for (Symbol symbol: scope.symbols){ 38 | if (name.equals(symbol.name) && symbol instanceof Variable ){ 39 | return (Variable) symbol; 40 | } 41 | } 42 | return null; 43 | } 44 | 45 | protected FunctionScope getFunction(String name, List paramTypes){ 46 | return getFunction(this,name,paramTypes); 47 | } 48 | 49 | /** 50 | * 从 symbols 中寻找 function 然后将形参和实参进行匹配如果匹配上了就返回 function 51 | * @param scope 52 | * @param name 53 | * @param paramTypes 54 | * @return 55 | */ 56 | protected static FunctionScope getFunction(Scope scope, String name,List paramTypes){ 57 | FunctionScope rtn = null; 58 | for (Symbol symbol: scope.symbols){ 59 | if (name.equals(symbol.name) && symbol instanceof FunctionScope ){ 60 | FunctionScope function = (FunctionScope) symbol; 61 | if (function.matchParameterTypes(paramTypes)){ 62 | rtn = function; 63 | break; 64 | } 65 | } 66 | } 67 | return rtn; 68 | } 69 | 70 | protected boolean containsSymbol(Symbol symbol){ 71 | return symbols.contains(symbol); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/StackFrame.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | 4 | public class StackFrame { 5 | //该frame所对应的scope 6 | Scope scope = null; 7 | 8 | /** 9 | * 放parent scope所对应的frame的指针,就叫parentFrame吧,便于提高查找效率。 10 | * 规则:如果是同一级函数调用,跟上一级的parentFrame相同; 11 | * 如果是下一级的函数调用或For、If等block,parentFrame是自己; 12 | * 如果是一个闭包(如何判断?),那么要带一个存放在堆里的环境。 13 | */ 14 | StackFrame parentFrame = null; 15 | 16 | PlayObject object = null; 17 | 18 | //实际存放变量的地方 19 | 20 | public StackFrame(FunctionObject object){ 21 | this.object = object; 22 | this.scope = object.function; 23 | } 24 | 25 | public StackFrame(BlockScope scope){ 26 | this.scope = scope; 27 | this.object = new PlayObject(); 28 | } 29 | 30 | protected boolean contains(Variable variable) { 31 | if(object != null && object.fields != null){ 32 | return object.fields.containsKey(variable); 33 | } 34 | return false; 35 | } 36 | 37 | 38 | @Override 39 | public String toString(){ 40 | String rtn = ""+scope; 41 | if (parentFrame != null){ 42 | rtn += " -> " + parentFrame; 43 | } 44 | return rtn; 45 | } 46 | 47 | 48 | 49 | 50 | 51 | } -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/Symbol.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | // 符号,块、类、字符串、函数都称之为符号 6 | public abstract class Symbol { 7 | 8 | protected String name = null; 9 | 10 | // 所属的作用域 11 | protected Scope enclosingScope = null; 12 | 13 | // 作用域所对应的 ast 上的节点 14 | protected ParserRuleContext ctx = null; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/Type.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | /** 4 | * 这里是要规定我们编写的语言所具有的类型 5 | * 编写的脚本语言比较简单,在我理解看来是结构 6 | * Class 7 | * Function 8 | * void 9 | * 10 | */ 11 | public interface Type { 12 | 13 | String getName(); 14 | 15 | Scope getEnclosingScope(); 16 | 17 | /** 18 | * 本类型是不是 is 目标类型。 也就是能否用来替换目标类型。 19 | * 以面向对象为例,子类 is 父类。子类可以出现在任何需要父类的地方。 20 | * @param type 目标类型 21 | * @return 22 | */ 23 | boolean isType(Type type); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/TypeAndScopeScanner.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | 4 | import org.antlr.v4.runtime.ParserRuleContext; 5 | 6 | import java.util.Stack; 7 | 8 | /** 9 | * 类似监听的感觉,可以在进入节点和退出节点的过程中做事情 10 | * 这里不是每个节点都会创建对应的作用域的 ,这里是我们自己处理的,例如我们的表达式 block function 这种 11 | * enterFunctionDeclaration ClassDeclaration Class 等等 12 | */ 13 | @SuppressWarnings("all") 14 | public class TypeAndScopeScanner extends PlayScriptBaseListener{ 15 | 16 | private AnnotatedTree at = null; 17 | // 临时变量 18 | private Stack scopeStack = new Stack<>(); 19 | 20 | public TypeAndScopeScanner(AnnotatedTree ast){ 21 | this.at = ast; 22 | } 23 | 24 | /** 25 | * 需要根据 node 取出作用域 26 | */ 27 | public void pushScope(ParserRuleContext ctx, Scope scope){ 28 | // node2Scope 属性将 ast 树上的节点和对应的作用域建立了联系 29 | at.node2Scope.put(ctx,scope); 30 | // 作用域对应的 ast 上的节点,暂时不知道干嘛用的 31 | scope.ctx = ctx; 32 | scopeStack.push(scope); // 压入当前堆栈中 33 | } 34 | 35 | /** 36 | * 扫描结束将 scopeStack 全部进行弹出 37 | */ 38 | public void popScope(){ 39 | scopeStack.pop(); 40 | } 41 | 42 | 43 | public Scope currentScope(){ 44 | if (scopeStack.size() > 0){ 45 | return scopeStack.peek(); 46 | }else { 47 | return null; 48 | } 49 | } 50 | /** 51 | * 程序刚开始的话就设置命名空间例如 package 52 | * 将当前的作用域与 AST 结合起来 53 | * 入口在这里,代表进入树结构,当进入 Prog 节点的时候可以触发 54 | * 同理离开的时候也会触发 exitProg 55 | * @param ctx 56 | */ 57 | @Override 58 | public void enterProg(PlayScriptParser.ProgContext ctx) { 59 | // 这里是这个属于的作用域的范围,这里赋值应该是 null ,创建命名空间 60 | NameSpace scope = new NameSpace("", currentScope(), ctx); // 所属作用域 61 | at.nameSpace = scope; // 设置树的命名结构 62 | pushScope(ctx,scope); // 压入 63 | } 64 | 65 | /** 66 | * 扫描结束退出 67 | * 退出 Prog 节点 68 | * @param ctx 69 | */ 70 | @Override 71 | public void exitProg(PlayScriptParser.ProgContext ctx) { 72 | popScope(); 73 | } 74 | 75 | /** 76 | * 针对 Block Function Class 依次进行处理 77 | */ 78 | @Override 79 | public void enterBlock(PlayScriptParser.BlockContext ctx) { 80 | // 如果父类不是函数体的话就创建,不加这个的话要创建两个 81 | if (!(ctx.parent instanceof PlayScriptParser.FunctionBodyContext)){ 82 | BlockScope scope = new BlockScope(); 83 | // 不懂这个添加的意义 84 | // currentScope().addSymbol(scope); // ? 为什么要这么做,在当前作用域下添加作用域?添加 85 | pushScope(ctx,scope); 86 | } 87 | } 88 | 89 | @Override 90 | public void exitBlock(PlayScriptParser.BlockContext ctx) { 91 | if (!(ctx.parent instanceof PlayScriptParser.FunctionBodyContext)) { 92 | popScope(); 93 | } 94 | } 95 | 96 | /** 97 | * 进入 function 98 | * @param ctx 99 | */ 100 | @Override 101 | public void enterFunctionDeclaration(PlayScriptParser.FunctionDeclarationContext ctx) { 102 | String name = ctx.IDENTIFIER().getText(); 103 | FunctionScope functionScope = new FunctionScope(name,currentScope(),ctx); 104 | at.types.add(functionScope); 105 | // ? 106 | currentScope().addSymbol(functionScope); 107 | pushScope(ctx,functionScope); 108 | } 109 | 110 | /** 111 | * 离开 function 112 | * @param ctx 113 | */ 114 | @Override 115 | public void exitFunctionDeclaration(PlayScriptParser.FunctionDeclarationContext ctx) { 116 | popScope(); 117 | } 118 | 119 | 120 | 121 | /** 122 | * 类待会在做有点小麻烦先把 func 做好 123 | * 进入 class 创建对应的 class 作用域 然后压到栈中 124 | * @param ctx 125 | */ 126 | // @Override 127 | // public void exitClassDeclaration(PlayScriptParser.ClassDeclarationContext ctx) { 128 | // popScope(); 129 | // } 130 | // 131 | // /** 132 | // * 离开 class 133 | // * @param ctx 134 | // */ 135 | // @Override 136 | // public void enterClassDeclaration(PlayScriptParser.ClassDeclarationContext ctx) { 137 | // String name = ctx.IDENTIFIER().getText(); 138 | // ClassScope classScope = new ClassScope(name,ctx); 139 | // 140 | // /** 141 | // * 先不管下面这些代码 尼玛创建好作用域就应该直接压入到栈 142 | // * at.types.add(theClass); 143 | // * 144 | // * if (at.lookupClass(currentScope(), idName) != null) { 145 | // * at.log("duplicate class name:" + idName, ctx); // 只是报警,但仍然继续解析 146 | // * } 147 | // */ 148 | // // 149 | // pushScope(ctx,classScope); 150 | // } 151 | 152 | 153 | 154 | // 这个应该是处理 for 语句的 155 | // /** 156 | // * 进入代码片段 157 | // * @param ctx 158 | // */ 159 | // @Override 160 | // public void enterStatement(PlayScriptParser.StatementContext ctx) { 161 | // super.enterStatement(ctx); 162 | // } 163 | // 164 | // /** 165 | // * 离开代码片段 166 | // * @param ctx 167 | // */ 168 | // @Override 169 | // public void exitStatement(PlayScriptParser.StatementContext ctx) { 170 | // super.exitStatement(ctx); 171 | // } 172 | } 173 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/TypeResolver.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | /** 4 | * 先把函数和变量做出来,现在加入类的话有可能会容易乱 5 | * 主要是对变量和函数的一个处理 6 | */ 7 | public class TypeResolver extends PlayScriptBaseListener{ 8 | 9 | private AnnotatedTree at = null; 10 | // 是否需要将变量添加到符号表 11 | private boolean enterLocalVariable = false; 12 | 13 | 14 | public TypeResolver(AnnotatedTree at) { 15 | this.at = at; 16 | } 17 | 18 | public TypeResolver(AnnotatedTree at,boolean enterLocalVariable){ 19 | this.at = at; 20 | this.enterLocalVariable = enterLocalVariable; 21 | } 22 | 23 | 24 | // int b = 10 离开变量定义片段 25 | @Override 26 | public void exitVariableDeclarators(PlayScriptParser.VariableDeclaratorsContext ctx) { 27 | Scope scope = at.enclosingScopeOfNode(ctx); 28 | 29 | //Aaaaaaaaaaayou同学请看这里。 30 | if (enterLocalVariable ){ 31 | // 设置变量类型 32 | Type type = (Type) at.typeOfNode.get(ctx.typeType()); 33 | 34 | for (PlayScriptParser.VariableDeclaratorContext child : ctx.variableDeclarator()) { 35 | Variable variable = (Variable) at.symbolOfNode.get(child.variableDeclaratorId()); 36 | variable.type = type; 37 | } 38 | } 39 | } 40 | 41 | 42 | /** 43 | * 对变量进行解析 44 | * @param ctx 45 | */ 46 | @Override 47 | public void exitPrimitiveType(PlayScriptParser.PrimitiveTypeContext ctx) { 48 | Type type = null; 49 | 50 | if (ctx.BOOLEAN() != null) { 51 | type = PrimitiveType.Boolean; 52 | } else if (ctx.INT() != null) { 53 | type = PrimitiveType.Integer; 54 | } else if (ctx.LONG() != null) { 55 | type = PrimitiveType.Long; 56 | } else if (ctx.FLOAT() != null) { 57 | type = PrimitiveType.Float; 58 | } else if (ctx.DOUBLE() != null) { 59 | type = PrimitiveType.Double; 60 | } else if (ctx.BYTE() != null) { 61 | type = PrimitiveType.Byte; 62 | } else if (ctx.SHORT() != null) { 63 | type = PrimitiveType.Short; 64 | } else if (ctx.CHAR() != null) { 65 | type = PrimitiveType.Char; 66 | }else if (ctx.STRING() != null) { 67 | type = PrimitiveType.String; 68 | } 69 | 70 | at.typeOfNode.put(ctx,type); 71 | } 72 | 73 | /** 74 | * 设置函数返回值 75 | */ 76 | @Override 77 | public void exitFunctionDeclaration(PlayScriptParser.FunctionDeclarationContext ctx) { 78 | FunctionScope function = (FunctionScope) at.node2Scope.get(ctx); 79 | 80 | // 对作用域进行赋值,将返回值添加到函数作用域中 81 | if (ctx.typeTypeOrVoid() != null){ 82 | function.returnType = at.typeOfNode.get(ctx.typeTypeOrVoid()); 83 | } 84 | 85 | /** 86 | * 函数查重 87 | */ 88 | 89 | 90 | } 91 | 92 | /** 93 | * 这里就是把变量名都放到了 symbolOfNode 94 | * @param ctx 95 | */ 96 | @Override 97 | public void enterVariableDeclaratorId(PlayScriptParser.VariableDeclaratorIdContext ctx) { 98 | String idName = ctx.IDENTIFIER().getText(); 99 | // 获取上一个节点的作用域,寻找当前变量应该在的作用域 100 | // 每个变量都需要知道自己属于哪个作用域 101 | Scope scope = at.enclosingScopeOfNode(ctx); 102 | 103 | /** 104 | * 如果当前节点的父节点是 FormalParameterContext 那么说明当前节点的变量是我们所需要的 105 | */ 106 | if (ctx.parent instanceof PlayScriptParser.FormalParameterContext || enterLocalVariable){ 107 | // 我们就需要去创建一个参数变量 108 | Variable variable = new Variable(idName,scope,ctx); 109 | // 暂时还不知道这个 addSymbol 是做什么的 110 | scope.addSymbol(variable); 111 | // 这一步才是最关键的就是把变量放到作用域里 112 | at.symbolOfNode.put(ctx,variable); 113 | } 114 | } 115 | 116 | 117 | /** 118 | * 主要解析条件中的 int a 部分 119 | * func void demo(int a){ 120 | * 121 | * } 122 | * 有点理解了,每个作用域都通过一个类对象来存储,将一些信息都添加到类对象中 123 | */ 124 | @Override 125 | public void exitFormalParameter(PlayScriptParser.FormalParameterContext ctx) { 126 | Type type = at.typeOfNode.get(ctx.typeType()); 127 | // 根据变量名去寻找 128 | Variable variable = (Variable) at.symbolOfNode.get(ctx.variableDeclaratorId()); 129 | variable.type = type; 130 | 131 | // 寻找当前节点的上一个节点的作用域,说白了就是看当前这个是在哪个作用域下面的 132 | Scope scope = at.enclosingScopeOfNode(ctx); 133 | // 如果是在 函数作用域下的话就添加 134 | if (scope instanceof FunctionScope){ 135 | ((FunctionScope) scope).parameters.add(variable); 136 | } 137 | } 138 | 139 | 140 | /** 141 | * exit 相当于就是当前节点已经遍历完了,所以这时已经可以知道这个树节点是否是void了 142 | * @param ctx 143 | */ 144 | @Override 145 | public void exitTypeTypeOrVoid(PlayScriptParser.TypeTypeOrVoidContext ctx) { 146 | if (ctx.VOID() != null){ 147 | at.typeOfNode.put(ctx,VoidType.instance()); 148 | // 如果不为 null 那么就根据原来的进行获取 149 | }else if (ctx.typeType() != null){ 150 | at.typeOfNode.put(ctx,at.typeOfNode.get(ctx.typeType())); 151 | } 152 | } 153 | 154 | 155 | // 为什么要把下级的属性注册到本级? 有点不知道所以然 156 | @Override 157 | public void exitTypeType(PlayScriptParser.TypeTypeContext ctx) { 158 | // 冒泡,将下级的属性标注在本级 159 | if (ctx.classOrInterfaceType() != null) { 160 | Type type = (Type) at.typeOfNode.get(ctx.classOrInterfaceType()); 161 | at.typeOfNode.put(ctx, type); 162 | } else if (ctx.functionType() != null) { 163 | Type type = (Type) at.typeOfNode.get(ctx.functionType()); 164 | at.typeOfNode.put(ctx, type); 165 | } else if (ctx.primitiveType() != null) { 166 | Type type = (Type) at.typeOfNode.get(ctx.primitiveType()); 167 | at.typeOfNode.put(ctx, type); 168 | } 169 | 170 | } 171 | 172 | 173 | 174 | 175 | } 176 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/Variable.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext; 4 | 5 | /** 6 | * int num = 111; 7 | */ 8 | public class Variable extends Symbol { 9 | 10 | protected Type type; 11 | 12 | /** 13 | * 缺省值 14 | */ 15 | protected Object defaultValue = null; 16 | 17 | protected Variable(String name, Scope enclosingScope, ParserRuleContext ctx) { 18 | this.name = name; 19 | this.enclosingScope = enclosingScope; 20 | this.ctx = ctx; 21 | } 22 | 23 | @Override 24 | public String toString(){ 25 | return "Variable " + name + " -> "+ type; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/playscript/VoidType.java: -------------------------------------------------------------------------------- 1 | package playscript; 2 | 3 | public class VoidType implements Type{ 4 | 5 | private static VoidType voidType = new VoidType(); 6 | 7 | public static VoidType instance(){ 8 | return voidType; 9 | } 10 | public VoidType(){ 11 | 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "void"; 17 | } 18 | 19 | /** 20 | * 基础类型不需要有所属作用域 21 | * @return 22 | */ 23 | @Override 24 | public Scope getEnclosingScope() { 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean isType(Type type) { 30 | return this==type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/java/script/MyScript.java: -------------------------------------------------------------------------------- 1 | package script; 2 | 3 | import calc.AstNode; 4 | import calc.AstNodeType; 5 | import lexer.*; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.InputStreamReader; 9 | import java.util.HashMap; 10 | 11 | 12 | public class MyScript { 13 | 14 | public static void main(String[] args) throws Exception{ 15 | System.out.println("Simple script language!"); 16 | SimpleParser parser = new SimpleParser(); 17 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 18 | 19 | StringBuilder scriptText = new StringBuilder(); 20 | System.out.print("\n>"); //提示符 21 | 22 | while (true) { 23 | try { 24 | String line = reader.readLine().trim(); 25 | if (line.equals("exit();")) { 26 | System.out.println("good bye!"); 27 | break; 28 | } 29 | scriptText.append(line).append("\n"); 30 | if (line.endsWith(";")) { 31 | // 主要的两行 32 | AstNode tree = parser.parse(scriptText.toString()); 33 | 34 | int result = parser.evaluate(tree, ""); 35 | 36 | System.out.println(result); 37 | 38 | System.out.print("\n>"); //提示符 39 | 40 | scriptText = new StringBuilder(); 41 | } 42 | 43 | } catch (Exception e) { 44 | e.printStackTrace(); 45 | System.out.println(e.getLocalizedMessage()); 46 | System.out.print("\n>"); //提示符 47 | scriptText = new StringBuilder(); 48 | } 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /JavaCompiler/src/main/resources/note: -------------------------------------------------------------------------------- 1 | 扩展巴科斯范式 2 | 3 | intDeclaration : 'int' Id ('=' additiveExpression)? ';'; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LearnCompiler 2 | 编译原理学习代码仓库 3 | 编译原理之美学习笔记&代码,课程为:https://time.geekbang.org/column/article/118378 4 | 5 | 因为不会 Go 语言,所以顺便学习的时候把 go 也写写 6 | 7 | 8 | 9 | 极客时间后面部分跨度也太大了吧,直接就是一个完整项目,人傻了... 10 | 11 | (半抄半看的弄了弄,把函数部分抽离出来了,然后语义检查也一并没做,弄的血压都高了 12 | 13 | --------------------------------------------------------------------------------