2

所以我正在使用 ANTLRWorks 2.1 研究 ANTLR4 中的组合语法。我有词法分析器规则Identifier并且Block未被识别为定义的词法分析器规则,但仅在定义的最后一个解析器规则中。在这些规则之后添加文字会删除(或隐藏)这些错误。

我的语法最后有错误(斜体标记抛出错误):

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_;
4

1 回答 1

2

ANTLR 需要明确的语法规则。在提供的语法中,规则与规则和其他Symbol规则冲突。Operator和规则冲突IdentifierLetter当它们可以匹配相同的输入(内容和长度)时,规则会发生冲突。

此外,例如,该Symbol规则包括'{'作为 alt。在其任何 alt中使用文字(这是隐式标记类型)的后续规则'{'将不匹配,因为隐式标记类型与Symbol标记类型不同。最佳实践是避免重复使用文字 - 在规则中定义文字,然后仅引用该规则。

最好的建议是购买一份TDAR来学习 Antlr4。

于 2017-04-06T19:29:55.140 回答