3

現在、これを使用して算術式を解析しています。

expr  : '(' expr ')' 
      | number op expr 
      | variable op expr 
      | number
      | variable
      | <error>

単純な式では機能しますが、ネストされたブラケット式は処理できません。ネストされた式を処理できるように拡張/変更する方法。

たとえば、これは機能します:

5 + 12
33 - $var
13 + 2 * $v
( 44 + 98 )

しかし、これは機能しません:

( 44 + 98 ) / 2
( 44 + 98 ) / ( 5 + $var2 )
( 11 + 5 ) * ( 3 + ( $v * 2 ) )
4

2 に答える 2

4

優先チェーンに問題があります。1 + (2 + 3)は として解析できます。右側の は ですが、 の左側に表示できないためnumber op expr、解析できません。もちろん、左再帰は禁止されているため、そこに直接追加することはできません。あなたがする必要があるのは、それを次のように分解することです:expr'(' expr ')'(1 + 2) + 3exprop

expr: term '+' expr
    | term '-' expr
    | term

term: factor '*' term
      | factor '/' term
      | factor

factor: '(' expr ')'
    | number
    | variable
    | <error>

はい、括弧はチェーンの最後にずっとあります。これは奇妙に思えるかもしれませんが、括弧で囲まれた式は因子が可能な場所ならどこにでも表示でき、バブルアップする前に評価されるということです。すべてが を参照しているためfactor、括弧で囲まれた式は必要な場所に表示できることが簡単にわかります。

于 2016-02-14T21:26:32.520 に答える
3

中置演算子を使用して、括弧で囲まれた式を別の式と結合するルールを追加します。

| '(' expr ')' op expr

ところで、元の文法は wrt ネストされた式には影響しませんが、括弧内の用語で始まる中置式には問題があります。

一般に、ユーザー ホブズによる解決策は、好みの異なる中置演算子を使用した式に取り組むための標準的なアプローチです。これには、正しい部分式の評価順序が適切な文法によって処理され、余分なコードで処理する必要がないという追加の利点があります。

本格的な式エバリュエーターが必要ない場合にのみ、私のソリューションを使用してください (必要であることが最も確実にわかります...)。

于 2016-02-14T21:28:56.353 に答える