语法 – 无法弄清楚如何解决减少/减少冲突

我正在尝试从glpk包
https://www3.nd.edu/~jeff/mathprog/glpk-4.47/doc/gmpl.pdf创建GNU MathProg语言的语法

不幸的是,到目前为止我写的语法很模糊.

当使用某些标识符时,我不知道如何告诉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
    ;

标识符只是“变量”的名称.变量具有特定类型(参数,集合,决策变量)并且可能被索引.在代码中,程序员必须在语句中声明变量类型,例如.

param p1;
param p2{1, 2} >=0;
set s1;
set s2{i in 1..5};
var v1 >=0;
var v2{S1,S2};

但是,当野牛看到标识符不知道应该使用哪个规则,我正在减少/减少冲突,如

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)]

我还有其他问题,但这个对我来说是阻碍

最佳答案 基本上问题是标识符出现在多个规则中:

numericExpression : identifier
symbolicExpression : identifier
setExpression: identifier

这可能适用于相同的背景.解决此问题的一种方法是为集名称和标量(参数和变量)名称引入不同的标记类型:

symbolicExpression : SCALAR_NAME
setExpression: SET_NAME

这将解决与集名称的冲突.我认为你不需要这个规则

numericExpression : identifier

因为在AMPL中存在从字符串到数字的自动转换,因此MathLrog是AMPL的子集,所以应该在numericExpression的上下文中允许symbolicExpression.

请注意,语法不是无上下文的,因此您需要从符号表中提取上述名称类别等附加信息,以解决此类问题.

我的flex有点生疏,但我认为你可以在标识符规则中做类似的事情:

return is_setname(...) ? TOK_SET_NAME : TOK_SCALAR_NAME;

其中is_setname是一个检查当前标识符是否为集合的函数.您需要定义此类函数并从符号表中获取必要的信息.

点赞