语法分析
在本篇文章中,我们将采用javacc来实现编译器的语法分析功能。语法中一定会有表示“需要解析的对象整体”的符号。在Cb中,编译的单位,即“单个的文件”是需要分析的对象,所以需要用相应的语法规则对其进行表示。
Cb中表示1个文件整体的非终端符号被成为compilation_unit,它的规则如下所示:
1 | compilation_unit():{} |
语法的单位
一般编程语言的语法单位有下面这些:
- 定义:指变量定义、函数定义或类定义等
- 声明
- 语句:函数或方法的定义的本体中包含有语句
- 表达式: 表达式是比语句小、具有值的语法单位
- 项:项这一语法单位是表达式中构成二元运算的一方,也就是仅由一元运算符构成的语法。
接下来我们将详细列出各种定义,声明,语句,表达式及项的对应的javacc描述。
import声明的语法
1 | import_stmts():{} |
各类定义的语法
1 | top_defs():{} |
语句的定义
1 | stmts():{} |
表达式分析
表达式的结构是有层次的,原因在于表达式中所使用的运算符存在优先级。优先级底的运算符靠近根节点,优先级高的运算符位于下层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
85expr():{}
{
LOOKAHEAD(term() "=")
term() "=" expr()
| LOOKAHEAD(term() opassign_op())
term() opassign_op() expr()
| expr10()
}
opassign_op():{}
{
(
"+="
| "-="
| "*="
| "/="
| "%="
| "&="
| "|="
| "^="
| "<<="
| ">>="
)
}
expr10():{}
{
expr9() ["?" expr() ":" expr10() ]
}
expr9():{}
{
expr8()("||"expr8())*
}
expr8():{}
{
expr7()("&&"expr7())*
}
expr7():{}
{
expr6()(
">" expr6()
|"<" expr6()
| ">=" expr6()
| "<=" expr6()
| "==" expr6()
| "!=" expr6()
)*
}
expr6():{}
{
expr5()("|" expr5())*
}
expr4():{}
{
expr3()("&"expr3())*
}
expr3():{}
{
expr2()(
">>"expr2()
| "<<" expr2()
)*
}
expr2():{}
{
expr1()(
"+"expr1()
|"-"expr1()
)*
}
expr1():{}
{
term()(
"*"term()
|"/"term()
|"+"term()
|"-"term()
)*
}
项的分析
1 | term():{} |