compiler construction - ANTLR4: grammar for arithmetic expression - division by zero check, keywords check -
i need grammar arithmetic expressions.
i notify user error message if tries divide 0 or if use vhdl keywords (target language) variable name.
but new antlr , cant figure out how extend grammar:
grammar arithmetic; @header { package generated; } stat : left = variable op = assigment right = expr # assigment ; expr : '(' exp = expr ')' # parens | minus exp = expr # unaryminus | left = expr op = (times | div) right = expr # muldiv | left = expr op = (plus | minus) right = expr # addsub | (variable | constant) # element ; assigment : '=' ; plus : '+' ; minus : '-' ; times : '*' ; div : '/' ; lparen : '(' ; rparen : ')' ; variable : (letter+|digit+|'_')+ ; constant : integer ; integer : digit+ ; letter : ('a' .. 'z') | ('a' .. 'z') ; digit : ('0' .. '9') ; ws : [ \r\n\t] + -> skip ;
i found numerous small problems have corrected in grammar below.
- no eof marker
- could run 1 statement extended
program - the @header thing causes java grungui not run
_valid variable name, not want.'5' valid left-hand-side of assignment.
5=6valid assignment statement, again, not want.grammar arithmetic; program : stat+ eof; stat : left = variable op = assigment right = expr # assigment ; expr : '(' exp = expr ')' # parens | minus exp = expr # unaryminus | left = expr op = (times | div) right = expr # muldiv | left = expr op = (plus | minus) right = expr # addsub | (variable | constant) # element ; assigment : '=' ; plus : '+' ; minus : '-' ; times : '*' ; div : '/' ; lparen : '(' ; rparen : ')' ; variable : letter+(letter|digit|'_')* ; constant : integer ; integer : digit+ ; letter : ('a' .. 'z') | ('a' .. 'z') ; digit : ('0' .. '9') ; ws : [ \r\n\t] + -> skip ;
now corrects lot of lexing , "good form" issues. next question about, example, division zero.
the grammar not place enforce such rules. example, 3/0 legal mathematical expression. happens evaluate infinity, , therefore guarded against in program. likewise, should handle special cases in code. implementing visitor or listener pattern when right-hand-side of #muldiv context equal zero, should intervene @ point. grammar no place trying implement such sophisticated semantic , context-sensitive rules.
as how program if statement, i'll give peek @ way implement them:
public override muvalue visitifstmt(lisbasicparser.ifstmtcontext context) { lisbasicparser.condition_blockcontext[] conditions = context.condition_block(); bool evaluatedblock = false; foreach (lisbasicparser.condition_blockcontext condition in conditions) { muvalue evaluated = visit(condition.expr()); if (evaluated.asboolean()) { evaluatedblock = true; visit(condition.stmt_block()); break; } } if (!evaluatedblock && context.stmt_block() != null) { visit(context.stmt_block()); } return muvalue.void; } granted, doesn't make sense out of context, rest assured works. see in full context, please visit bart kiers excellent example of grammar , implementation .
Comments
Post a Comment