Difference between revisions of "Antlr"
Jump to navigation
Jump to search
Line 12: | Line 12: | ||
=== Example === | === Example === | ||
+ | ==== Exp grammar ==== | ||
+ | <source lang='antlr4'> | ||
+ | /** | ||
+ | * Copyright 2016-2017 BITPlan GmbH | ||
+ | * Author: Wolfgang Fahl | ||
+ | * | ||
+ | * this is an Example Antlr Grammar | ||
+ | * | ||
+ | * | ||
+ | * it is specified using antlr syntax and uses the ANTLR V4 parser generator | ||
+ | * see http://www.antlr.org | ||
+ | * | ||
+ | * for Eclipse you might want to install the IDE support: | ||
+ | * https://github.com/jknack/antlr4ide | ||
+ | * | ||
+ | */ | ||
+ | grammar Exp; | ||
+ | /* This will be the entry point of our parser. */ | ||
+ | eval returns [double value] | ||
+ | : exp=additionExp {$value = $exp.value;} | ||
+ | ; | ||
+ | |||
+ | /* Addition and subtraction have the lowest precedence. */ | ||
+ | additionExp returns [double value] | ||
+ | : m1=multiplyExp {$value = $m1.value;} | ||
+ | ( '+' m2=multiplyExp {$value += $m2.value;} | ||
+ | | '-' m2=multiplyExp {$value -= $m2.value;} | ||
+ | )* | ||
+ | ; | ||
+ | |||
+ | /* Multiplication and division have a higher precedence. */ | ||
+ | multiplyExp returns [double value] | ||
+ | : a1=atomExp {$value = $a1.value;} | ||
+ | ( '*' a2=atomExp {$value *= $a2.value;} | ||
+ | | '/' a2=atomExp {$value /= $a2.value;} | ||
+ | )* | ||
+ | ; | ||
+ | |||
+ | /* An expression atom is the smallest part of an expression: a number. Or | ||
+ | when we encounter parenthesis, we're making a recursive call back to the | ||
+ | rule 'additionExp'. As you can see, an 'atomExp' has the highest precedence. */ | ||
+ | atomExp returns [double value] | ||
+ | : n=Number {$value = Double.parseDouble($n.text);} | ||
+ | | '(' exp=additionExp ')' {$value = $exp.value;} | ||
+ | ; | ||
+ | |||
+ | /* A number: can be an integer value, or a decimal value */ | ||
+ | Number | ||
+ | : ('0'..'9')+ ('.' ('0'..'9')+)? | ||
+ | ; | ||
+ | |||
+ | /* We're going to ignore all white space characters */ | ||
+ | WS | ||
+ | : (' ' | '\t' | '\r'| '\n') { | ||
+ | |||
+ | } | ||
+ | ; | ||
+ | </source> | ||
+ | |||
<source lang='java'> | <source lang='java'> | ||
/** | /** |
Revision as of 13:33, 14 October 2017
ANTLR is a parser generator tool.
BITPlan has been using ANTLR in projects for a few years now and Wolfgang Fahl has been active in improving ANTLR see e.g. #Motivation
Library with helpers for ANTLR Language development com.bitplan.antlr
To simplify Parser development with ANTLR BITPlan has created a library with some helper code for ANTLR Language Development and published it as Open Source at:
Base Class Language Parser
The abstract base class LanguageParser has some help code that makes language development and debugging easier.
Example
Exp grammar
/**
* Copyright 2016-2017 BITPlan GmbH
* Author: Wolfgang Fahl
*
* this is an Example Antlr Grammar
*
*
* it is specified using antlr syntax and uses the ANTLR V4 parser generator
* see http://www.antlr.org
*
* for Eclipse you might want to install the IDE support:
* https://github.com/jknack/antlr4ide
*
*/
grammar Exp;
/* This will be the entry point of our parser. */
eval returns [double value]
: exp=additionExp {$value = $exp.value;}
;
/* Addition and subtraction have the lowest precedence. */
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( '+' m2=multiplyExp {$value += $m2.value;}
| '-' m2=multiplyExp {$value -= $m2.value;}
)*
;
/* Multiplication and division have a higher precedence. */
multiplyExp returns [double value]
: a1=atomExp {$value = $a1.value;}
( '*' a2=atomExp {$value *= $a2.value;}
| '/' a2=atomExp {$value /= $a2.value;}
)*
;
/* An expression atom is the smallest part of an expression: a number. Or
when we encounter parenthesis, we're making a recursive call back to the
rule 'additionExp'. As you can see, an 'atomExp' has the highest precedence. */
atomExp returns [double value]
: n=Number {$value = Double.parseDouble($n.text);}
| '(' exp=additionExp ')' {$value = $exp.value;}
;
/* A number: can be an integer value, or a decimal value */
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
/* We're going to ignore all white space characters */
WS
: (' ' | '\t' | '\r'| '\n') {
}
;
/**
* example parser
* @author wf
*
*/
public class ExpLanguageParser extends LanguageParser {
private ExpParser parser;
ExpLexer lexer;
public ExpParser getParser() {
return parser;
}
@Override
protected ParseTree getRootContext(Parser parser) {
if (!(parser instanceof ExpParser)) {
throw new RuntimeException("wrong parser type for getRootContext, expected Rule but got "+parser.getClass().getName());
} else {
ExpParser expParser=(ExpParser) parser;
return expParser.eval();
}
}
@Override
protected ParseTree parse(ANTLRInputStream in, String inputText)
throws Exception {
lexer = new ExpLexer(in);
parser=new ExpParser(getTokens(lexer));
ParseTree result=super.parse(lexer,getParser());
return result;
}
@Override
public void showParseTree() {
super.showParseTree(getParser());
}
}