1

割り当て全体のみを気にするいくつかの割り当てを解析したい。課題の内容についてではありません。割り当ては で示され':='ます。(編集:課題の前後に他のことが来るかもしれません)

いくつかの例:

a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;

現在、私は「ケース」を含む課題と他の課題を区別しています。単純な割り当てについては、次のようなものを試しまし~('case' | 'esac' | ';')たが、antlr は一致しないトークンについて不平を言いました ( など'=')。

assignment : 
   NAME ':='! expression ;

expression : 
    ( simple_expression | case_expression) ;


simple_expression : 
    ((OPERATOR | NAME) & ~('case' | 'esac'))+  ';'! ;

case_expression : 
    'case' .+ 'esac' ';'! ;

Eclipse インタープリター((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ;'and'.

   (~(OPERATOR | ~NAME | ('case' | 'esac')) |
    ~(~OPERATOR | NAME | ('case' | 'esac')) |
    ~(~OPERATOR | ~NAME | ('case' | 'esac')))  ';'!

しかし、これはうまくいきません。私は得る

"error(139): /AntlrTutorial/src/foo/NusmvInput.g:78:5: セット補数が空です |---> ~(~OPERATOR | ~NAME | ('case' | 'esac'))) EOC ! ;」

どうすれば解析できますか?

4

1 に答える 1

2

ここで問題が発生していることがいくつかあります。

  • &文法で使用しているのに、引用符で囲んでいる必要があります。'&'
  • 自分が何をしているのかを正確に理解していない限り、パーサールール内で使用しないでください(特にそうではあり~ませ..+!)。レクサールールでのみ使用してください。
  • 'case'パーサールールを定義する代わりにレクサールールを作成'esac'します(他のレクサールールが一致する可能性がない場合は、パーサールールでリテラルトークンを使用しても安全ですが'case'、よく似'esac' NAME おり、ASTに含まれる可能性があります。その場合はレクサーで自分で明示的に定義することをお勧めします)

簡単なデモは次のとおりです。

grammar T;

options {
  output=AST;
}

tokens {
  ROOT;
  CASES;
  CASE;
}

parse
 : (assignment SCOL)* EOF -> ^(ROOT assignment*)
 ;

assignment 
 : NAME ASSIGN^ expression 
 ;

expression
 : ternary_expression
 ;

ternary_expression
 : or_expression (QMARK^ ternary_expression COL! ternary_expression)?
 ;

or_expression
 : unary_expression ((AND | OR)^ unary_expression)*
 ;

unary_expression
 : NOT^ atom
 | atom
 ;

atom
 : TRUE
 | FALSE
 | NUMBER
 | NAME
 | CASE single_case+ ESAC -> ^(CASES single_case+)
 | '(' expression ')'     -> expression
 ;

single_case
 : expression COL expression SCOL -> ^(CASE expression expression)
 ;

TRUE   : 'TRUE';
FALSE  : 'FALSE';
CASE   : 'case';
ESAC   : 'esac';
ASSIGN : ':='; 
AND    : '&';
OR     : '|';
NOT    : '!';
QMARK  : '?';
COL    : ':';
SCOL   : ';';
NAME   : ('a'..'z' | 'A'..'Z')+;
NUMBER : ('0'..'9')+;
SPACE  : (' ' | '\t' | '\r' | '\n')+ {skip();};

入力を解析します:

a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;

次のように:

ここに画像の説明を入力してください

于 2012-06-07T20:16:39.570 に答える