";
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 |
--------------------------------------------------------------------------------