Подразделы

Другие разделы

Дата и время

05/05/2024 06:50:42

Авторизация

Имя:
Пароль:
Зарегистрироваться
Восстановить пароль
 

printПримеры для средств разработки трасляторов

printANTLR

Пример калькулятора на ANTLR.
LabeledExpr.g4:
grammar LabeledExpr; 
prog:   stat+ ;
stat:   expr NEWLINE                # printExpr
    |   ID '=' expr NEWLINE         # assign
    |   NEWLINE                     # blank
    ;
expr:   expr op=('*'|'/') expr      # MulDiv
    |   expr op=('+'|'-') expr      # AddSub
    |   INT                         # int
    |   ID                          # id
    |   '(' expr ')'                # parens
    ;

MUL :   '*' ; // Назначение имен токенам
DIV :   '/' ;
ADD :   '+' ;
SUB :   '-' ;
ID  :   [a-zA-Z]+ ;      
INT :   [0-9]+ ;         
NEWLINE:'\r'? '\n' ;     
WS  :   [ \t]+ -> skip ; // Пропуск пробельных символов
Calc.java:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import java.io.FileInputStream;
import java.io.InputStream;

public class Calc {
    public static void main(String[] args) throws Exception {
        InputStream is = System.in;
        if ( args.length>0 ) is = new FileInputStream(args[0]);

        ANTLRInputStream input = new ANTLRInputStream(is);
        LabeledExprLexer lexer = new LabeledExprLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        LabeledExprParser parser = new LabeledExprParser(tokens);
        ParseTree tree = parser.prog(); 
        EvalVisitor eval = new EvalVisitor();
        eval.visit(tree);
    }
}
EvalVisitor.java:
import java.util.HashMap;
import java.util.Map;

public class EvalVisitor extends LabeledExprBaseVisitor<Integer> {
    // Память для хранения значений
    Map<String, Integer> memory = new HashMap<String, Integer>();
    private Integer eval(Integer left, Integer op, Integer right)
    { switch(op) {
      case LabeledExprParser.MUL: return left*right;
      case LabeledExprParser.DIV: return left/right;
      case LabeledExprParser.ADD: return left+right;
      case LabeledExprParser.SUB: return left-right;
      }
    }
    @Override // ID '=' expr NEWLINE
    public Integer visitAssign(LabeledExprParser.AssignContext ctx) {
       memory.put(ctx.ID().getText(), visit(ctx.expr()));
       return 0;
    }
    @Override // expr NEWLINE 
    public Integer visitPrintExpr(LabeledExprParser.PrintExprContext ctx) {
       System.out.println(visit(ctx.expr())); 
       return 0;                          
    }
    @Override // INT 
    public Integer visitInt(LabeledExprParser.IntContext ctx) {
       return Integer.valueOf(ctx.INT().getText());
    }
    @Override // ID 
    public Integer visitId(LabeledExprParser.IdContext ctx) {
       String id = ctx.ID().getText();
       if ( memory.containsKey(id) ) return memory.get(id);
       return 0;
    }
    @Override // expr op=('*'|'/') expr
    public Integer visitMulDiv(LabeledExprParser.MulDivContext ctx) {
       return eval(visit(ctx.expr(0)), ctx.op.getType(), visit(ctx.expr(1))); 
    }
    @Override // expr op=('+'|'-') expr
    public Integer visitAddSub(LabeledExprParser.AddSubContext ctx) {
       return eval(visit(ctx.expr(0)), ctx.op.getType(), visit(ctx.expr(1))); 
    }
    @Override // '(' expr ')' 
    public Integer visitParens(LabeledExprParser.ParensContext ctx) {
       return visit(ctx.expr());
    }
}
loading