2017-04-05 3 views
0

ANTLRWorks 2.1でANTLR4で結合された文法に取り組んでいます。私は定義されたレクサールールとして認識されないが、最後に定義されたパーサールールでのみ認識されるレクサールールIdentifierBlockを持っています。これらのルールの後にリテラルを追加すると、これらのエラーが削除(または非表示)されます。ANTL 4結合された文法ではレクサールールが認識されない

最後にエラーと私の文法(イタリック体のトークンはエラーを投げている):

grammar GCombined; 

options { language = Cpp; } 

@lexer::namespace{AntlrTest01} 
@parser::namespace{AntlrTest01} 

    /* First Lexer Stage */ 

Bit: '0' | '1'; 
Digit : '0'..'9'; 
ODigit: '0'..'7'; 
XDigit: '0'..'f'; 
Letter: ('a'..'z') | ('A'..'Z'); 
Symbol: '|' 
     | '-' 
     | '!' 
     | '#' 
     | '$' 
     | '%' 
     | '&' 
     | '(' 
     | ')' 
     | '*' 
     | '+' 
     | ',' 
     | '-' 
     | '.' 
     | '/' 
     | ':' 
     | ';' 
     | '<' 
     | '=' 
     | '>' 
     | '?' 
     | '@' 
     | '[' 
     | ']' 
     | '^' 
     | '_' 
     | '`' 
     | '{' 
     | '|' 
     | '}' 
     | '~'; 
WSpace: (' ' 
     | '\t' 
     | '\r' 
     | '\n' 
     | '\c' 
     | '\0' 
     | '\u000C' 
     )+ -> skip; 

DNumber: Digit+; 
ONumber: '0o' Digit+; 
XNumber: '0x' Digit; 
Integer: DNumber 
     | ONumber 
     | XNumber; 
Float: DNumber '.' DNumber; 

Character: Letter 
     | Digit 
     | Symbol 
     | WSpace; 
String: Character+; 
Literal: '"' String '"'; 

Boolean: 'true' | 'false'; 

    /* Second Lexer Stage */ 

Number: Integer | Float; 
Identifier: Letter (Letter | Digit | '_')+; 
Keyword: Letter+; 
Operator: '+' 
     | '-' 
     | '*' 
     | '/' 
     | '%' 
     | '==' 
     | '!=' 
     | '>' 
     | '<' 
     | '>=' 
     | '<=' 
     | '&&' 
     | '||' 
     | '^' 
     | '&' 
     | '|' 
     | '<<' 
     | '>>' 
     | '~' ; 

Expression: (Operator | Identifier) 
     '(' (Identifier | Number)+ ')'; 
Parameter: Identifier 
     | Expression 
     | Number; 
Statement: Keyword '(' Parameter+ ')'; 
Block: '{' Statement+ '}'; 

    /* Third Lexer Stage */ 

Add: '+'; 
Sub: '-'; 
Mlt: '*'; 
Div: '/'; 
Mod: '%'; 
Mathop: Add | Sub | Mlt | Div | Mod; 

Deq: '=='; 
Neq: '!='; 
Gtr: '>'; 
Lss: '<'; 
Geq: '>='; 
Leq: '<='; 
Condop: Deq | Neq | Gtr | Lss | Geq | Leq; 

And: '&&'; 
Or: '||'; 
Xor: '^'; 
Bnd: '&'; 
Bor: '|'; 
Logop: And | Or | Xor | Bnd | Bor; 

Neg: '!'; 
Boc: '~'; 
Negop: Neg | Boc; 

Asl: '<<'; 
Asr: '>>'; 
Shftop: Asl | Asr; 

Eql: '='; 

Inc: '++'; 
Dec: '--'; 
Incop: Inc | Dec; 

Peq: '+='; 
Meq: '-='; 
Teq: '*='; 
Seq: '/='; 
Req: '%='; 
Casop: Peq | Meq | Teq | Seq | Req; 

Lparen: '('; 
Rparen: ')'; 
Lbrack: '['; 
Rbrack: ']'; 
Lbrace: '{'; 
Rbrace: '}'; 
Point : '.'; 
Colon : ':'; 

