无法弄清楚如何解决 reduce/reduce 冲突
Can't figure out how to resolve reduce/reduce conflict
我正在尝试从 glpk 包中为 GNU MathProg 语言创建语法 https://www3.nd.edu/~jeff/mathprog/glpk-4.47/doc/gmpl.pdf
不幸的是,到目前为止我写的语法是模棱两可的。
当使用某些标识符时,我不知道如何告诉 bison 解析树的哪个分支是正确的。例如:
numericExpression : numericLiteral
| identifier
| numericFunctionReference
| iteratedNumericExpression
| conditionalNumericExpression
| '(' numericExpression ')' %prec PARENTH
| '-' numericExpression %prec UNARY
| '+' numericExpression %prec UNARY
| numericExpression binaryArithmeticOperator numericExpression
;
symbolicExpression : stringLiteral
| symbolicFunctionReference
| identifier
| conditionalSymbolicExpression
| '(' symbolicExpression ')' %prec PARENTH
| symbolicExpression '&' symbolicExpression
;
indexingExpression : '{' indexingEntries '}'
| '{' indexingEntries ':' logicalExpression '}'
;
setExpression : literalSet
| identifier
| aritmeticSet
| indexingExpression
| iteratedSetExpression
| conditionalSetExpression
| '(' setExpression ')' %prec PARENTH
| setExpression setOperator setExpression
;
numericLiteral : INT
| FLT
;
linearExpression : identifier
| iteratedLinearExpression
| conditionalLinearExpression
| '(' linearExpression ')' %prec PARENTH
| '-' linearExpression %prec UNARY
| '+' linearExpression %prec UNARY
| linearExpression '+' linearExpression
| linearExpression '-' linearExpression
| linearExpression '*' numericExpression
| numericExpression '*' linearExpression
| linearExpression '/' numericExpression
;
logicalExpression : numericExpression
| relationalExpression
| iteratedLogicalExpression
| '(' logicalExpression ')' %prec PARENTH
| NOT logicalExpression %prec NEG
| logicalExpression AND logicalExpression
| logicalExpression OR logicalExpression
;
identifier : SYMBOLIC_NAME
| SYMBOLIC_NAME '[' listOfIndices ']'
;
listOfIndices : SYMBOLIC_NAME
| listOfIndices ',' SYMBOLIC_NAME
;
标识符只是 'variable' 的名称。变量具有特定类型(参数、集合、决策变量)并且可能被索引。在代码中,程序员必须在 eg 等语句中声明变量类型。
param p1;
param p2{1, 2} >=0;
set s1;
set s2{i in 1..5};
var v1 >=0;
var v2{S1,S2};
但是当 bison 看到标识符时不知道应该使用哪个规则,我遇到了 reduce/reduce 冲突,例如
113 numericExpression: identifier .
123 symbolicExpression: identifier .
'&' reduce using rule 123 (symbolicExpression)
ELSE reduce using rule 113 (numericExpression)
ELSE [reduce using rule 123 (symbolicExpression)]
INTEGER reduce using rule 113 (numericExpression)
INTEGER [reduce using rule 123 (symbolicExpression)]
BINARY reduce using rule 113 (numericExpression)
BINARY [reduce using rule 123 (symbolicExpression)]
ASIGN reduce using rule 113 (numericExpression)
ASIGN [reduce using rule 123 (symbolicExpression)]
',' reduce using rule 113 (numericExpression)
',' [reduce using rule 123 (symbolicExpression)]
'>' reduce using rule 113 (numericExpression)
'>' [reduce using rule 123 (symbolicExpression)]
'}' reduce using rule 113 (numericExpression)
'}' [reduce using rule 123 (symbolicExpression)]
113 numericExpression: identifier .
123 symbolicExpression: identifier .
130 setExpression: identifier .
UNION reduce using rule 130 (setExpression)
DIFF reduce using rule 130 (setExpression)
SYMDIFF reduce using rule 130 (setExpression)
ELSE reduce using rule 113 (numericExpression)
ELSE [reduce using rule 123 (symbolicExpression)]
ELSE [reduce using rule 130 (setExpression)]
WITHIN reduce using rule 130 (setExpression)
IN reduce using rule 113 (numericExpression)
IN [reduce using rule 123 (symbolicExpression)]
我还有其他问题,但这个对我来说是个障碍
基本上问题是 identifier
出现在多个规则中:
numericExpression : identifier
symbolicExpression : identifier
setExpression: identifier
这可能适用于相同的上下文。解决这个问题的一种方法是为集合名称和标量(参数和变量)名称引入不同的标记类型:
symbolicExpression : SCALAR_NAME
setExpression: SET_NAME
这将解决与集合名称的冲突。我认为你不需要这条规则
numericExpression : identifier
因为 AMPL 中有从字符串到数字的自动转换,因此 MathProg 是 AMPL 的一个子集,所以 symbolicExpression
应该允许在 numericExpression
的上下文中.
请注意,语法不是上下文无关的,因此您需要从符号 table 中提取其他信息(如上面的名称类别)来解决此类问题。
我的 flex 有点生疏,但我认为你可以在标识符规则中做类似的事情:
return is_setname(...) ? TOK_SET_NAME : TOK_SCALAR_NAME;
其中is_setname
是检查当前标识符是否为集合的函数。您需要定义这样的函数并从符号 table.
中获取必要的信息
我正在尝试从 glpk 包中为 GNU MathProg 语言创建语法 https://www3.nd.edu/~jeff/mathprog/glpk-4.47/doc/gmpl.pdf
不幸的是,到目前为止我写的语法是模棱两可的。
当使用某些标识符时,我不知道如何告诉 bison 解析树的哪个分支是正确的。例如:
numericExpression : numericLiteral
| identifier
| numericFunctionReference
| iteratedNumericExpression
| conditionalNumericExpression
| '(' numericExpression ')' %prec PARENTH
| '-' numericExpression %prec UNARY
| '+' numericExpression %prec UNARY
| numericExpression binaryArithmeticOperator numericExpression
;
symbolicExpression : stringLiteral
| symbolicFunctionReference
| identifier
| conditionalSymbolicExpression
| '(' symbolicExpression ')' %prec PARENTH
| symbolicExpression '&' symbolicExpression
;
indexingExpression : '{' indexingEntries '}'
| '{' indexingEntries ':' logicalExpression '}'
;
setExpression : literalSet
| identifier
| aritmeticSet
| indexingExpression
| iteratedSetExpression
| conditionalSetExpression
| '(' setExpression ')' %prec PARENTH
| setExpression setOperator setExpression
;
numericLiteral : INT
| FLT
;
linearExpression : identifier
| iteratedLinearExpression
| conditionalLinearExpression
| '(' linearExpression ')' %prec PARENTH
| '-' linearExpression %prec UNARY
| '+' linearExpression %prec UNARY
| linearExpression '+' linearExpression
| linearExpression '-' linearExpression
| linearExpression '*' numericExpression
| numericExpression '*' linearExpression
| linearExpression '/' numericExpression
;
logicalExpression : numericExpression
| relationalExpression
| iteratedLogicalExpression
| '(' logicalExpression ')' %prec PARENTH
| NOT logicalExpression %prec NEG
| logicalExpression AND logicalExpression
| logicalExpression OR logicalExpression
;
identifier : SYMBOLIC_NAME
| SYMBOLIC_NAME '[' listOfIndices ']'
;
listOfIndices : SYMBOLIC_NAME
| listOfIndices ',' SYMBOLIC_NAME
;
标识符只是 'variable' 的名称。变量具有特定类型(参数、集合、决策变量)并且可能被索引。在代码中,程序员必须在 eg 等语句中声明变量类型。
param p1;
param p2{1, 2} >=0;
set s1;
set s2{i in 1..5};
var v1 >=0;
var v2{S1,S2};
但是当 bison 看到标识符时不知道应该使用哪个规则,我遇到了 reduce/reduce 冲突,例如
113 numericExpression: identifier .
123 symbolicExpression: identifier .
'&' reduce using rule 123 (symbolicExpression)
ELSE reduce using rule 113 (numericExpression)
ELSE [reduce using rule 123 (symbolicExpression)]
INTEGER reduce using rule 113 (numericExpression)
INTEGER [reduce using rule 123 (symbolicExpression)]
BINARY reduce using rule 113 (numericExpression)
BINARY [reduce using rule 123 (symbolicExpression)]
ASIGN reduce using rule 113 (numericExpression)
ASIGN [reduce using rule 123 (symbolicExpression)]
',' reduce using rule 113 (numericExpression)
',' [reduce using rule 123 (symbolicExpression)]
'>' reduce using rule 113 (numericExpression)
'>' [reduce using rule 123 (symbolicExpression)]
'}' reduce using rule 113 (numericExpression)
'}' [reduce using rule 123 (symbolicExpression)]
113 numericExpression: identifier .
123 symbolicExpression: identifier .
130 setExpression: identifier .
UNION reduce using rule 130 (setExpression)
DIFF reduce using rule 130 (setExpression)
SYMDIFF reduce using rule 130 (setExpression)
ELSE reduce using rule 113 (numericExpression)
ELSE [reduce using rule 123 (symbolicExpression)]
ELSE [reduce using rule 130 (setExpression)]
WITHIN reduce using rule 130 (setExpression)
IN reduce using rule 113 (numericExpression)
IN [reduce using rule 123 (symbolicExpression)]
我还有其他问题,但这个对我来说是个障碍
基本上问题是 identifier
出现在多个规则中:
numericExpression : identifier
symbolicExpression : identifier
setExpression: identifier
这可能适用于相同的上下文。解决这个问题的一种方法是为集合名称和标量(参数和变量)名称引入不同的标记类型:
symbolicExpression : SCALAR_NAME
setExpression: SET_NAME
这将解决与集合名称的冲突。我认为你不需要这条规则
numericExpression : identifier
因为 AMPL 中有从字符串到数字的自动转换,因此 MathProg 是 AMPL 的一个子集,所以 symbolicExpression
应该允许在 numericExpression
的上下文中.
请注意,语法不是上下文无关的,因此您需要从符号 table 中提取其他信息(如上面的名称类别)来解决此类问题。
我的 flex 有点生疏,但我认为你可以在标识符规则中做类似的事情:
return is_setname(...) ? TOK_SET_NAME : TOK_SCALAR_NAME;
其中is_setname
是检查当前标识符是否为集合的函数。您需要定义这样的函数并从符号 table.