2

안녕하세요, 주어진 입력을 기반으로 부울 식 true 또는 false를 반환합니다 자바 또는 C# 메서드를 할 싶어요. 예 :ANTLR 커먼 트리가 올바른지 확인하십시오. 또는 주어진 입력이 ANTLR 문법과 일치하는지 확인하는 방법?

if (입력이 antlr 문법과 일치) return true; else false를 반환합니다. 그래서 문제는 내가 어떻게 montatchetoken을 가지고 있는지 확인하는 방법을 알고있다. 나는 나무를 가로 지르려고했으나 어떤 미스 매치 토큰을 그 나무의 노드로주지 않았다. 아마도 문제는 AST가 파스 트리 만 일치하지 않는 토큰을 표시하지 않는다는 것입니다. 누군가 파서로부터 parsetree를 얻는 방법을 말해 준다면 도움이 될 수 있습니까?

내가 ANTLR · G 파일을 수행하고 그것을 잘 작동합니다, 지금은 다음을 수행해야합니다

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를 반환합니다. 난 항상 그것을 짓을하는 방법은 사실 반환하지만 문자열이없는 경우는

인쇄 수정 "행 1 : 4 외부 입력 '+'EOF 기대"콘솔

.

답변

1

내가 질문 아래의 의견에 암시로 : this previous Q&A 귀하의 질문에 대답을 제공합니다. 예를 들어 설명해 보겠습니다.

숫자를 허용하고 공백을 무시하는 문법이 있다고 가정 해 보겠습니다. 파서와 렉서의 reportError을 모두 재정의하고 해당 메서드에서 예외를 throw하면됩니다. 파서 (또는 렉서)가 계속 진행되지 않습니다. 오류를 잡아 static 도우미 메서드에서 false을 반환하면됩니다.

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")); 
    } 
} 

가 인쇄됩니다 :

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();}; 

지금 클래스를 실행하는 대답을

true 
true 
false 
+0

고맙습니다. 아주 좋았습니다. 이제 나는 하나 더 질문한다. 내 문법은 예를 들어이 문자열 a * b를 받아들이지 만 ** b를 받아 들일 수는 없지만이 부분은 잘 작동하지만 언어의 일부가 아닌 문자열을 추가하면 예외가 발생하지만 예를 들어 a * b_를 반환합니다. 이 경우 '_'은 제 언어의 일부가 아닙니다.어떤 제안 – sm13294

+0

오, 내 렉서에 @Override를 추가하는 것을 잊어 버렸습니다. 고마워요. – sm13294

0

ANTLR은 당신에게 익숙하지 않은 경우 고통 스러울 수있는 약간의 오류 (예 : 분명한 스턴)를 친절하게 복구합니다.

원하는 경우 regExParser 클래스의 BaseRecognizer.recoverFromMismatchedToken을 무시하고 일치하지 않는 토큰이 발견되면 항상 예외를 throw합니다.

참조 :

ANTLR: error recovery and reporting

+0

감사합니다,하지만 난 사용자 지정 오류를 보여 달성 할 클래스를 재정 의하여 생각, 즉 내가 필요로하는 것이 아닙니다. (오류가 발생했을 때) 다음과 같이하고 싶습니다. if (오류가 발생했습니다) {do smth} else {else smeth else} 오류가 발생했습니다. 주어진 입력이 antlr 문법과 일치하는지 확인하는 것을 의미합니다. .g 파일에 지정 되었습니까? – sm13294