2016-10-12 4 views
0

私はANTLRの完全な新人です。ANTLR解析で正しいレクサー部分が見つかりません

私は、次のANTLRの文法があります

grammar DrugEntityRecognition; 

// Parser Rules 

derSentence : ACTION (INT | FRACTION | RANGE) FORM TEXT; 

// Lexer Rules 

ACTION : 'TAKE' | 'INFUSE' | 'INJECT' | 'INHALE' | 'APPLY' | 'SPRAY' ; 

INT : [0-9]+ ; 

FRACTION : [1] '/' [1-9] ; 

RANGE : INT '-' INT ; 

FORM : ('TABLET' | 'TABLETS' | 'CAPSULE' | 'CAPSULES' | 'SYRINGE') ; 

TEXT : ('A'..'Z' | WHITESPACE | ',')+ ; 

WHITESPACE : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ -> skip ; 

をそして私が文を解析しようとすると、次のように:

String upperLine = line.toUpperCase(); 
org.antlr.v4.runtime.CharStream stream = new ANTLRInputStream(upperLine); 
DrugEntityRecognitionLexer lexer = new DrugEntityRecognitionLexer(stream); 
lexer.removeErrorListeners(); 
lexer.addErrorListener(ThrowingErrorListener.INSTANCE); 

CommonTokenStream tokenStream = new CommonTokenStream(lexer); 
DrugEntityRecognitionParser parser = new DrugEntityRecognitionParser(tokenStream); 

try { 
     DrugEntityRecognitionParser.DerSentenceContext ctx = parser.derSentence(); 

     StringBuilder sb = new StringBuilder(); 

     sb.append("ACTION: ").append(ctx.ACTION()); 
     sb.append(", "); 
     sb.append("FORM: ").append(ctx.FORM()); 
     sb.append(", "); 
     sb.append("INT: ").append(ctx.INT()); 
     sb.append(", "); 
     sb.append("FRACTION: ").append(ctx.FRACTION()); 
     sb.append(", "); 
     sb.append("RANGE: ").append(ctx.RANGE()); 

     System.out.println(upperLine); 
     System.out.println(sb.toString()); 

    } catch (ParseCancellationException e) { 
     //e.printStackTrace(); 
    } 

レクサーへの入力の例:

take 10 Tablet (25MG) by oral route every week 

この場合、ACTIONノードにはデータが入力されませんが、takeはTEXTノードであり、ACTIONノードではありません。ただし、10はINTノードとして認識されています。

この文法を正しく動作させるにはどうすればよいですか?ACTIONノードには正しく入力されます(FORMも入力されません)。

答えて

1

はあなたの文法上のいくつかの問題があります

  1. あなたのTEXTルールのみ大文字に一致します。 ACTIONと同じです。
  2. 単一のテキストルール(ここではカンマ)に句読点とテキストを混同しないでください。そうしないと、トークン間の空白を自由に指定できなくなります。
  3. 括弧はまったく一致しないため、(25MG)は有効ではなく、パーサーはエラー状態に戻ります。
  4. 認識エラーの原因を確認するために、構文エラーがないかどうかを確認しませんでした。

また、疑わしいときは、トークンソースからトークンシーケンスを出力して、実際に入力が実際にトークン化されているかどうかを確認してください。パーサーに行く前に文法を修正してください。いずれの場合に文字を一致して、そのキーワードを定義するための

fragment A: [aA]; 
fragment B: [bB]; 
fragment C: [cC]; 
fragment D: [dD]; 
... 

ACTION : T A K E | I N F U S E | I N J E C T | I N H A L E | A P P L Y | S P R A Y; 
を一般的に(あなたの言語では大文字と小文字を区別しない場合)あなたはこのような規則があります。大文字と小文字の区別について

+0

1.レクサーを実行する前に文を大文字に変換します。 2.ありがとう、私はそれを変更し、それがどうなるか見る。 3.どのように括弧をマッチさせるべきですか? 4.同じですが、構文エラーを確認する方法はありますか。また、トークンソースからトークンシーケンスを出力して、期待どおりにトークン化されているかどうかを確認するにはどうすればよいですか?繰り返しますが、ここでは初心者を完全に - 私は具体的な助けが必要です。 – daniel0mullins

+0

カッコの部分は、それに一致する別のルールを作成します。 '投薬量:'( 'INT(' M '|'μ ')' G '') ';または類似のもの、おそらくオプションの部分。トークンリストは簡単に入手できます。あなたのトークンストリームとその 'getTokens()'メソッドを参照してください。 ANTLRランタイムのほとんどのクラスは、いくつかの情報を出力するために使用できるtoString()メソッドを持っています。エラーの場合、Parser.getNumberOfSyntaxErrors()を使用することができますが、実際のエラー処理はもう少し(独自のエラーリスナーを使用して)機能します。これは、独自の質問で処理する必要があります。 –

関連する問題