文法定义:

词法定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.<加法运算符> ::= +|-

2.<乘法运算符> ::= *|/

3.<关系运算符> ::= <|<=|>|>=|!=|==

4.<逻辑运算符> ::= && | '|| ' | !

5.<字母> ::= _|a|...|z|A|...|Z

6.<非零数字> ::= 1|...|9

7.<数字> ::= 0|<非零数字>

8.<无符号整数> ::= <非零数字>{<数字>}|0

9.<整数> ::= [+|-]<无符号整数>

10.<字符> ::= '<加法运算符>'|'<乘法运算符>'|'<字母>'|'<数字>'

11.<字符串> ::= "{十进制编码为32,33,35-126的ASCII字符}"

12.<标识符> ::= <字母>{<字母>|<数字>}

语法定义

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
13.<程序> ::= [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>

这里有很多的公因子,但是为了文法简单,好理解;就在程序上实现,没有提取

14.<常量说明> ::= const<常量定义>;{ const<常量定义>;}

15.<常量定义> ::= int<标识符>=<整数>{,<标识符>=<整数>}| char<标识符>=<字符>{,<标识符>=<字符>}

16.<变量说明> ::= <变量定义>;{<变量定义>;}

17.<变量定义> ::= <类型标识符><标识符>[‘[’<无符号整数>‘]’] {,<标识符>[‘[’<无符号整数>‘]’]}

18.<类型标识符> ::= int | char

19.<有返回值函数定义> ::= <声明头部>‘(’<参数表>‘)’ ‘{’<复合语句>‘}’

20.<声明头部> ::= int<标识符> | char<标识符>

21.<无返回值函数定义> ::= void<标识符>‘(’<参数表>‘)’ ‘{’<复合语句>‘}’

22.<参数表> ::= <类型标识符><标识符>{,<类型标识符><标识符>}| <空>

>>>>>>>> 空语句:这里也有一处空语句,但follow集只有')'一个元素

23.<复合语句> ::= [<常量说明>][<变量说明>]<语句列>

24.<主函数> ::= void main ‘(’ ‘)’ ‘{’<复合语句>‘}’

25.<语句列> ::= {<语句>}

语句列是若干(包括0)个连续语句的集合
>>>>>>>> 空语句:也就是说,可以光有定义,但是其他语句一个没有,什么都不做,follow集只有'}',

26.<语句> ::= <条件语句>|<循环语句>|‘{’<语句列>‘}’|<有返回值的函数调用语句>;|<无返回值的函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<空>;|<返回语句>;

!!!!!! 注意:这里的 “<空>;” 和 空语句是不一样的,只有个分号

27.<赋值语句> ::= <标识符>[‘[’<算术表达式>‘]’]=<算术表达式>

28.<条件语句> ::= if ‘(’<布尔表达式>‘)’<语句>[else<语句>]

29.<循环语句> ::= while ‘(’<布尔表达式>‘)’<语句>| for‘(’<赋值语句>;<布尔表达式>;<赋值语句>‘)’<语句>

for循环中的三个表达式:初始化表达式、循环变量测试表达式、循环变量修正表达式

30.<有返回值的函数调用语句> ::= <标识符>‘(’<值参数表>‘)’

31.<无返回值的函数调用语句> ::= <标识符>‘(’<值参数表>‘)’

32.<值参数表> ::= <算术表达式>{,<算术表达式>}|<空>

>>>>>>>> 空语句:这里也有一处空语句,但follow集只有')'一个元素

33.<读语句> ::= scanf ‘(’<标识符>{,<标识符>}‘)’

34.<写语句> ::= printf ‘(’<字符串>,<算术表达式>‘)’| printf ‘(’<字符串>‘)’| printf ‘(’<算术表达式>‘)’

定义写语句是以printf为起始的,后接圆括号括起来的字符串或表达式或者两者都有,若两者都存在,则字符串在先,以逗号隔开。

35.<返回语句> ::= return[‘(’<算术表达式>‘)’]


36.<算术表达式> ::= [+|-]<项>{<加法运算符><项>}

37.<项> ::= <因子>{<乘法运算符><因子>}

38.<因子> ::= <标识符>|<标识符>‘[’<算术表达式>‘]’|<无符号整数>|<字符>|<有返回值函数调用语句>|‘(’<算术表达式>‘)’

39.<布尔表达式> ::= <布尔项> { ‘||’ <布尔项> }

40.<布尔项> ::= <布因子>{ && <布因子> }

41.<布因子> ::= false | true | ! <布因子> | ‘(‘<布尔表达式>’)’ | <条件因子> [<条件运算符> <条件因子>]

事实上,这里的 ! 的优先级是比关系运算符低的

42.<条件因子> ::= <标识符>[‘[’<算术表达式>‘]’]| <无符号整数> | <字符> | <有返回值函数调用语句>

事实上,这里<条件因子>不像(算术)表达式中一样,这里不支持嵌套,不支持’()’,因为布尔表达式设计起来符合嵌套,主要是括号不好处理;暂时这么设计,然后如果真要表达式的话,可以在前面先计算赋值给一个变量