1

これが何千回も議論されていることを私は知っていますが、なぜ文法に従うことが失敗しているのか理解できません。インタプリタでは、エラーや警告なしですべてが正常に機能します。ただし、生成されたコードを実行すると、以下に示すように入力が一致しなくなります。

この文法の場合:

grammar xxx;

options {
    language = Java;
    output = AST;
}

@members {
  @Override
    public String getErrorMessage(RecognitionException e,
    String[] tokenNames)
    {
        List stack = getRuleInvocationStack(e, this.getClass().getName());
        String msg = null;
        if ( e instanceof NoViableAltException ) {
            NoViableAltException nvae = (NoViableAltException)e;
            msg = " no viable alt; token="+e.token+
            " (decision="+nvae.decisionNumber+
            " state "+nvae.stateNumber+")"+
            " decision=<<"+nvae.grammarDecisionDescription+">>";
        }
        else {
          msg = super.getErrorMessage(e, tokenNames);
        }
        return stack+" "+msg;
    }

  @Override
    public String getTokenErrorDisplay(Token t) {
      return t.toString();
    }
}

obj
      : first=subscription 
      (COMMA other=subscription)*
      ;

subscription
      : ID
      (EQUALS arguments_in_brackets)?
      filters
      ;

arguments_in_brackets
      : LOPAREN arguments ROPAREN
      ;

arguments
      : (arguments_body)
      ;

arguments_body
      : argument (arguments_more)?
      ;

arguments_more
      : SEMICOLON arguments_body
      ;

argument
    : id_equals argument_body
    ;

argument_body
    :   STRING
    |   INT
    |   FLOAT
    ;

filters
      : LSPAREN expression RSPAREN
      ;

expression
      :  or
      ;

or
    : first=and
    (OR^ second=and)*
    ;

and        : first=atom
    (AND^ second=atom)*
    ;

atom
    : filter
    | atom_expression
    ;

atom_expression
    : LCPAREN
    expression
    RCPAREN
    ;

filter
    : id_equals arguments_in_brackets
    ;

id_equals
    : WS* ID WS* EQUALS WS*
    ;

COMMA: WS* ',' WS*;
LCPAREN : WS* '(' WS*;
RCPAREN : WS* ')' WS*;
LSPAREN : WS* '[' WS*;
RSPAREN : WS* ']' WS*;
LOPAREN : WS* '{' WS*;
ROPAREN : WS* '}' WS*;
AND: WS* 'AND' WS*;
OR: WS* 'OR' WS*;
NOT: WS* 'NOT' WS*;
EQUALS: WS* '=' WS*;
SEMICOLON: WS* ';' WS*;

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

INT :   '0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

//    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
//    :   '"' (~'"')* '"'
STRING
    :   '"' (~'"')* '"'
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

NEWLINE:    '\r'? '\n' {skip();} ;

WS:     (' '|'\t')+ {skip();} ;

そして、この入力について:

status={name="Waiting";val=5}[ownerEmail1={email="dsa@fdsf.ds"} OR internalStatus={status="New"}],comments={type="fds"}[(internalStatus={status="Owned"} AND ownerEmail2={email="dsa@fds.ds"}) OR (role={type="Contributor"} AND status={status="Closed"})]

私が得ている:

line 1:67 [obj, subscription, filters, expression, or, and, atom, filter, arguments_in_brackets] mismatched input [@18,67:80='internalStatus',<11>,1:67] expecting  ROPAREN
line 1:157 [obj, subscription, filters, expression, or, and, atom, atom_expression, expression, or, and, atom, filter, arguments_in_brackets] mismatched input [@42,157:167='ownerEmail2',<11>,1:157] expecting ROPAREN

誰かが私に何か手がかりを与えることができますか?なぜこれが失敗するのですか?私はそれを多くの方法で書き直そうとしましたが、エラーはまだ同じです。

4

1 に答える 1

1

問題はWS、他のレクサールールでトークンを使用しているため、これらのトークンをスキップしていることです。これにより、レクサーはこれらのトークンを完全に破棄し、パーサールールで使用できなくなります。

したがって、次のようなルールがある場合:

WS : ' ' {skip();};

次に、このルールを次の場所で使用しますNOT

NOT : WS* 'NOT' WS*;

NOTトークンもスキップされます。

これらの文字をすでにスキップしている場合WSは、他のレクサールールに含める必要はありません。WS*他のルールのすべてを削除するだけです。

...
NOT : 'NOT';
...

(また、パーサールールからそれらを削除します。skipレクサーからのすべてのpedトークンは、とにかくパーサールールで使用できることはありません!)

于 2012-09-11T07:49:45.953 に答える