使用GLR解析器时,将EBNF转换为BNF的正确方法是什么?

时间:2015-04-01 08:05:58

标签: parsing glr

EBNF喜欢这个

Goal = Stmt
Stmt = "if" "expr" "then" Stmt ("else" Stmt)?
Stmt = "S"

我应该将其转换为

Goal = Stmt
X = "else" Stmt
Stmt = "if" "expr" "then" Stmt | "if" "expr" "then" Stmt X 
Stmt = "S"

或者

Goal = Stmt
Stmt = "if" "expr" "then" Stmt | "if" "expr" "then" Stmt "else" Stmt
Stmt = "S"

这两个BNF对GLR解析器的意义是否相同?

------------------------ APPEND CONTENT --------------------- ---------

如果词法是

"if" "expr" "then" "if" "expr" "then" "S" "else" "S"

GLR解析器应该有两棵树

Goal
    Stmt
        "if"
        "expr"
        "then"
        Stmt
            "if"
            "expr"
            "then"
            Stmt
                "S"
        "else"
        Stmt
            "S"

Goal
    Stmt
        "if"
        "expr"
        "then"
        Stmt
            "if"
            "expr"
            "then"
            Stmt
                "S"
            "else"
             Stmt
                "S"

但是第一个转换后的BNF只能得到第一个树,因为当它遇到"else"时,减少/转移没有冲突,冲突就是在满足X.

第二个BNF在遇到"else"时会有一个减少/移位冲突,因此解析器将拆分为两个线程以在不同条件下解析。

我是对的吗?是否有任何ACTION,GOTO TABLE生成器会像第二个BNF一样处理第一个BNF?

1 个答案:

答案 0 :(得分:1)

它们是等效的语法,将解析相同的语言。

您的X语法仅在一个地方使用X.净效果就好像X的主体被替换为X被引用。在实践中,拥有X生产将迫使解析器做更多的工作。除非你想为X的减少附加一个语义动作,否则这个额外的工作不会在效率上购买任何东西。

如果使用这种一次性使用会使语法更易于维护,那么这很有用。在这样的小语法中,我没有看到这一点。在实际的语法中(我们有IBM COBOL的GLR语法,有5000个产品[责怪IBM,而不是我们]),这样的结构可能非常有用,额外的解析开销并不重要。