Font size:
Dotted grammar for simple expressions
header
{%
#include <ctype.h>
%}
grammar ExprParser
{
terminals
PLUS MIN
MUL DIV
NUM
LP RP
EOL SEMI
nonterminals
loop
begin
expr _expr
term _term
factor
syntaxerror
type int
start begin
error syntaxerror
principles
.begin: .expr loop
;
.loop : .EOL
| .SEMI expr loop
;
expr.loop: . loop {% cout << "\nResult: " << lhsAttr(-1) << endl; %}
;
.expr: .term _expr
;
term._expr: expr. PLUS term _expr {% attr(-1) = lhsAttr(-1); %}
| expr.MIN term _expr {% attr(-1) = lhsAttr(-1); %}
| expr. {% attr(-1) = lhsAttr(-1); %}
;
expr PLUS term._expr: term._expr {% attr(-1) = lhsAttr(-3) + lhsAttr(-1); %} ;
expr MIN term. _expr: term._expr {% attr(-1) = lhsAttr(-3) - lhsAttr(-1); %} ;
.term: .factor _term
;
factor._term: term. MUL factor _term {% attr(-1) = lhsAttr(-1); %}
| term. DIV factor _term {% attr(-1) = lhsAttr(-1); %}
| term. {% attr(-1) = lhsAttr(-1); %}
;
term MUL factor._term: factor._term {% attr(-1) = lhsAttr(-3) * lhsAttr(-1); %}
;
term DIV factor._term: factor._term {% attr(-1) = lhsAttr(-3) / lhsAttr(-1); %}
;
.factor: .LP expr RP factor
| .NUM factor
;
LP expr RP. factor: factor. {% attr(-1) = lhsAttr(-2); %}
;
NUM. factor : factor. {% attr(-1) = lhsAttr(-1); %}
;
. syntaxerror :
{% cout << "\nerror : Nonterminal :<" << getSymbolName(lhsToken(-1))
<< "> Lookahead symbol <" << GetSymbolName(lookAhead())
<< ">" << endl; popL(1);
%}
;
{%
public:
void parse()
{
run();
}
%}
}
source
{%
void ExprParser::getToken(Symbol<int> &a)
{
char c;
cin >> c;
if (isdigit(c))
{
a.id = NUM;
a.attr = c - '0';
return;
}
switch(c)
{
case '/' : a.id = DIV; break;
case '*' : a.id = MUL; break;
case '+' : a.id = PLUS; break;
case '-' : a.id = MIN; break;
case '(' : a.id = LP; break;
case ')' : a.id = RP; break;
case ';' : a.id = SEMI; break;
case '.' : a.id = EOL; break;
default: a.id = 0;
}
a.attr = 0;
}
%}

