ANTLR 4如何处理一元/负数

编程入门 行业动态 更新时间:2024-10-13 14:27:59
本文介绍了ANTLR 4如何处理一元/负数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试使用Antlr 4设置一个简单的计算器.

I'm trying to setup a simple calculator with Antlr 4.

语法:

grammar calcGrammar; input : expression EOF; expression : MINUS expression #unaryMinusExpr | expression op=(MULTIPLY | DIVIDE) expression #multiplicationExpr | expression op=(MINUS | ADD) expression #additiveExpr | NUMBER #num ; NUMBER : [0-9]+ ; DOUBLE : NUMBER '.' NUMBER; LPAR : '('; RPAR : ')'; ADD : ('+'); MINUS : ('-'); DIVIDE : ('/'); MULTIPLY : ('*');

Java代码:

public class Listener extends ListenerBaseVisitor { @Override public Object visitUnaryMinusExpr(ArithmeticGrammarParser.UnaryMinusExprContext ctx) { System.out.println(ctx.children.get(0).getText()); } @Override public Object visitAdditiveExpr(ArithmeticGrammarParser.AdditiveExprContext ctx) { System.out.println(ctx.children.get(0).getText()); System.out.println(ctx.children.get(1).getText()); }

如果我的输入是2--2.输入的代码永远不会进入此方法.请注意,输入具有负一元运算符,应将其视为"-2".当我在该方法中放置调试点时,永远不会进入.

If my input is 2 - -2. The code will never go into this method with this input. Notice that the input has a negative unary operator, this should be perceived as '-2'. When i put a debug point in the method is never enters.

使用我的语法设置时,不应该总是总是考虑一进制减号吗?

With my grammar setup should it not be the case that it should always take into consideration the unary minus first?

似乎同时执行一元和令人上瘾的表达式时,会出现此错误.在这种情况下,输入'2--2'时,程序将不会进入一元方法

It seems that this error arises when both unary and addictive expressions are implemented. The program will not go into the unary method in this case with input '2 - -2'

推荐答案

使用我的语法设置时,不是应该总是先考虑一元减号吗?

With my grammar setup should it not be the case that it should always take into consideration the unary minus first?

是的,它应该(而且确实如此).

Yes, it should (and it does).

我猜您最近没有重新生成解析器和词法分析器类,因为给定您的语法(我只添加了SPACE : [ \t\r\n] -> skip;),当我运行此类时:

I'm guessing you didn't regenerate your parser and lexer classes recently, because given your grammar (I only added SPACE : [ \t\r\n] -> skip;), when I run this class:

import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTreeWalker; public class Main { static class Listener extends calcGrammarBaseListener { @Override public void enterUnaryMinusExpr(calcGrammarParser.UnaryMinusExprContext ctx) { System.out.println("enterUnaryMinusExpr: " + ctx.getText()); } @Override public void enterAdditiveExpr(calcGrammarParser.AdditiveExprContext ctx) { System.out.println("enterAdditiveExpr: " + ctx.getText()); } } public static void main(String[] args) { String source = "2 - -2"; calcGrammarLexer lexer = new calcGrammarLexer(CharStreams.fromString(source)); calcGrammarParser parser = new calcGrammarParser(new CommonTokenStream(lexer)); ParseTreeWalker.DEFAULT.walk(new Listener(), parser.input()); } }

打印以下内容:

enterAdditiveExpr: 2--2 enterUnaryMinusExpr: -2

对于访问者,您需要实施所有访问方法,如下所示:

For a visitor, you'll need to implement all your visit-methods like this:

import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; public class Main { static class Visitor extends calcGrammarBaseVisitor<Integer> { @Override public Integer visitInput(calcGrammarParser.InputContext ctx) { System.out.println("visitInput: " + ctx.getText()); return visit(ctx.expression()); } @Override public Integer visitUnaryMinusExpr(calcGrammarParser.UnaryMinusExprContext ctx) { System.out.println("visitUnaryMinusExpr: " + ctx.getText()); return -1 * visit(ctx.expression()); } @Override public Integer visitNum(calcGrammarParser.NumContext ctx) { System.out.println("visitNum: " + ctx.getText()); return Integer.parseInt(ctx.getText()); } @Override public Integer visitMultiplicationExpr(calcGrammarParser.MultiplicationExprContext ctx) { System.out.println("visitMultiplicationExpr: " + ctx.getText()); if (ctx.op.getType() == calcGrammarLexer.MULTIPLY) { return visit(ctx.expression(0)) * visit(ctx.expression(1)); } return visit(ctx.expression(0)) / visit(ctx.expression(1)); } @Override public Integer visitAdditiveExpr(calcGrammarParser.AdditiveExprContext ctx) { System.out.println("visitAdditiveExpr: " + ctx.getText()); if (ctx.op.getType() == calcGrammarLexer.ADD) { return visit(ctx.expression(0)) + visit(ctx.expression(1)); } return visit(ctx.expression(0)) - visit(ctx.expression(1)); } } public static void main(String[] args) { String expression = "2 - -2"; calcGrammarLexer lexer = new calcGrammarLexer(CharStreams.fromString(expression)); calcGrammarParser parser = new calcGrammarParser(new CommonTokenStream(lexer)); Integer answer = new Visitor().visit(parser.input()); System.out.printf("%s = %s\n", expression, answer); } }

将打印:

visitInput: 2--2<EOF> visitAdditiveExpr: 2--2 visitNum: 2 visitUnaryMinusExpr: -2 visitNum: 2 2 - -2 = 4

这是一个表达式解析器/评估器的小演示,其中包括基本循环以及使用ANTLR4 +访问者的if语句: https ://github/bkiers/Mu

Here's a small demo of an expression parser/evaluator including basic loops and if statements using ANTLR4 + a Visitor: github/bkiers/Mu

更多推荐

ANTLR 4如何处理一元/负数

本文发布于:2023-11-29 12:16:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1646370.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:负数   如何处理   ANTLR

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!