Monday, March 17, 2014

Antlr + StringTemplate

  • Antlrworks is not good tool. It does not support semantic predicates.
  • The documentation for using Antlr together with StringTemplate is not good enough.
  • There are many ways to improve error reporting. A quick fix would be to override emitErrorMessage(String message) in the parser class and simply throw an exception with the provided message:

grammar T;
@members {
@Override
public void emitErrorMessage(String message) {
throw new RuntimeException(message);
}
}
definition
: '(' 'define' ( '(' variable def_formals ')' body ')'
| variable expression ')'
)
;
def_formals
: variable* ('.' variable)?
;
body
: ((definition)=> definition)* expression+
;
expression
: INT
;
variable
: ID
;
ID : 'a'..'z'+;
INT : '0'..'9';
SPACE : ' ' {skip();};
view raw gistfile1.g4 hosted with ❤ by GitHub
which you can test with the class:

import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) {
String[] tests = {
"(define x 5)",
"(define x 5))",
"(define x)",
"(define)"
};
for(String input : tests) {
TLexer lexer = new TLexer(new ANTLRStringStream(input));
TParser parser = new TParser(new CommonTokenStream(lexer));
System.out.println("\nParsing : " + input);
try {
parser.definition();
} catch(Exception e) {
System.out.println(" exception -> " + e.getMessage());
}
}
}
}
view raw gistfile1.java hosted with ❤ by GitHub



After running the class above, you will see the following:

bart@hades:~/Programming/ANTLR/Demos/T$ java -cp antlr-3.3.jar org.antlr.Tool T.g

bart@hades:~/Programming/ANTLR/Demos/T$ javac -cp antlr-3.3.jar *.java

bart@hades:~/Programming/ANTLR/Demos/T$ java -cp .:antlr-3.3.jar Main

Parsing : (define x 5)
Parsing : (define x 5))
Parsing : (define x)
exception -> line 1:9 missing INT at ')'
Parsing : (define)
exception -> line 1:7 no viable alternative at input ')'
As you can see, the input (define x 5)) produces no exception! That is because the lexer has no problems with it (they're all valid tokens) and the parser is simply instructed to consume the definition rule:

definition

: '(' 'define' ( '(' variable def_formals ')' body ')'

| variable expression ')'

) ;
which it does. If you wanted an error because of the dangling ')', then you'd have the add the EOF token at the end of the rule:

definition

: '(' 'define' ( '(' variable def_formals ')' body ')'

| variable expression ')'

)

EOF;


No comments:

Post a Comment