上一篇我们使用ANTLR来描述了Jerry语言的基本语法,并通过ANTLRWorks来实验该语法对样本代码生 成的解析树。但如同上一篇最后所述,这样得到的解析树中有太多对后续处理来说无用的冗余信息。我们 需要消除这些冗余信息,得到抽象语法树(AST)。
本篇将以之前做的语法为基础,通过添加树重写规则来将ANTLR默认生成的解析树简化整理为抽象语法 树。
本文涉及的源码和运行时库打包在附件里了,懒得复制粘贴的话就直接下载附件的版本,用 ANTLRWorks来查看和编辑语法文件吧~
修改后的语法文件如下:
Jerry.g(ANTLR 3.1语法文件,以Java为生成目标语言)
Java代码
1.grammar Jerry;
2.
3.options {
4. language = Java;
5. output = AST;
6. ASTLabelType = CommonTree;
7.}
8.
9.tokens {
10. // imaginary tokens
11. VAR_DECL;
12. SIMPLE_TYPE;
13. ARRAY_TYPE;
14. ARRAY_LITERAL;
15. SIMPLE_VAR_ACCESS;
16. ARRAY_VAR_ACCESS;
17. UNARY_MINUS;
18. BLOCK;
19. EXPR_STMT;
20.}
21.
22.// parser rules
23.
24.program : statementList EOF!
25. {
26. System.out.println(
27. null == $statementList.tree ?
28. "null" :
29. $statementList.tree.toStringTree());
30. }
31. ;
32.
33.statementList
34. : statement*
35. ;
36.
37.statement
38. : expressionStatement
39. | variableDeclaration
40. | blockStatement
41. | ifStatement
42. | whileStatement
43. | breakStatement
44. | readStatement
45. | writeStatement
46. ;
47.
48.expressionStatement
49. : expression SEMICOLON
50. -> ^( EXPR_STMT expression )
51. ;
52.
53.variableDeclaration
54. : typeSpecifier
55. ( Identifier
56. ( -> ^( VAR_DECL ^( SIMPLE_TYPE typeSpecifier ) Identifier )
57. | ( LBRACK Integer RBRACK )+
58. - > ^( VAR_DECL ^( ARRAY_TYPE typeSpecifier Integer+ ) Identifier )
59. | EQ expression
60. -> ^( VAR_DECL ^( SIMPLE_TYPE typeSpecifier ) Identifier expression )
61. | ( LBRACK Integer RBRACK )+ EQ arrayLiteral
62. -> ^( VAR_DECL ^( ARRAY_TYPE typeSpecifier Integer+ ) Identifier arrayLiteral )
63. )
64. )
65. ( COMMA id=Identifier
66. ( -> $variableDeclaration ^( VAR_DECL ^( SIMPLE_TYPE typeSpecifier ) $id )
67. | ( LBRACK dim1+=Integer RBRACK )+
68. -> $variableDeclaration ^( VAR_DECL ^( ARRAY_TYPE typeSpecifier $dim1+ ) $id )
69. | EQ exp=expression
70. -> $variableDeclaration ^( VAR_DECL ^( SIMPLE_TYPE typeSpecifier ) $id $exp )
71. | ( LBRACK dim2+=Integer RBRACK )+ EQ al=arrayLiteral
72. -> $variableDeclaration ^( VAR_DECL ^( ARRAY_TYPE typeSpecifier $dim2+ ) $id $al )
73. )
74. { if (null != $dim1) $dim1.clear(); if (null != $dim2) $dim2.clear(); }
75. )*
76. SEMICOLON
77. ;
78.
79.typeSpecifier
80. : INT | REAL
81. ;
82.
83.arrayLiteral
84. : LBRACE
85. arrayLiteralElement ( COMMA arrayLiteralElement )*
86. RBRACE
87. -> ^( ARRAY_LITERAL arrayLiteralElement+ )
88. ;
89.
90.arrayLiteralElement
91. : expression
92. | arrayLiteral
93. ;
94.
95.blockStatement
96. : LBRACE statementList RBRACE
97. -> ^( BLOCK statementList )
98. ;
99.
100.ifStatement
101. : IF^ LPAREN! expression RPAREN! statement ( ELSE! statement )?
102. ;
103.
104.whileStatement
105. : WHILE^ LPAREN! expression RPAREN! statement
106. ;
107.
108.breakStatement
109. : BREAK SEMICOLON!
110. ;
111.
112.readStatement
113. : READ^ variableAccess SEMICOLON!
114. ;
115.
116.writeStatement
117. : WRITE^ expression SEMICOLON!
118. ;
119.
120.variableAccess
121. : Identifier
122. ( -> ^( SIMPLE_VAR_ACCESS Identifier )
123. | ( LBRACK Integer RBRACK ) +
124. -> ^( ARRAY_VAR_ACCESS Identifier Integer+ )
125. )
126. ;
127.
128.expression
129. : assignmentExpression
130. | logicalOrExpression
131. ;
132.
133.assignmentExpression
134. : variableAccess EQ^ expression
135. ;
136.
137.logicalOrExpression
138. : logicalAndExpression ( OROR^ logicalAndExpression )*
139. ;
140.
141.logicalAndExpression
142. : relationalExpression ( ANDAND^ relationalExpression )*
143. ;
144.
145.relationalExpression
146. : additiveExpression ( relationalOperator^ additiveExpression )?
147. | BANG^ relationalExpression
148. ;
149.
150.additiveExpression
151. : multiplicativeExpression ( additiveOperator^ multiplicativeExpression )*
152. ;
153.
154.multiplicativeExpression
155. : primaryExpression ( multiplicativeOperator^ primaryExpression )*
156. ;
157.
158.primaryExpression
159. : variableAccess
160. | Integer
161. | RealNumber
162. | LPAREN! expression RPAREN!
163. | MINUS primaryExpression
164. -> ^( UNARY_MINUS primaryExpression )
165. ;
166.
167.relationalOperator
168. : LT | GT | EQEQ | LE | GE | NE
169. ;
170.
171.additiveOperator
172. : PLUS | MINUS
173. ;
174.
175.multiplicativeOperator
176. : MUL | DIV
177. ;
178.
179.// lexer rules
180.
181.LPAREN : '('
182. ;
183.
184.RPAREN : ')'
185. ;
186.
187.LBRACK : '['
188. ;
189.
190.RBRACK : ']'
191. ;
192.
193.LBRACE : '{'
194. ;
195.
196.RBRACE : '}'
197. ;
198.
199.COMMA : ','
200. ;
201.
202.SEMICOLON
203. : ';'
204. ;
205.
206.PLUS : '+'
207. ;
208.
209.MINUS : '-'
210. ;
211.
212.MUL : '*'
213. ;
214.
215.DIV : '/'
216. ;
217.
218.EQEQ : '=='
219. ;
220.
221.NE : '!='
222. ;
223.
224.LT : '<'
225. ;
226.
227.LE : '<='
228. ;
229.
230.GT : '>'
231. ;
232.
233.GE : '>='
234. ;
235.
236.BANG : '!'
237. ;
238.
239.ANDAND : '&&'
240. ;
241.
242.OROR : '||'
243. ;
244.
245.EQ : '='
246. ;
247.
248.IF : 'if'
249. ;
250.
251.ELSE : 'else'
252. ;
253.
254.WHILE : 'while'
255. ;
256.
257.BREAK : 'break'
258. ;
259.
260.READ : 'read'
261. ;
262.
263.WRITE : 'write'
264. ;
265.
266.INT : 'int'
267. ;
268.
269.REAL : 'real'
270. ;
271.
272.Identifier
273. : LetterOrUnderscore ( LetterOrUnderscore | Digit )*
274. ;
275.
276.Integer : Digit+
277. ;
278.
279.RealNumber
280. : Digit+ '.' Digit+
281. ;
282.
283.fragment
284.Digit : '0'..'9'
285. ;
286.
287.fragment
288.LetterOrUnderscore
289. : Letter | '_'
290. ;
291.
292.fragment
293.Letter : ( 'a'..'z' | 'A'..'Z' )
294. ;
295.
296.WS : ( ' ' | '\t' | '\r' | '\n' )+ { $channel = HIDDEN; }
297. ;
298.
299.Comment
300. : '/*' ( options { greedy = false; } : . )* '*/' { $channel = HIDDEN; }
301. ;
302.
303.LineComment
304. : '//' ~ ('\n'|'\r')* '\r'? '\n' { $channel = HIDDEN; }
305. ;