Numvar: Number 
     | Identifier 
     | Mathop '(' Parameter+ ')'; 
Boolvar: Boolean 
     | Identifier 
     | Condop '(' Parameter+ ')' 
     | Logop '(' Parameter+ ')'; 
Metaxpr: (Identifier | Operator) '(' Parameter+ ')'; 

    /* First Parser Stage */ 

    //expressions 

add: '+' '(' Numvar+ ')'; 
sub: '-' '(' Numvar+ ')'; 
mlt: '*' '(' Numvar+ ')'; 
div: '/' '(' Numvar+ ')'; 
mod: '%' '(' Integer+ ')'; 
mathexpr: add 
     | sub 
     | mlt 
     | div 
     | mod; 

eql: '==' '(' Parameter+ ')'; 
neq: '!=' '(' Parameter+ ')'; 
gtr: '>' '(' Parameter+ ')'; 
les: '<' '(' Parameter+ ')'; 
geq: '>=' '(' Parameter+ ')'; 
leq: '<=' '(' Parameter+ ')'; 
condexpr: eql 
     | neq 
     | gtr 
     | les 
     | geq 
     | leq; 

and: '&&' '(' Parameter+ ')'; 
or : '||' '(' Parameter+ ')'; 
xor: '^' '(' Parameter+ ')'; 
bnd: '&' '(' Parameter+ ')'; 
bor: '|' '(' Parameter+ ')'; 
logexpr: and 
     | or 
     | xor 
     | bnd 
     | bor; 

asl: '<<' '(' Parameter Numvar ')'; 
asr: '>>' '(' Parameter Numvar ')'; 
shiftexpr: asl | asr; 

neg: '!' '(' Parameter ')'; 
boc: '~' '(' Parameter ')'; 
negexpr: neg 
     | boc; 

arrexpr: Identifier '[' Numvar ']'; 

    //instruction forms 

vardec: 'def' '(' Identifier+ ')' ': ' Identifier ; 
lindec: Identifier '(' Identifier ')'; 
assign: '=' '(' (Identifier | lindec) Parameter ')'; 

incstmt: (Inc | Dec) '(' Identifier ')' 
     | Casop '(' Identifier Identifier ')'; 

cond: 'if' '(' Boolvar ')' Block 
    ('else if' '(' Boolvar ')' Block)? 
    ('else' Block)?; 

loop: (
     ('while' '(' (condexpr | negexpr) ')') 
    | ('for' '(' assign ',' (condexpr | negexpr) ',' incstmt')') 
    ) Block; 

fundef: 'func' '(' Identifier Parameter+ ')' ': ' Identifier Block; 
prodef: 'proc' '(' Identifier Parameter* ')' Block; 
call: Identifier '(' Parameter+ ')'; 

excHandler: 'try' Block 
      'catch' '(' Identifier ')' Block 
      ('finally' Block)?; 

classdef: 'class' '(' Identifier ')' (': ' _Identifier_)? _Block_; 
+1

エラーを示す完全な文法を提供する必要があります。 – GRosenberg

答えて

0

ANTLRは、明確な文法規則が必要です。提供された文法では、SymbolルールはOperatorルールなどと競合します。 IdentifierLetterの規則が競合しています。同じ入力(コンテンツ&の長さ)に一致する場合、ルールは競合します。

また、例えば、Symbolのルールは、代替として'{'を含む。暗黙のトークンタイプがSymbolトークンタイプと同じではないため、いずれのaltsにもリテラル'{'(暗黙のトークンタイプ)を使用する後続のルールは一致しません。ベストプラクティスは、リテラルの冗長な使用を避けることです。リテラルをルールに定義し、そのルールを参照するだけです。

Antlr4を学ぶには、TDARのコピーを購入することをおすすめします。

+0

私は実際にチュートリアルとコーディングを読んできました。 Lo、見よ。レクサー・ステージの順序を逆にすると、問題が解決されます。 –

+0

並べ替えを行うと、他の競合するルールが期待どおりに機能しなくなります。 Antlrはあいまいさに対処していません - それは、常に(常に)矛盾するルールの最初のもの(トップダウン)を使用し、残っているものを機能的にシャドーイングする結果になります。 – GRosenberg

関連する問題