s :type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F {check=1;}
|fname OPEN_P call CLOSE_P SEMI_COLON {if(npd != npc) printf("No of parameters don't matchn");}
|type vars SEMI_COLON
|VAR EQL NUM SEMI_COLON
|RETURN VAR SEMI_COLON NEW_LINE
我得到如下解析输出文件
Terminals unused in grammar
KEY_WORD
OPEN_S
CLOSE_S
STAR
State 18 conflicts: 1 shift/reduce
State 19 conflicts: 1 shift/reduce
Grammar
0 $accept: s $end
1 s: type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F
2 | fname OPEN_P call CLOSE_P SEMI_COLON
3 | type vars SEMI_COLON
4 | VAR EQL NUM SEMI_COLON
5 | RETURN VAR SEMI_COLON NEW_LINE
6 | OPEN_F
7 | CLOSE_F
8 vars: VAR
9 | VAR COMMA vars
10 fname: VAR
11 type: VTYPE
12 | type pointer
13 | type ar
14 ar: '[' ']'
15 | ar '[' ']'
16 pointer: '*'
17 | pointer '*'
18 param: type VAR
19 | type VAR COMMA param
20 call: VAR
21 | VAR COMMA call
Terminals, with rules where they appear
$end (0) 0
'*' (42) 16 17
'[' (91) 14 15
']' (93) 14 15
error (256)
VAR (258) 4 5 8 9 10 18 19 20 21
VTYPE (259) 11
NUM (260) 4
RETURN (261) 5
KEY_WORD (262)
EQL (263) 4
SEMI_COLON (264) 2 3 4 5
OPEN_P (265) 1 2
CLOSE_P (266) 1 2
OPEN_F (267) 1 6
CLOSE_F (268) 1 7
OPEN_S (269)
CLOSE_S (270)
COMMA (271) 9 19 21
STAR (272)
NEW_LINE (273) 1 5
Nonterminals, with rules where they appear
$accept (22)
on left: 0
s (23)
on left: 1 2 3 4 5 6 7, on right: 0 1
vars (24)
on left: 8 9, on right: 3 9
fname (25)
on left: 10, on right: 1 2
type (26)
on left: 11 12 13, on right: 1 3 12 13 18 19
ar (27)
on left: 14 15, on right: 13 15
pointer (28)
on left: 16 17, on right: 12 17
param (29)
on left: 18 19, on right: 1 19
call (30)
on left: 20 21, on right: 2 21
State 0
0 $accept: . s $end
VAR shift, and go to state 1
VTYPE shift, and go to state 2
RETURN shift, and go to state 3
OPEN_F shift, and go to state 4
CLOSE_F shift, and go to state 5
s go to state 6
fname go to state 7
type go to state 8
State 1
4 s: VAR . EQL NUM SEMI_COLON
10 fname: VAR .
EQL shift, and go to state 9
$default reduce using rule 10 (fname)
State 2
11 type: VTYPE .
$default reduce using rule 11 (type)
State 3
5 s: RETURN . VAR SEMI_COLON NEW_LINE
VAR shift, and go to state 10
State 4
6 s: OPEN_F .
$default reduce using rule 6 (s)
State 5
7 s: CLOSE_F .
$default reduce using rule 7 (s)
State 6
0 $accept: s . $end
$end shift, and go to state 11
State 7
2 s: fname . OPEN_P call CLOSE_P SEMI_COLON
OPEN_P shift, and go to state 12
State 8
1 s: type . fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F
3 | type . vars SEMI_COLON
12 type: type . pointer
13 | type . ar
VAR shift, and go to state 13
'[' shift, and go to state 14
'*' shift, and go to state 15
vars go to state 16
fname go to state 17
ar go to state 18
pointer go to state 19
State 9
4 s: VAR EQL . NUM SEMI_COLON
NUM shift, and go to state 20
State 10
5 s: RETURN VAR . SEMI_COLON NEW_LINE
SEMI_COLON shift, and go to state 21
State 11
0 $accept: s $end .
$default accept
State 12
2 s: fname OPEN_P . call CLOSE_P SEMI_COLON
VAR shift, and go to state 22
call go to state 23
State 13
8 vars: VAR .
9 | VAR . COMMA vars
10 fname: VAR .
COMMA shift, and go to state 24
OPEN_P reduce using rule 10 (fname)
$default reduce using rule 8 (vars)
State 14
14 ar: '[' . ']'
']' shift, and go to state 25
State 15
16 pointer: '*' .
$default reduce using rule 16 (pointer)
State 16
3 s: type vars . SEMI_COLON
SEMI_COLON shift, and go to state 26
State 17
1 s: type fname . OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F
OPEN_P shift, and go to state 27
State 18
13 type: type ar .
15 ar: ar . '[' ']'
'[' shift, and go to state 28
'[' [reduce using rule 13 (type)]
$default reduce using rule 13 (type)
State 19
12 type: type pointer .
17 pointer: pointer . '*'
'*' shift, and go to state 29
'*' [reduce using rule 12 (type)]
$default reduce using rule 12 (type)
State 20
4 s: VAR EQL NUM . SEMI_COLON
SEMI_COLON shift, and go to state 30
State 21
5 s: RETURN VAR SEMI_COLON . NEW_LINE
NEW_LINE shift, and go to state 31
State 22
20 call: VAR .
21 | VAR . COMMA call
COMMA shift, and go to state 32
$default reduce using rule 20 (call)
State 23
2 s: fname OPEN_P call . CLOSE_P SEMI_COLON
CLOSE_P shift, and go to state 33
State 24
9 vars: VAR COMMA . vars
VAR shift, and go to state 34
vars go to state 35
State 25
14 ar: '[' ']' .
$default reduce using rule 14 (ar)
State 26
3 s: type vars SEMI_COLON .
$default reduce using rule 3 (s)
State 27
1 s: type fname OPEN_P . param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F
VTYPE shift, and go to state 2
type go to state 36
param go to state 37
State 28
15 ar: ar '[' . ']'
']' shift, and go to state 38
State 29
17 pointer: pointer '*' .
$default reduce using rule 17 (pointer)
State 30
4 s: VAR EQL NUM SEMI_COLON .
$default reduce using rule 4 (s)
State 31
5 s: RETURN VAR SEMI_COLON NEW_LINE .
$default reduce using rule 5 (s)
State 32
21 call: VAR COMMA . call
VAR shift, and go to state 22
call go to state 39
State 33
2 s: fname OPEN_P call CLOSE_P . SEMI_COLON
SEMI_COLON shift, and go to state 40
State 34
8 vars: VAR .
9 | VAR . COMMA vars
COMMA shift, and go to state 24
$default reduce using rule 8 (vars)
State 35
9 vars: VAR COMMA vars .
$default reduce using rule 9 (vars)
State 36
12 type: type . pointer
13 | type . ar
18 param: type . VAR
19 | type . VAR COMMA param
VAR shift, and go to state 41
'[' shift, and go to state 14
'*' shift, and go to state 15
ar go to state 18
pointer go to state 19
State 37
1 s: type fname OPEN_P param . CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F
CLOSE_P shift, and go to state 42
State 38
15 ar: ar '[' ']' .
$default reduce using rule 15 (ar)
State 39
21 call: VAR COMMA call .
$default reduce using rule 21 (call)
State 40
2 s: fname OPEN_P call CLOSE_P SEMI_COLON .
$default reduce using rule 2 (s)
State 41
18 param: type VAR .
19 | type VAR . COMMA param
COMMA shift, and go to state 43
$default reduce using rule 18 (param)
State 42
1 s: type fname OPEN_P param CLOSE_P . NEW_LINE OPEN_F NEW_LINE s CLOSE_F
NEW_LINE shift, and go to state 44
State 43
19 param: type VAR COMMA . param
VTYPE shift, and go to state 2
type go to state 36
param go to state 45
State 44
1 s: type fname OPEN_P param CLOSE_P NEW_LINE . OPEN_F NEW_LINE s CLOSE_F
OPEN_F shift, and go to state 46
State 45
19 param: type VAR COMMA param .
$default reduce using rule 19 (param)
State 46
1 s: type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F . NEW_LINE s CLOSE_F
NEW_LINE shift, and go to state 47
State 47
1 s: type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE . s CLOSE_F
VAR shift, and go to state 1
VTYPE shift, and go to state 2
RETURN shift, and go to state 3
OPEN_F shift, and go to state 4
CLOSE_F shift, and go to state 5
s go to state 48
fname go to state 7
type go to state 8
State 48
1 s: type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s . CLOSE_F
CLOSE_F shift, and go to state 49
State 49
1 s: type fname OPEN_P param CLOSE_P NEW_LINE OPEN_F NEW_LINE s CLOSE_F .
$default reduce using rule 1 (s)
这是我给的输入文件
*int add(int a)
{
return a;
}
c=10;
d=20;
add(10);*
我得到这样的输出
您的词法分析器/解析器接口存在一些潜在的问题,但是由于您没有显示词法分析器,因此很难判断。
-
您有一个令牌
STAR
,但是您的语法使用'*'
,因此取决于您的词法分析器返回STAR
还是'*'
,它可能无法工作。您需要一致地使用令牌名称或单字符令牌文字。一般来说,我认为最好总是使用单字符字面量,因为这样更清晰(所以使用'('
而不是OPEN_P
等)。 -
您的语法在某些地方需要
NEW_LINE
标记,但是对于这种语言(带有显式的';'
分隔符),您通常希望词法分析器忽略换行符。
您的语法被编写为只接受一个声明,但是您给了它多个声明。人们可能会期望这会导致解析器简单地以Syntax error
退出,但可能是词法分析器的问题之一阻止了这种情况的发生。如果你想接受多个声明,你需要你的开始规则像input: /*empty*/ | input declaration ;
在语法中有两个shift/reduce冲突(状态18和19),这是由指针和数组的使用方式的模糊性引起的。简化一下,您有四个与指针相关的规则:
type : VTYPE | type pointer
pointer : '*' | pointer '*'
可以在type
或pointer
上递归,所以当你有一个具有多个*
的类型时,它可以以任何一种方式解析它们:
type type
/ /
type pointer type pointer
/ / /
VTYPE pointer '*' type pointer '*'
| / |
'*' VTYPE '*'
你会想要去掉其中一个递归(最简单的是去掉pointer
和ar
)。然而,这仍然可能不是您想要的,因为通常(在类似C的语言中),指针和数组修饰符与声明符相关联,而不是类型(因此您可以拥有像int *a, *b;
这样的输入)