2017-10-06 1 views
2

を解析停止します。予想通りAntlr4が突然、私は式の文法と簡単な計算機を開発しています表現

grammar Formula ; 
expr : <assoc=right> expr POW expr    # pow 
    | MINUS expr        # unaryMinus 
    | PLUS expr        # unaryPlus 
    | expr PERCENT       # percent 
    | expr op=(MULTIPLICATION|DIVISION) expr # multiplyDivide 
    | expr op=(PLUS|MINUS) expr    # addSubtract 
    | ABS '(' expr ')'      # abs 
    | '|' expr '|'       # absParenthesis 
    | MAX '(' expr (',' expr)* ')'   # max 
    | MIN '(' expr (',' expr)* ')'   # min 
    | '(' expr ')'       # parenthesis 
    | NUMBER         # number 
    | '"' COLUMN '"'       # column 
    ; 

MULTIPLICATION: '*' ; 
DIVISION: '/' ; 
PLUS: '+' ; 
MINUS: '-' ; 
PERCENT: '%' ; 
POW: '^' ; 
ABS: [aA][bB][sS] ; 
MAX: [mM][aA][xX] ; 
MIN: [mM][iI][nN] ; 
NUMBER: [0-9]+('.'[0-9]+)? ; 
COLUMN: (~[\r\n"])+ ; 
WS : [ \t\r\n]+ -> skip ; 

"column a"*"column b"入力は私に次のツリーを与える: enter image description here

しかし"column a" * "column b"入力が突然解析を停止します。 enter image description here

私には何が欠けていますか?

答えて

3

お客様のWSルールは、ルールで壊れており、高い数字はprecedenceです。より正確には、問題は~[\r\n"]もスペース文字に一致するということです。

"column a"*"column b" lexes次のように:'"'COLUMN'"'MULTIPLICATION'"'COLUMN'"'

"column a" * "column b" lexes次のように:'"'COLUMN'"'COLUMN'"'COLUMN'"'

はい、 "宇宙の星スペースは"としてレクサー処理しまいましたトークンはANTLRレクサールールの仕組みであるため、長いトークンの一致が優先されます。

あなたが見ることができるように、このトークンストリームはは全体としてexprルール、'"'COLUMN'"'で、それはできる限りそうexprマッチを、一致ししません。

あなたのように否定的なルールだけを使ってレクサールールを宣言すると、は常にという悪い考えです。別の'"'トークンを持っていても、私にとっては気分が悪いです。

COLUMN: '"' (~["\r\n])* '"'; 

は、その後、あなたのパーサールールからスタンドアロンの引用符を削除します。彼らは論理的にトークンの一部だとして、あなたがやるべき何

COLUMNルールで引用符を含めることです。構文解析ツリーを処理するときにテキストを後で引用符で囲むか、またはトークンの基になる値を変更するためにレクサーのトークン排出ロジックを変更することができます。

とするためには、入力を末尾無視するあなたが入力全体を消費してきたことを確認します別のルールを追加していない:

formula: expr EOF; 

あなたのパーサーを呼び出すときに、あなたのエントリールールの代わりに、exprとしてこのルールを使用します。

+0

詳細な説明ありがとうございます! – tiktak

3

はしかし、 "列" * "B列" の入力が突然、私はANTLR 4であなたの文法を実行する場合

を解析停止します。6、それはそれはパーサが一致しないことができるものをピンクにファイル全体およびディスプレイを解析し、解析し停止しません:

点はスペースを表しています。

、重要なエラーメッセージがあります:私はできるだけ早くあなたが「不一致」エラーを持っているようhereを説明したよう

line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'} 

、GRUNに-tokensを追加します。 "column a"*"column b"

"column a" * "column b"

$ grun Formula expr -tokens -diagnostics t1.text 
[@0,0:0='"',<'"'>,1:0] 
[@1,1:8='column a',<COLUMN>,1:1] 
[@2,9:9='"',<'"'>,1:9] 
[@3,10:10='*',<'*'>,1:10] 
[@4,11:11='"',<'"'>,1:11] 
[@5,12:19='column b',<COLUMN>,1:12] 
[@6,20:20='"',<'"'>,1:20] 
[@7,22:21='<EOF>',<EOF>,2:0] 

$ grun Formula expr -tokens -diagnostics t2.text 
[@0,0:0='"',<'"'>,1:0] 
[@1,1:8='column a',<COLUMN>,1:1] 
[@2,9:9='"',<'"'>,1:9] 
[@3,10:12=' * ',<COLUMN>,1:10] 
[@4,13:13='"',<'"'>,1:13] 
[@5,14:21='column b',<COLUMN>,1:14] 
[@6,22:22='"',<'"'>,1:22] 
[@7,24:23='<EOF>',<EOF>,2:0] 
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'} 

すぐ" * "COLUMNとして解釈されていることを参照してください。レクサールールと入力を照合について

多くの疑問はこれらの最後の日頼まれています

extraneous input

ordering

greedy

ambiguity

expression

ルーカスは問題のすべてを要約した回答をするだけで、間違った質問を投稿しています。disambiguate

関連する問題