我正在为一种简单的编程语言构建这种语法(已经解决了以前的歧义问题:Can't figure out why Bison is throwing "Rules useless in parser due to conflicts")。
这是我完整的语法:http://pastebin.com/yBHLSP0z
这是Bison的输出文件:http://pastebin.com/eAma3gWy
(对不起,他们是西班牙语,但我认为他们很明显不言自明)
事实是,我仍然在状态107得到一个班次/减少错误(我正在翻译它):
state 107
31 factor: ID .
48 concatenacion: ID . OPERADOR_SUMA ID
49 | ID . OPERADOR_SUMA literal_string
OPERADOR_SUMA shift and go to state 140
OPERADOR_SUMA [reduce using rule 31 (factor)]
$default reduce using rule 31 (factor)
现在,状态107从状态70调用:
estado 70
45 asignacion: ID OPERADOR_ASIGNACION . concatenacion
46 | ID OPERADOR_ASIGNACION . expresion
47 | ID OPERADOR_ASIGNACION . literal_string
OPERADOR_RESTA desplazar e ir al estado 55
PARENTESIS_ABRE desplazar e ir al estado 56
COMILLA desplazar e ir al estado 67
ID desplazar e ir al estado 107
expresion ir al estado 108
termino ir al estado 61
factor ir al estado 62
concatenacion ir al estado 109
literal_string ir al estado 110
literal_real ir al estado 63
literal_entero ir al estado 64
signo ir al estado 65
我认为正在发生的事情(如果我错了请纠正我)是当它找到这样的“asignacion”规则时:
asignacion: ID OPERADOR_ASIGNACION concatenacion | ID OPERADOR_ASIGNACION expresion
它看到从“expresion”它可以获得一个ID令牌(expresion> termino> factor> ID),使 ID OPERADOR_ASIGNACION ID :
expresion:
expresion OPERADOR_SUMA termino
| expresion OPERADOR_RESTA termino
| termino
;
termino:
termino OPERADOR_MULTIPLICACION factor
| termino OPERADOR_DIVISION factor
| factor
;
factor:
ID
| literal_entero
| literal_real
| PARENTESIS_ABRE expresion PARENTESIS_CIERRA
;
现在,当它到达 ID OPERADOR_ASIGNACION concatenacion 并查看“concatenacion”的规则时,它会得到:
concatenacion:
ID OPERADOR_SUMA ID
| ID OPERADOR_SUMA literal_string
| literal_string OPERADOR_SUMA ID
| literal_string OPERADOR_SUMA literal_string
;
其中两个以“ID”开头。因此,如果选择了这两个规则中的任何一个,它就会进入一个状态,它可以获得 ID OPERADOR_ASIGNACION ID ,只有那个带有“concatenacion”规则的状态才需要找到“OPERADOR_SUMA”令牌。 。但是我认为,一旦它看到“concatenacion”和“expresion”都可以形成 ID OPERADOR_ASIGNACION ID 表达式,它就会窒息。
如果这不是正在发生的事情,我想知道那是什么问题。
而且,如果我在错误发生的地方是正确的,我真的不知道如何解决它。
请帮忙:)
谢谢!
答案 0 :(得分:2)
问题来自:
asignacion
: ID OPERADOR_ASIGNACION concatenacion
| ID OPERADOR_ASIGNACION expresion
;
以及所选择的替代方案:
expresion
: expresion OPERADOR_SUMA termino
;
termino
: factor
;
factor
: ID
;
concatenacion
: ID OPERADOR_SUMA ID
;
这意味着当您的解析器遇到:
x = y + z
它无法判断它是否正在处理asignacion
的第一个或第二个备选方案。
这很容易。怎么修?最简单的修复(如果它可以工作,我没有测试过)将删除我显示的concatenacion
规则,并在expresion
规则中识别您何时处理{{1} } vs concatenacion
因为它们在语法上是相同的:
expresion
你会看到ID OPERADOR_SIGNACION ID OPERADOR_SUM ID
的两个操作数的类型,如果它们都是字符串类型,那么你假设它是expresion
,否则是concatenacion
}。
您可能希望查看整个expresion
规则。我认为您需要通过concatenacion
规则设置字符串,因此您需要为factor
添加另一种替代方法:
factor
这意味着您必须拒绝其他规则中的文字字符串,因此需要进行更多的语义检查。另一种方法是引入除factor
: literal_string
;
之外的单独运算符来表示“字符串连接”。 SQL使用+
;有些语言使用||
;您可以完全使用其他令牌,例如,
。一旦脱离@
,有很多选择。你甚至可以使用'两个相邻的字符串表达式来表示连接操作',它们之间没有运算符吗?
如果这些都不起作用,请回复我。