解决 PLY 中表达式语法中的移位/归约冲突,以调用嵌入式函数

问题描述 投票:0回答:1

我正在为 PLY 中的解释器创建语法。目前,我正在尝试将嵌入式函数调用实现为表达式,但我在查看以下规则的冲突位置时遇到问题。

情况如下,语言中对于向量类型的对象有某些“原生”操作,对于某些数据类型也有某些函数。例如,对于向量,有 pop()、push()、join() 等函数

例如:

vect1.pop()
vect1.join()

所以我有以下规则:

expresion :     ID PUNTO POP PAREN_APERTURA PAREN_CIERRE
              | ID PUNTO INDEX_OF PAREN_APERTURA expresion PAREN_CIERRE
              | ID PUNTO JOIN PAREN_APERTURA PAREN_CIERRE

还有一些函数适用于某些类型的表达式,例如 toString()。

例如:

console.log(12.5.toString())
var num1 : number = 20;
console.log(num1.toString())

所以我添加了以下规则:

expresion : expresion PUNTO funcion_emb PAREN_APERTURA PAREN_CIERRE

funcion_emb     : TO_STRING
                | TO_UPPER_CASE
                | TO_LOWER_CASE

此外,还有其他用于转换值的函数,例如:

parseInt("12")
parseFloat("24.5")

遵循以下规则:

expresion:      PARSE_INT PAREN_APERTURA expresion PAREN_CIERRE
              | PARSE_FLOAT PAREN_APERTURA expresion PAREN_CIERRE
              | TYPE_OF expresion

问题是它生成了有关移位/归约冲突的警告,但它没有向我显示生成它的规则。

查看语法,可能是以下规则产生了冲突

expresion:      expresion PUNTO funcion_emb PAREN_APERTURA PAREN_CIERRE
              | ID PUNTO POP PAREN_APERTURA PAREN_CIERRE
              | ID PUNTO INDEX_OF PAREN_APERTURA expresion PAREN_CIERRE
              | ID PUNTO JOIN PAREN_APERTURA PAREN_CIERRE
              | PARSE_INT PAREN_APERTURA expresion PAREN_CIERRE
              | PARSE_FLOAT PAREN_APERTURA expresion PAREN_CIERRE
              | TYPE_OF expresion

以下是相应的表达式和优先级规则:

precedence = (
    ('left', 'OR'),
    ('left', 'AND'),
    ('left', 'IGUAL', 'DIFERENTE'),
    ('left', 'MENOR_QUE', 'MAYOR_QUE', 'MENOR_IGUAL', 'MAYOR_IGUAL'),
    ('left', 'MAS', 'MENOS'),
    ('left', 'MULTI', 'DIV', 'MOD'),
    ('right', 'NOT', 'UMENOS'),
    ('nonassoc', 'TYPE_OF'),    
)

expresion :     expresion MAS expresion
              | expresion MENOS expresion
              | expresion MULTI expresion
              | expresion DIV expresion
              | expresion MOD expresion
              | expresion IGUAL expresion
              | expresion DIFERENTE expresion
              | expresion MENOR_QUE expresion
              | expresion MAYOR_QUE expresion
              | expresion MENOR_IGUAL expresion
              | expresion MAYOR_IGUAL expresion
              | expresion AND expresion
              | expresion OR expresion
              | PAREN_APERTURA expresion PAREN_CIERRE
              | MENOS expresion %prec UMENOS
              | NOT expresion              
              | expresion PUNTO funcion_emb PAREN_APERTURA PAREN_CIERRE
              | ID PUNTO POP PAREN_APERTURA PAREN_CIERRE
              | ID PUNTO INDEX_OF PAREN_APERTURA expresion PAREN_CIERRE
              | ID PUNTO JOIN PAREN_APERTURA PAREN_CIERRE
              | PARSE_INT PAREN_APERTURA expresion PAREN_CIERRE
              | PARSE_FLOAT PAREN_APERTURA expresion PAREN_CIERRE
              | TYPE_OF expresion
              | literal
              | ID 


funcion_emb : TO_STRING
                | TO_UPPER_CASE
                | TO_LOWER_CASE

literal : LIT_NUMBER
            | LIT_FLOAT
            | LIT_CHAR
            | LIT_BOOLEAN
            | LIT_STRING

有什么建议吗?

python compiler-construction interpreter context-free-grammar ply
1个回答
0
投票

调试这些东西的最佳方法是调用

yacc.yacc(debug=True)
并查看生成的文件
parser.out

    (18) expresion -> ID . PUNTO POP ( )
    (19) expresion -> ID . PUNTO INDEX_OF ( expresion )
    (20) expresion -> ID . PUNTO JOIN ( )
    (25) expresion -> ID .

您已经阅读了

ID
,现在即将阅读一个句点。语法不确定是只移动句点,还是将 ID 转换为表达式。 (后者是一种可能性,因为
expression . function_emb ( )
在你的语法中。

解决方法是

ID PUNTO ...
永远不应该出现在你的语法中。在所有这些中,它应该是
expression PUNTO ...
,因为
pop()
等可以在任何表达式上调用

© www.soinside.com 2019 - 2024. All rights reserved.