语法分析
在本篇文章中,我们将采用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():{} |