如何在我的PLY语法中解决这种转移 - 减少冲突?

时间:2013-07-16 06:55:34

标签: parsing programming-languages grammar ply shift-reduce-conflict

我正在编写一种编程语言的语法,但我一直在努力解决转移/减少问题。问题可以在州内找到:

fn_call -> ID . L_PAREN fn_args R_PAREN
assignment -> ID . ASSIGN value
assignment -> ID . ASSIGN container
value -> ID

在进一步解释之前,我想澄清一下:

这是shift / reduce,因为程序无法确定我是在调用函数还是使用ID作为值(例如,常量或变量)?

继续,是否有可能解决这个问题?我的语言目前不使用行分隔符(例如C中的';'或Python中的'\ n')。解析器是LALR(1)。

在函数调用或带行分隔符的变量之间解密的最有效方法是什么(在语法中添加最少的规则)?

编辑:这是该州的前瞻。

  ! shift/reduce conflict for L_PAREN resolved as shift
    L_PAREN         shift and go to state 60
    ASSIGN          shift and go to state 61
    COMMA           reduce using rule 43 (value -> ID .)
    R_PAREN         reduce using rule 43 (value -> ID .)
    DASH            reduce using rule 43 (value -> ID .)
    R_BRACE         reduce using rule 43 (value -> ID .)
    NONE            reduce using rule 43 (value -> ID .)
    DEFN            reduce using rule 43 (value -> ID .)
    FOR             reduce using rule 43 (value -> ID .)
    INT_T           reduce using rule 43 (value -> ID .)
    DBL_T           reduce using rule 43 (value -> ID .)
    STR_T           reduce using rule 43 (value -> ID .)
    ID              reduce using rule 43 (value -> ID .)
    INT             reduce using rule 43 (value -> ID .)
    DBL             reduce using rule 43 (value -> ID .)
    STR             reduce using rule 43 (value -> ID .)
    COMMENT_LINE    reduce using rule 43 (value -> ID .)
    L_BRACE         reduce using rule 43 (value -> ID .)
    SET             reduce using rule 43 (value -> ID .)

  ! L_PAREN         [ reduce using rule 43 (value -> ID .) ]

2 个答案:

答案 0 :(得分:2)

以下只是猜测,因为你没有表现出太多的语法。我假设你允许表达式作为语句,而不仅仅是函数调用。在这种情况下,表达式可以以(开头,语句可以以ID结尾。既然你没有语句分隔符(我认为),那么下面的内容真的很模糊:

a = b
(c + d)

在阅读bID)后,不清楚是否将其缩减为value,作为assignment的一部分,或将其保留为ID并将(转换为fn_call的一部分。

您无法通过添加制作来消除歧义。 :)

答案 1 :(得分:1)

如果这是构成解析器“状态”的项目集,那么你还没有把它写下来:

fn_call -> ID . L_PAREN fn_args R_PAREN
assignment -> ID . ASSIGN value
assignment -> ID . ASSIGN container
value -> ID .  *missing lookahead set*

你没有展示你的其他语言,所以我们无法知道规则的前瞻集是什么

 value -> ID

假设您在此状态下确实存在shift-reduce冲突,则前瞻集必须包含“ASSIGN”或“L_PAREN”。我不能告诉你如何在不知道更多的情况下解决你的问题。

鉴于你目前的语法存在这些问题,你无法解决这个简单的“添加规则”,无论它们是否涉及行分隔符,因为添加规则不会改变已经在先行集中的内容(它可能会添加更多令牌到现有的集合。)

编辑:解决问题的一种方法可能是切换解析技术。您的问题是LALR解析器无法处理您似乎拥有的 local 歧义。但是,如果你向前看,你的整体语法可能没有实际的模糊性。这取决于你的语言语法,但你正在自己动手,所以你可以随意做。我建议研究一下可以处理任意前瞻的GLR解析技术;查看最近版本的Bison。