2

こんにちは私は与えられた入力に基づいて真または偽のブール式を返すjavaまたはC#メソッドを実行したいです。例:ANTLRコモンツリーが正しいかどうかを確認するか、入力がANTLR文法に一致するかどうかをチェックする方法?

if(入力がantlr文法と一致する場合) return true; else falseを返します。 問題は、私は、どのようにmontatchetokenがあるかどうかを確認する方法を知っていません。私は木を横切ろうとしましたが、樹木のノードとしてミスマッチトークンを与えませんでした。おそらく問題は、ASTがパーズツリーだけの不一致のトークンを表示しないことです。誰かがパーサーをパーサーから取得する方法を教えても助けになるでしょうか?

私は次の操作を行う必要がある今、私はANTLR .Gファイルを行っている、それは良い作品:私は入力が正しかったかどうかをチェックする必要があるが、私はこれを行っているが、それは仕事をdoesntの:

public static boolean check() { 
    String file = "test.txt"; 
    ANTLRReaderStream input; 
    try{ 

      input = new ANTLRReaderStream(new FileReader(file)); 
      regExLexer lexer = new regExLexer(input); 
      CommonTokenStream tokens = new CommonTokenStream(lexer); 
      regExParser parser = new regExParser(tokens); 

      CommonTree root = (CommonTree)parser.goal().getTree(); 

     return true;} 
catch{ 
return false;} 
} 

私のメソッドからは、入力文字列が正しい場合にのみtrueを返します。そうでない場合はfalseを返します。私が行っている方法は、それは常にtrueを返しますが、文字列は、それが

印刷し正しくない場合:コンソールの

を「ライン1 EOF期待し4余分な入力 『+』」を。

答えて

1

私はあなたの質問の下のコメントで示唆したよう:this previous Q&Aは、あなたの質問に答えます。私は例を使ってデモンストレーションします。

数字を受け入れる(そしてスペースを無視する)文法があるとします。パーサーとレクサーの両方をオーバーライドするだけで、そのメソッドで例外をスローする必要があります。パーザ(またはレクサー)は続行しません。エラーをキャッチしてヘルパーメソッドでfalseを返すだけです。

今クラスを実行している
grammar T; 

@parser::members { 

    public static boolean matches(String input) { 
    try { 
     TLexer lexer = new TLexer(new ANTLRStringStream(input)); 
     TParser parser = new TParser(new CommonTokenStream(lexer)); 
     parser.parse(); 
     return true; 
    } catch(Exception e) { 
     return false; 
    } 
    } 

    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException(e); 
    } 
} 

@lexer::members { 
    @Override 
    public void reportError(RecognitionException e) { 
    throw new RuntimeException(e); 
    } 
} 

parse 
: NUMBER* EOF 
; 

NUMBER : '0'..'9'+; 
SPACE : ' ' {skip();}; 

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    System.out.println(TParser.matches("")); 
    System.out.println(TParser.matches("1 234 42")); 
    System.out.println(TParser.matches("12 556 f")); 
    } 
} 

を印刷します:答えのための

true 
true 
false 
+0

ありがとう、とてもよかったです。今私はもう1つ質問します。私の文法は、例えばこの文字列a * bを受け入れますが、** bを受け入れません。この部分はうまくいきますが、言語の一部ではない文字列を追加すると、例外がスローされますが、例えばa * b_のように真を返します。この場合、 '_'は私の言語の一部ではありません。任意の提案 – sm13294

+0

ああ、私のレクサーに@Overrideを追加するのを忘れた。どうもありがとうございました。 – sm13294

0

ANTLRはあなたに馴染みのない人にとっては痛みを感じるかもしれないいくつかのエラー(親切な覚えがないなど)を親切に回復します。

必要に応じて、regExParserクラスのBaseRecognizer.recoverFromMismatchedTokenをオーバーライドし、常に不一致トークンが見つかった場合に例外をスローすることができます。

参考:

ANTLR: error recovery and reporting

+0

おかげで、私は、そのクラスをオーバーライドすることにより、私はカスタムエラーを表示するように実現すると思う、それはあります私が必要とするものではありません。私はちょうどエラーが発生したときに知っておく必要があります(何らかのエラーが発生しました)このようなことをしたいと思います:if(エラーが発生します){do smth} else {do smth else}エラーが発生しました。 .gファイルで指定されていますか? – sm13294

関連する問題