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