2017-02-14 6 views
3

Antlr 3.5の文法でJava解析を行っている間に、 'IDENTIFIER'ルールはANTLR Lexer文法でキーワードをほとんど消費しません。 ' - > IDENTIFIER VAR_VALUE' はまた、望ましくない"この"キーワードを、消費し、次にルール'IDENTIFIER'ルールはANTLR Lexer文法でキーワードも消費します

public final int inch = this.getValue(); 

:私は行を解析しようとするとレクサー文法は

lexer grammar JavaLexer; 

options { 
    //k=8; 
    language=Java; 
    filter=true; 
    //backtrack=true; 
} 

@lexer::header { 
package java; 
} 

@lexer::members { 
public ArrayList<String> keywordsList = new ArrayList<String>(); 
} 

V_DECLARATION 
: 
(((MODIFIERS)=>tok1=MODIFIERS WS+)? tok2=TYPE WS+ var=V_DECLARATOR WS*) 
{...}; 

fragment 
V_DECLARATOR 
    : 
    (
    tok=IDENTIFIER WS* (',' | ';' | ASSIGN WS* V_VALUE) 
) 
    {...}; 

fragment 
V_VALUE 
: (IDENTIFIER (DOT WS* IDENTIFIER WS* '(' | ',' | ';')) 
; 

MODIFIERS 
    : 
    (PUBLIC | PRIVATE | FINAL)+ 
; 

PRIVATE 
    : tok = 'private' 
    { keywordsList.add($tok.getText()); } 
    ; 

PUBLIC 
    : tok = 'public' 
    { keywordsList.add($tok.getText()); } 
    ; 

DOT 
    : '.' 
    { keywordsList.add("."); } 
    ; 

THIS 
    : tok = 'this' 
    { keywordsList.add($tok.getText()); } 
    ; 

ASSIGN 
    : '=' 
     { keywordsList.add("="); } 
    ;  

IDENTIFIER: 
    tok =Identifier 
    { 
    //System.out.println("Identifier: " + $tok.text); 
    } 
    ; 

fragment 
Identifier 
    : (Letter (Letter|JavaIDDigit)*); 

fragment 
Letter 
    : '\u0024' | 
     '\u0041'..'\u005a' | 
     '\u005f' | 
     '\u0061'..'\u007a' | 
     '\u00c0'..'\u00d6' | 
     '\u00d8'..'\u00f6' | 
     '\u00f8'..'\u00ff' | 
     '\u0100'..'\u1fff' | 
     '\u3040'..'\u318f' | 
     '\u3300'..'\u337f' | 
     '\u3400'..'\u3d2d' | 
     '\u4e00'..'\u9fff' | 
     '\uf900'..'\ufaff' 
    ; 

fragment 
JavaIDDigit 
    : '\u0030'..'\u0039' | 
     '\u0660'..'\u0669' | 
     '\u06f0'..'\u06f9' | 
     '\u0966'..'\u096f' | 
     '\u09e6'..'\u09ef' | 
     '\u0a66'..'\u0a6f' | 
     '\u0ae6'..'\u0aef' | 
     '\u0b66'..'\u0b6f' | 
     '\u0be7'..'\u0bef' | 
     '\u0c66'..'\u0c6f' | 
     '\u0ce6'..'\u0cef' | 
     '\u0d66'..'\u0d6f' | 
     '\u0e50'..'\u0e59' | 
     '\u0ed0'..'\u0ed9' | 
     '\u1040'..'\u1049' 
    ; 

WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN; skip();} 
    ; 

ですキーワードは別のリストにも収集されるためです。

Antlr文法では、 "IDENTIFIER"のような他の機能に影響を与えずに、キーワード自体を一致させるためのトリック/プロビジョニングはありますか?

+0

オプション '** {backtrack = true;}' **を試しましたが、結果はありません。 – Kishore

+2

ルールV_DECLARATION、V_DECLARATOR、V_VALUEは、レクサーではなくパーサに属しています。 –

+0

@Maurice Perryは、特定のトークンと一致する非常に基本的なレクサールールであり、さまざまなルールで完全なJava文法を含むパーサーをトリガーします。 – Kishore

答えて

3

あなたの問題は確かにレクサーに属するものの誤解によって引き起こされ、何がパーサに属する:

  • レクサーの仕事は、文字のストリームを表す言葉を決定することです
    • 例えばそのthis0NUMBERthatパーサのジョブが「文章」とからなるかどうか、つまり、レクサーから放出されたワードのシーケンスが所与の言語に適合するかどうかを決定することであるIDENTIFIER
  • であり、THISありますそれらの言葉は意味をなさない
    • その宣言が可能修飾子、タイプ、およびレクサーの仕事は、入力上にあるどの言葉を決定することです

ので、識別子のリストで構成され、それは入力を処理し、最長有効探しmatch(ANTLRでは、2つ以上のルールが同じ入力を受け入れる場合、ソース文法の最上位のものが優先されます)。 「最も特化した」ものではなく、単に最も長いものです。

例:

  • 入力t
    • は指定できTHISまたはIDENTIFIER
  • 入力h
    • まだできTHISまたはIDENTIFIER
  • 入力a
    • はもはやTHISになることはできません、唯一のIDENTIFIERが可能です
  • 確認
  • 入力用の入力t
    • IDENTIFIER.
      • はもはやIDENTIFIERと一致しないので、thatIDENTIFIERとして一致され、最後の入力.は、次のトークン

    の新しい開始し、別の例として、照合されます。

    • 入力t,h,i,sいうよりもどちらかTHISまたはIDENTIFIER全体の時間
  • 入力.
    • は、もはや何もによって一致することはできないので、thisTHISと照合されます(一番上のマッチングルール)として
      • を一致させることができますIDENTIFIER.は新しいトークンを開始します

    そして今、重要な部分に - は、レクサールールが別のレクサールールから参照されている限り、参照するレクサールールの単なるフラグメントとみなされます。つまり、マッチすると新しいトークンは生成されず、フラグメントのマッチの終わりに複数のマッチするトークン間で決定がトリガーされません。 thisが実際IDENTIFIERルールで一致させることができるので、全体の宣言はV_DECLARATIONレクサールールに準拠 - そう入力の少なくとも同一の長さは、以前の文法では、このルールより一致させることができる別のレクサールールがありますがない限り、この規則が適用されます。

    THISを参照するルールを指定していないため、文法でどのくらい正確に再生されているのかわからないのですが、明らかな原因は、より長い入力または以前のルールと一致する可能性があります。

  • 関連する問題