2

ANTLR を使用してコンテキスト依存のレクサー ルールをコーディングしようとしていますが、必要な処理を行うことができません。ルールは、ルールの先頭にある文字に基づいて、2 つの選択肢のうちの 1 つに一致する必要があります。以下は、問題の大幅に簡略化されたバージョンです。

この例の文法:

lexer grammar X;

options
{
  language = C;
}

RULE :
  SimpleIdent {ctx->someFunction($SimpleIdent);}
  (
    {ctx->test != true}?
     //Nothing
  | {ctx->test == true}?
     SLSpace+ OtherText
  )
  ;

fragment SimpleIdent  : ('a'..'z' | 'A'..'Z' | '_')+;
fragment SLSpace    : ' ';
fragment OtherText :  (~'\n')* '\n';

ctx->testが false の場合、レクサーはこのルールを終了し、SimpleIdent の後のすべての文字を無視すると思います。残念ながら、ANTLR は述語がテストされる前に SimpleIdent の後に文字をテストするため、そこにスペースがある場合は常に 2 番目の選択肢が使用されます。これは、C コードで明確に示されています。

// X.g:10:3: ({...}?|{...}? ( SLSpace )+ OtherText )
{
    int alt2=2;
    switch ( LA(1) )
    {
    case '\t':
    case ' ':
        {
            alt2=2;
        }
        break;

    default:
        alt2=1;
    }

    switch (alt2)
    {
    case 1:
        // X.g:11:5: {...}?
        {
            if ( !((ctx->test != true)) )
            {
                    //Exception
            }

        }
        break;
    case 2:
        // X.g:13:5: {...}? ( SLSpace )+ OtherText
        {
            if ( !((ctx->test == true)) )
            {
                   //Exception
            }

ANTLR が実行時にレクサーで特定のパスを取るようにするにはどうすればよいですか?

4

1 に答える 1

2

検証セマンティック述語の代わりに、ゲーテッド セマンティック述語を使用します1。式が に検証された場合、検証述語は例外をスローします。そして、「代替手段なし」を最後に一致させます。 false

また、OtherText何とも一致しSLSpaceSLSpace+ OtherTextあいまいになります。単純に削除するか、 a 以外のものから始めSLSpace+ましょう。OtherText' '

私は C ターゲットにはあまり詳しくありませんが、この Java デモは C でも問題なく動作するはずです (もちろん、Java コードを翻訳した後)。

grammar T;

rules
 : RULE+ EOF
 ;

RULE
 : SimpleIdent {boolean flag = $SimpleIdent.text.startsWith("a");}
   ( {!flag}?=> OtherText
   |            // Nothing
   )
 ;

Spaces 
 : (' ' | '\t' | '\r' | '\n')+ {skip();}
 ;

fragment SimpleIdent : ('a'..'z' | 'A'..'Z' | '_')+;
fragment OtherText   : (~'\n')* '\n';

入力を解析する場合:

abcd efgh ijkl mnop
bbb aaa ccc ddd

次の解析が得られます。

ここに画像の説明を入力

RULEつまり、 a が小文字で始まる場合は常に"a"、行末​​まで一致しません。

1 ANTLR の「セマンティック述語」とは何ですか?

于 2012-08-07T07:57:24.750 に答える