2

ANTLR を使用して LALR 文法を LL に変換しようとしていますが、いくつかの問題が発生しています。これまでのところ、式をトップダウンのアプローチに変換するのは簡単だと思います。問題は、Range (1..10) と (1.0..10.0) を float に含める場合です。

ここで見つかった答えを使用しようとしましたが、どういうわけか、フロートの範囲、つまり(float..float)を解決することは言うまでもなく、コードで正しく実行されていません。 ANTLR の浮動リテラルと範囲パラメーター

添付されているのは、この問題に焦点を当てた私の文法のサンプルです。

grammar Test;

options {
  language = Java;
  output = AST;
}

parse: 'in' rangeExpression ';'
     ;

rangeExpression : expression ('..' expression)?
                ;

expression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
           ;

addingExpression : multiplyingExpression (('+'|'-') multiplyingExpression)*
                 ;

multiplyingExpression : unaryExpression 
                        (('*'|'/'|'div') unaryExpression)*
                      ;

unaryExpression: ('+'|'-')* primitiveElement;   

primitiveElement : literalExpression
                 | id ('.' id)?
                 | '(' expression ')'
                 ;  

literalExpression : NUMBER
                  | BOOLEAN_LITERAL
                  | 'infinity'
                  ;              

id : IDENTIFIER
   ;

// L E X I C A L   R U L E S    
Range
 : '..'
 ;

NUMBER 
    : (DIGITS Range) => DIGITS          {$type=DIGITS;} 
    | (FloatLiteral) => FloatLiteral    {$type=FloatLiteral;}
    | DIGITS                            {$type=DIGITS;}
    ;   


// fragments
fragment FloatLiteral : Float;
fragment Float
 : DIGITS ( options {greedy = true; } : '.' DIGIT* EXPONENT?)
 | '.' DIGITS EXPONENT?
 | DIGITS EXPONENT
 ;

BOOLEAN_LITERAL : 'false' 
                | 'true'
                ;

IDENTIFIER : LETTER (LETTER | DIGIT)*;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

服用していない理由:

in 10;

また

in 10.0;

前もって感謝します!

4

2 に答える 2

2

次のことは正しくありません。

  • ルールFloatLiteral内で一致することはありませんliteralExpression
  • NUMBERトークンのタイプを変更するすべての選択肢では、NUMBERトークンが作成されることはありません。

このようなものは、との両方11..22で機能するはずです1.1..2.2

...

literalExpression : INT
                  | BOOLEAN_LITERAL
                  | FLOAT
                  | 'infinity'
                  ;              

id : IDENTIFIER
   ;

// L E X I C A L   R U L E S    
Range
 : '..'
 ;

INT 
    : (DIGITS Range)=> DIGITS
    | DIGITS (('.' DIGITS EXPONENT? | EXPONENT) {$type=FLOAT;})?
    ; 

BOOLEAN_LITERAL : 'false' 
                | 'true'
                ;

IDENTIFIER : LETTER (LETTER | DIGIT)*;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment FLOAT : ;
于 2013-02-21T17:32:09.283 に答える
1

取り扱いに関するご質問へ(1.0 .. 10.0)

パーサー ルールprimitiveElementは代替を として定義します'(' expression ')'が、ルールexpressionは決してルールに到達できないことに注意してくださいrangeExpression

expression次のrangeExpressionように再定義することを検討してください。

expression : rangeExpression
           ;

rangeExpression : compExpression ('..' compExpression)?
                ;

compExpression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
               ;

これにより、expressionルールがすべての形式の式の上にあり、括弧内で期待どおりに機能することが保証されます。

于 2013-02-21T17:58:06.147 に答える