3

Hi I want to do a java or c# method which will return a boolean expression true or false based on the given input. For example:

if (input matches the antlr grammar) return true; else return false; So the problem is i dont know how to check if the commontree have any mismatchetoken. I tried to traverse the tree but it doesnt give any mismatchetoken as node of the tree. Probably the problem is that the AST doesnt show the mismatched tokens only the parse tree. It could be help also if someone tell me how get the parsetree from parser?

I have done the ANTLR .g file and it works good, now I need to do the following: i have to check if the input was correct or not, I have done this but it doesnt work:

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

So i expect from my method to return true only when the input string is correct, and false otherwise. The way I have done it always returns true, but when the string is not correct it prints

"line 1:4 extraneous input '+' expecting EOF"

in console.

sm13294
  • 563
  • 7
  • 23

2 Answers2

1

As I hinted in the comments under your question: this previous Q&A answers your question. I'll demonstrate with an example.

Let's say you have a grammar that accepts numbers (and ignores spaces). You only need to override both the parser's- and the lexer's reportError and throw an exception in that method: that way the parser (or lexer) will not continue. Catch the error and simply return false in a static helper method.

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

Now running the class:

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

will print:

true
true
false
Community
  • 1
  • 1
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Thank you, it was very good. Now I one more question. My grammar accepts for example this string a*b but doesnt accept a**b, this part works well, but when i add a string which is not part of language it throws an exception but returns true for example a*b_. In this case '_' is not part of my language. Any suggestion – sm13294 Feb 23 '12 at 18:29
  • Oh i forgot to add the @Override in my lexer. thank you very much. – sm13294 Feb 23 '12 at 18:31
0

ANTLR kindly recovers some errors (like missing an obvious stoken) for you, which may be a pain if you are not familiar with it.

If you like, you can override BaseRecognizer.recoverFromMismatchedToken in regExParser class and always throws an exception is a mismatched token is found.

Reference:

ANTLR: error recovery and reporting

Community
  • 1
  • 1
Lex Li
  • 60,503
  • 9
  • 116
  • 147
  • thanks for the answer, but I think by overriding that class I will achieve to show custom errors, that is not what I need. I just need to know when an error occurs (any error) i want to do something like this: if(error occurs){do smth} else {do smth else} by error occurs I mean checking if the given input match the antlr grammar specified in .g file? – sm13294 Feb 23 '12 at 14:21