-1
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 match\n");}
    |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);*

我得到这样的输出

4

1 回答 1

0

您的词法分析器/解析器接口存在一些潜在问题,但是由于您没有向词法分析器展示,因此很难分辨。

  • 您有一个 token STAR,但随后您的语法使用'*',因此取决于您的词法分析器是否返回STARor '*',它可能无法正常工作。您需要始终使用标记名称或单字符标记文字。一般来说,我认为最好始终使用单字符文字,因为这样更清晰(所以使用'('代替OPEN_P等)。

  • 您的语法NEW_LINE在某些地方需要标记,但是对于这种语言(带有显式';'分隔符),您通常希望词法分析器忽略换行符。

你的语法被写成只接受一个声明,但你给它多个声明。人们会期望这会导致您的解析器简单地以 a 退出Syntax error,但也许您的词法分析器问题之一正在阻止这种情况。如果你想接受多个声明,你需要你的开始规则是这样的input: /*empty*/ | input declaration ;

您的语法中有两个移位/减少冲突(状态 18 和 19),这是由您处理指针和数组的方式中的歧义引起的。稍微简化一下,您有四个与指针相关的规则:

type : VTYPE | type pointer
pointer : '*' | pointer '*'

它可以在typeor上递归pointer,所以当你有一个带有多个*'s 的类型时,它可以用任何一种方式解析它们:

            type                         type
           /    \                       /    \
       type      pointer            type      pointer
        /       /       \          /    \         \
     VTYPE    pointer   '*'     type   pointer    '*'
                 |               /        |
                '*'            VTYPE     '*'

你会想要摆脱其中一个递归(最简单的是摆脱pointerand ar)。但是,这仍然可能不是您想要的,因为通常(在类似 C 的语言中),指针和数组修饰符与声明符相关联,而不是类型(因此您可以输入类似int *a, *b;.)

于 2015-09-20T20:05:54.557 回答