一个简单的语言的语法(二):ANTLR的重写规则
时间:2011-10-07 javaeye RednaxelaFX
上一篇我们使用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
|