0

我正在用 bison 构建语法,但我有 ar/r 冲突(我知道它在哪里),但我不知道如何解决它。我将不胜感激任何可能的帮助。

我的代码中包含冲突的部分是:

orismos2: %empty
|orismos orismos2
|error {yyerrok;yyclearin;};

orismos: orismosmetablitwn
|orismossunartisis
|prwtotuposunartisis;

orismosmetablitwn: tuposdedomenwn listametablitwn SEMICOLON ;

tuposdedomenwn: INT
|BOOL
|STRING;

listametablitwn: ID nid ;

nid: %empty
|pid nid
|error {yyerrok;yyclearin;};

pid: COMMA ID ;

orismossunartisis: kefalidasunartisis tmimaorismwn tmimaentolwn;

prwtotuposunartisis: kefalidasunartisis SEMICOLON;

kefalidasunartisis: typos_synartisis ID OPENBRACKET c CLOSEBRACKET;

typos_synartisis: INT
|BOOL
|VOID;

我制作了一个输出文件,在其中我可以看到所有的冲突。

包含冲突的文件部分是:

State 21 conflicts: 1 reduce/reduce
State 22 conflicts: 1 reduce/reduce


Grammar

   10 orismos2: %empty
   11         | orismos orismos2
   12         | error

   13 orismos: orismosmetablitwn
   14        | orismossunartisis
   15        | prwtotuposunartisis

   16 orismosmetablitwn: tuposdedomenwn listametablitwn SEMICOLON

   17 tuposdedomenwn: INT
   18               | BOOL
   19               | STRING

   20 listametablitwn: ID nid

   21 nid: %empty
   22    | pid nid
   23    | error

   24 pid: COMMA ID

   25 orismossunartisis: kefalidasunartisis tmimaorismwn tmimaentolwn

   26 prwtotuposunartisis: kefalidasunartisis SEMICOLON

   27 kefalidasunartisis: typos_synartisis ID OPENBRACKET c CLOSEBRACKET

   28 typos_synartisis: INT
   29                 | BOOL
   30                 | VOID


State 21

   17 tuposdedomenwn: INT .
   28 typos_synartisis: INT .

    ID        reduce using rule 17 (tuposdedomenwn)
    ID        [reduce using rule 28 (typos_synartisis)]
    $default  reduce using rule 17 (tuposdedomenwn)


State 22

   18 tuposdedomenwn: BOOL .
   29 typos_synartisis: BOOL .

    ID        reduce using rule 18 (tuposdedomenwn)
    ID        [reduce using rule 29 (typos_synartisis)]
    $default  reduce using rule 18 (tuposdedomenwn)

我真的已经尝试了一切,但我无法消除冲突......欢迎任何想法或建议!

非常感谢!!

4

1 回答 1

0

关键在这里:……

orismos → (13) orismosmetablitwn → (16) tuposdedomenwn listametablitwn
orismos → (14) orismossunartisis → (25) kefalidasunartisis … → (27) typos_synartisis …
orismos → (15) prwtotuposunartisis → (26) kefalidasunartisis … → (27) typos_synartisis …

还:

tuposdedomenwn → NUMBER | BOOL | STRING
listametablitwn → ID …
kefalidasunartisis → typos_synartisis ID …
typos_synartisis → NUMBER | BOOL | VOID

所以,这里有一些推导orismos

orismos → orismosmetablitwn → tuposdedomenwn listametablitwn → NUMBER ID …
orismos → orismossunartisis → kefalidasunartisis … → typos_synartisis … → NUMBER ID …
orismos → prwtotuposunartisis → kefalidasunartisis … → typos_synartisis … → NUMBER ID …

假设我们处于orismis可能的上下文中,并且我们刚刚看到 aNUMBER而我们现在正在查看 a ID。以上三种推导都是可能的。但是有一个小问题:在第一个中,NUMBER是派生自,tuposdedomenwn而在后两个中,它是派生自typos_synartisis. 在我们对 进行任何操作之前,我们需要知道要减少两个推导中的哪一个,但是在我们看到之后ID标记之前,我们无法知道这一点。ID

这意味着语法需要两个前瞻标记,因此 LALR(1) 解析器无法解析它。

最简单的解决方案是将表示类型集的两个非终结符组合起来,创建一个允许所有四种可能性的非终结符:

tuposdedomenwn: NUMBER | BOOL | STRING | VOID

然后,您必须稍后进行语义检查,以验证未声明变量VOID或声明函数STRING。(为什么你的函数不能返回字符串?这似乎有点限制。)这种接受语言上标,然后在 AST 构建期间甚至稍后进行语义检查的策略非常常见。例如,这是在使用变量之前强制声明的唯一方法。

但是,如果您不想进行语义检查,则可以通过创建由数据类型和ID. 这将导致类似:

tupodedomenon_kai_metavlites
       : INT ID
       | BOOL ID
       | STRING ID
       | tupodedomenon_kai_metavlites ',' ID

tupo_synartisis_kai_metavliton
       : INT ID
       | BOOL ID
       | VOID ID

orismos: orismosmetablitwn
       | orismossunartisis
       | prwtotuposunartisis

orismosmetablitwn
       : tupodedomenon_kai_metavlites ';'

orismossunartisis
       : kefalidasunartisis tmimaorismwn tmimaentolwn

prwtotuposunartisis
       : kefalidasunartisis ';'

kefalidasunartisis
       : tupo_synartisis_kai_metavliton '(' c ')'

有了这种变化,就没有必要减少NUMBER(或其他类型);ID可以移动,然后将基于以下标记执行减少为一种或另一种可能性:如果以下标记为 或 ,则作为变量声明,如果以下标记为,;,作为函数声明(

于 2016-06-04T20:57:28.163 回答