我正在为 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
有什么建议吗?
调试这些东西的最佳方法是调用
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()
等可以在任何表达式上调用