2016-05-01 15 views
4

glpkパッケージからGNU MathProg言語用の文法を作成しようとしていますhttps://www3.nd.edu/~jeff/mathprog/glpk-4.47/doc/gmpl.pdf
残念ながら、これまで書いた文法はあいまいです。 いくつかの識別子が使われているときに、バイソンに構文解析ツリーのどの枝が正しいかを伝える方法がわかりません。例:reduce/reduceの競合を解決する方法がわからない

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

のような競合を削減/削減取得しています私はまた、他の問題を抱えているが、これも私のためのブロッカーである

+0

パーサも表示できますか?私はあなたの文法を読んで、 "param" "var"の文字列を探し続けようとしています – aec

+0

ここにはbisonファイル全体があります。それはまだfinshedされていないことを覚えておいてください。いくつかの演算子の優先順位が欠落し、いくつかの表ルールがあります。 http://wklej.org/id/2370457/ – Lisu

+0

私は、そのような問題を明確に引き起こすのではなく、意味的に表現を分岐させるような気がします。 "numericExpression"や "logicalExpression"(たとえば)が足りないでしょうか? これらは両方とも同じことをよく評価します: "表現"。これらのより具体的な表現を使用して検証するだけです。 – aec

答えて

1

基本的に問題はidentifierが複数のルールに表示されていることである:

numericExpression : identifier 
symbolicExpression : identifier 
setExpression: identifier 

は、同じ文脈で適用される可能性があります。これを解決する一つの方法は、セット名とスカラー(パラメータおよび変数)のためのさまざまなトークンタイプを導入することである名:

symbolicExpression : SCALAR_NAME 
setExpression: SET_NAME 

これは、セット名との競合を解決します。 AMPLのサブセットでAMPLしたがってMathProg、中の数字に文字列からの自動変換がありますので、私はあなたがこのルール

numericExpression : identifier 

を必要とすることはないと思うので、symbolicExpressionnumericExpressionのコンテキストで許可されなければなりません。

文法は文脈自由ではないので、このような問題を解決するには、上記の名前カテゴリのような追加情報をシンボルテーブルから取得する必要があります。

マイフレックスは少し錆びですが、私はあなたが識別子のルールにそのような何かを行うことができると思う:

is_setnameは、現在の識別子が設定されているかどうかをチェックする機能です
return is_setname(...) ? TOK_SET_NAME : TOK_SCALAR_NAME; 

。このような関数を定義し、シンボルテーブルから必要な情報を取得する必要があります。

+0

あなたはSCALAR_NAMEとSET_NAMEをどのように区別しますか?どちらも単純にflex正規表現 によって生成されます> SYMBOLIC_NAME [a-zA-Z _] [a-zA-Z0-9 _] * 多分私はpre-lex解析を行い、param_name1、var_name2のようなプレフィックスを追加する必要があります – Lisu

+0

適切なトークンを返すことでflex規則でこれを実行できるはずです。私は答えを更新しました。 – vitaut

関連する問題