终结符说明:
数字    NUMBER
标识符  INDENTIFI
(      LP
)       RP
{       LC
}       RC
功能需求:
args_list 是函数的参数列表,
实际用途中,可能有多个参数, 可能有1个参数,可能没有参数。
为了兼容上述情景,设计 args_list 的语法为下:
1:空,
2:单字符,
3:左边为1与2组合,右边单字符.
BNF 描述如下:1
2
3
4args_list       :
                | INDENTIFI
                | args_list INDENTIFI
                ;
问题描述:
YACC 解释时  有冲突!
YACC 文件内容: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
37chunli@ubuntu:~/lab/yacc/$ cat example.y
%{
#include <stdio.h>
%}
%token NUMBER INDENTIFI LP RP LC RC
%%
function_args   :INDENTIFI LP args_list RP
                {
                    // 函数的名形式, 形如下:
                    // foo(int a, double b)
                    // foo(const char *str)
                    // foo(float)
                    // foo()
                }
                ;
args_list       :
                {
                    // 允许参数匹配空参数
                }
                | INDENTIFI
                {
                    // 形如 int
                }
                | args_list INDENTIFI
                {
                    // ... char
                }
                ;
%%
chunli@ubuntu:~/lab/yacc/$
YACC 分析结果:
哦嚯?!  YACC 有警告 …
| 1 |  | 
YACC  异常分析
y.output 是 yacc 输出的调试信息文件
| 1 |  | 
分析:
$accept         代表当前输入的标记
$default        代表 向前看时下一个标记
$end            代表结束标记
可以看到 y.output文件头直接报告 状态3 存在 1 个 移进/规约 的 冲突
来看看 是什么地方导致的 shift/reduce conflicts ?
在 State 3 中
当遇到 INDENTIFI 标记,规约为 规则2(args_list)
当遇到 无论什么  标记,规约为 规则2(args_list)
再看看看 rule 2:
2 args_list: %empty
当遇到 INDENTIFI时, 要么向上规约为args_list, 要么向下移进。
那么到底是要 shift 还是 reduce呢 ?
改正之后: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
31chunli@ubuntu:~/lab/yacc/$ cat example.y
%{
#include <stdio.h>
%}
%token NUMBER INDENTIFI LP RP LC RC
%%
function_args   :INDENTIFI LP args_list RP
                {
                    // 函数的名形式, 形如下:
                    // foo(int a, double b)
                    // foo(const char *str)
                    // foo(float)
                    // foo()
                }
                ;
args_list       :
                {
                    // 允许参数匹配空参数
                }
                | args_list INDENTIFI
                {
                    // ... char
                }
                ;
%%
chunli@ubuntu:~/lab/yacc/$ yacc -v example.y
chunli@ubuntu:~/lab/yacc/$
将 args_list中的规则删除一部分, 可以达到 上述功能需求。
改正之后的 args_list1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20args_list       :
                {
                    // 允许参数匹配空参数
                    // foo 为 function_的名字
                    // 匹配 foo()
                }
                | args_list INDENTIFI
                {
                    // foo 为 function_的名字
                    // 匹配 foo(int)
                    // 匹配 foo(int a)
                    // 匹配 foo(const int a)
                }
                ;
1. 支持参数为空,如 foo()
2. 支持参数1个, 如 foo(int)
2. 支持参数2个, 如 foo(int a)
2. 支持参数3个, 如 foo(const int a)
