[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-settings":3,"$fndhqw1sm47op":14,"$f34sgqgtsiu7ix":31,"$f31nzld6lo2ynk":57,"$f2hf8zv88r59zg":61,"render-antlr4-03-variables-and-print":74},{"code":4,"message":5,"data":6},0,"ok",{"author_role":7,"icp":8,"skill_one_title":7,"about_hero_image":7,"skill_two_title":7,"author_status":7,"skill_one_desc":7,"site_description":9,"site_tagline":7,"author_years":10,"author_city":11,"home_hero_image":7,"tagline_line_two":7,"site_name":12,"closing_quote":7,"author_bio_two":7,"tagline_line_one":7,"weekly_thought":7,"author_tagline":7,"site_url":13,"site_footer":7,"author_bio":7,"skill_two_desc":7,"toolkit":7,"closing_quote_date":7,"og_default_image":7},"","陕ICP备2021009682号-1","花开空白 - 个人博客","10","西安","花开空白","https:\u002F\u002Firule.cn",{"code":4,"message":5,"data":15},{"id":16,"slug":17,"title":18,"summary":19,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":23,"readingMinutes":24,"publishedAt":25,"contentMd":26,"contentHtml":27,"tags":28,"metaTitle":20,"metaDescription":20,"keywords":20,"canonicalUrl":20,"robots":30,"ogImage":20,"faq":20,"aiSummary":20},"2101585710597718018","antlr4-03-variables-and-print","Antlr4系列③：支持变量定义和打印函数","number\u002Fstring\u002Fboolean变量定义、print函数、VisitorResult统一返回类型",null,"1946000000000000001",1,8172,21,"2026-09-20T16:14:14","在上一篇文章中我们完善了四则运算使其支持连续混合运算，并解决了连续运算时包含乘除法的优先级问题，本篇文章我们将继续完善语法，使其支持变量的定义，并在四则混合运算中支持变量的使用。\n\n## 一、语法设计\n1. 变量定义语法\n\n    在java语言中变量的定义是这样的`int a = 1;`，可以看出变量的定义通常包含变量类型、变量名称以及变量值，参考java语言变量的定义方式，在我们的语法中变量的定义设计如下：\n    - 支持三种变量类型`number`、`string`、`boolean`，分别代表数值型、字符型和布尔型。\n    -  变量名称设计为：**变量名称以大小写字母或下划线开头，可以包含数字。**\n    -  `number`作为数值型的关键字，其定义的变量值可以为整型或者浮点型。\n    -  `string`作为字符型的关键字，其定义的变量值为用双引号包裹的任意字符。\n    -  `boolean`作为布尔型的关键字，其定义的变量值为true或false。（后续再支持逻辑运算）\n    -  `=`作为赋值符号\n    -  变量定义语句的结尾以分号结尾，分号可以省略。\n  \n2. 打印函数语法\n   \n    为了方便验证计算结果，我们再设计一种打印函数，设计原则如下：\n    -  使用print关键字作为打印函数名称\n    -  print后面使用小括号将要打印的信息进行包裹\n    -  支持打印字符串\n    -  支持打印boolean型\n    -  支持打印变量\n3. 四则运算语法完善\n   \n    在四则运算语法中引入变量，使其支持使用变量进行计算。\n\n## 二、语法定义\n\n根据以上设计原则对之前的语法定义进行完善，完善后的结果如下：\n```\ngrammar RuleSet; \u002F\u002F程序名称和.g4名称一致即可\n\nprog: main+      \u002F\u002F 新增\n   ;\n\nmain: setArg SEMI?                                                 \u002F\u002F 新增\n    | print SEMI?                                                  \u002F\u002F 新增\n    ;\n\nsetArg :'number'  id = ID '='  calcu                      #numarg   \u002F\u002F 新增\n       |'string'  id = ID '='  STRING                     #chararg  \u002F\u002F 新增\n       |'boolean' id = ID '='  BOOL                       #boolarg  \u002F\u002F 新增\n       ;\ncalcu: calcu opt=(MUL|DIV) calcu                          # mulAndDiv \n     | calcu opt=(ADD|SUB) calcu                          # addAndSub\n     | '(' calcu ')'                                      # parens\n     | NUMBER                                             # number\n     | ID                                                 # argValue  \u002F\u002F 新增\n     ;\nprint: PRINT '(' value = ID ')'                           # printArg  \u002F\u002F 新增\n     | PRINT '(' value = BOOL ')'                         # printBoolean \u002F\u002F 新增\n     | PRINT '(' value = STRING ')'                       # printString  \u002F\u002F 新增\n     ;\n\nWS : [ \\t\\n\\r]+ -> skip ; \u002F\u002F ->skip表示antlr4在分析语言的文本时，符合这个规则的词法将被无视\nADD : '+' ;\nSUB : '-' ;\nMUL : '*' ;\nDIV : '\u002F' ;\nNUMBER : '-'? [0-9]+('.'([0-9]+)?)? ;        \u002F\u002F 数字正则\n\u002F\u002F以下为本次新增词法\nBOOL : 'true' | 'false' ;\nSTRING : '\"' .*? '\"';\nPRINT : 'print';\nSEMI:  ';';\nfragment ID_LETTER : [a-z] | [A-Z] | '_' ;\nfragment DIGIT : [0-9] ;\nID : ID_LETTER (ID_LETTER | DIGIT)* ;\n\n```\n为方便和上一篇文章中的语法进行对比，对于本次新增的部分使用注释进行了标注，接下来对本次新增的部分进行解释。\n\n1. 词法部分\n   \n    对于词法部分主要是一些正则表达式的定义，需要理解的地方如下：\n    - `?`： 表示匹配或忽略\n    - `*`： 表示匹配0次或者多次\n    - `+`： 表示匹配1次或者多次\n    - `fragment`： 表示一个词法片段，可以被词法引用，但是不能在语法中使用，如 `DIGIT`可以在词法`ID`中使用，但是不能在`calcu`语法中使用，而未被 `fragment`标识的`ID`是可以在`calcu`语法中使用的。\n\n2. 语法部分\n   \n   各个语法的解释如下：\n\n    - `setArg`语法表示变量定义语法，其包含三种规则，分别用来定义`number`、`string`、 `boolean`三种类型的变量，其中的词法`ID`是变量的名称`=`作为赋值符号将右边的值赋给变量，`string`、`boolean`的变量值都是固定的词法，`number`的值为`calcu`语法，而`calcu`语法的规则中包含了`NUMBER`词法，因此`number`变量定义时等号右侧可以是数值也可以是四则运算。\n\n    - `calcu`语法中新增了一个`ID`词法，因为`ID`词法是作为变量定义时的变量的名称的，所以`calcu`就支持了使用变量进行计算。\n\n    - `print`有三种规则，语法的括号内按照上文的设计原则分别匹配了变量、字符串和布尔型。\n\n    - `main`增加此语法是因为`print`和`setArg`之间不存在引用关系，是两种独立的语法，是两个独立的语法树，而在antlr4中想要将所有代码完整执行就只能存在一棵语法树，因此需要一个新的语法将两种语法关联到一起为最终形成一棵语法树做好准备�\b\n\n\b\b\u000bH\u0018\u001c\u001c���:+�y��y.+yc깧\"x\u001bXZ[�9. 9��z+�y��{�#9\u002Fa��+�g*\u0018\u001bXZ[�9�9d#�gh��\"x可表示匹配一个或多个，因此当代码中同时出现`setArg`和`print`时可以多次匹配，最终形成一棵完整的语法树。\n\n    对于`main`和`prog`两种语法可能相对比较难理解，简单的来说如果没有`prog`和`mian`时`setArg`和`calcu`只能独立使用，同时出现在代码中时语法检查无法通过。如果没有`prog`只有`mian`时，根据上一篇文章所讲的语法规则优先级，`setArg`和`calcu`同时出现在代码中时，写在后面的代码会被忽略掉，无法完整执行。\n\n    ## 三、语法实现\n\n    接下来使用idea插件将定义好的.g4文件生成对应的java文件，使用新生成的java文件覆盖之前的文件，至此我们需要思考一个问题之前的文章中`MyRuleSetVisitor`继承`RuleSetBaseVisitor`后因为四则运算的返回值为数值型将泛型指定为了Double，在本次新增的语法中打印函数和变量定义均无返回值类型，该如何兼容这种情况呢？这就需要再定义一种类型，来兼容各种返回值类型，方便后续返回不同类型的值。\n\n    定义一个`VisitorResult`类如下：\n ```java\n    \u002F**\n    * visitor访问语法树每个节点的返回结果\n    * 返回结果包含 三种类型 数值型（全部转为double）、字符串、布尔型，每次只可能返回三种类型中的一种，其他类型将抛出运行时异常\n    *\n    * @author dongxingli\n    * createTime 2023\u002F5\u002F11\n    * @version V1.0\n    *\u002F\n    public class VisitorResult {\n\n        private Object value;\n\n        private VisitorResult() {\n\n        }\n\n        private VisitorResult(Object value) {\n            if (value instanceof String \n            || value instanceof Double \n            || value instanceof Boolean \n            || value == null) {\n                this.value = value;\n            } else {\n                throw new RuntimeException(\"不支持的参数类型\" + value);\n            }\n        }\n\n        public Boolean getBool() {\n            if (isBoolean()) {\n                return (Boolean) value;\n            }\n            throw new RuntimeException(\"非Boolean类型\");\n        }\n\n        public Double getNumber() {\n            if (isNumber()) {\n                return (Double) value;\n            }\n            throw new RuntimeException(\"非Number类型\");\n        }\n\n        public String getString() {\n            if (isVarchar()) {\n                return (String) value;\n            }\n            throw new RuntimeException(\"非String类型\");\n        }\n\n        public static VisitorResult value(Object value) {\n            return new VisitorResult(value);\n        }\n\n        \u002F**\n        * 返回NULL\n        *\n        * @return 结果类\n        *\u002F\n        public static VisitorResult nil() {\n            return new VisitorResult();\n        }\n\n        \u002F**\n        * 返回结果是否数值型\n        *\n        * @return 是或否\n        *\u002F\n        public boolean isNumber() {\n            return this.value instanceof Number;\n        }\n\n        \u002F**\n        * 返回结果是否字符串\n        *\n        * @return 是或否\n        *\u002F\n        public boolean isVarchar() {\n            return this.value instanceof String;\n        }\n\n        \u002F**\n        * 返回结果是否布尔型\n        *\n        * @return 是或否\n        *\u002F\n        public boolean isBoolean() {\n            return this.value instanceof Boolean;\n        }\n\n        \u002F**\n        * 返回结果是否为null\n        *\n        * @return 是或否\n        *\u002F\n        public boolean isNull() {\n            return value == null;\n        }\n\n        public Object getValue() {\n            return value;\n        }\n\n        @Override\n        public String toString() {\n            if (isNumber()) {\n                return Double.toString((Double) value);\n            } else if (isVarchar()) {\n                return (String) value;\n            } else if (isBoolean()) {\n                return Boolean.toString((Boolean) value);\n            } else {\n                throw new RuntimeException(\"未知类型\");\n            }\n        }\n    }\n```\n\n接下来使用`VisitorResult`类作为`RuleSetBaseVisitor`的泛型对之前的四则运算代码进行修改，并实现赋值与打印函数的功能，修改后的代码如下：\n\n```java\n    public class MyRuleSetVisitor extends RuleSetBaseVisitor\u003CVisitorResult> { \u002F\u002F修改泛型\n\n\n        \u002F**\n         * 语法中定义的参数，key为变量名称\n         *\u002F\n        private final Map\u003CString, Object> paramDefine = new HashMap\u003C>();  \u002F\u002F新增\n\n        @Override\n        public VisitorResult visitAddAndSub(RuleSetParser.AddAndSubContext ctx) {\n            \u002F\u002F 符号左边的calcu语法，\n            \u002F\u002F 它可能是一组带括号或不带括号甲减乘除运算，也可能是一个数字\n            \u002F\u002F 直接visit即可访问它的处理方法拿到最终返回结果\n            VisitorResult visit = visit(ctx.calcu(0));          \u002F\u002F修改\n            double left = visit.getNumber();                       \u002F\u002F修改\n            \u002F\u002F 符号右边的calcu语法\n            VisitorResult visit2 = visit(ctx.calcu(1));        \u002F\u002F修改\n            double right = visit2.getNumber();                    \u002F\u002F修改\n            \u002F\u002F通过别名获取opt类型判断是加还是减\n            if (ctx.opt.getType() == RuleSetLexer.ADD) {\n                return VisitorResult.value(left + right);         \u002F\u002F修改\n            } else {\n                return VisitorResult.value(left - right);        \u002F\u002F修改\n            }\n        }\n\n        @Override\n        public VisitorResult visitMulAndDiv(RuleSetParser.MulAndDivContext ctx) {\n            VisitorResult visit = visit(ctx.calcu(0));          \u002F\u002F修改\n            double left = visit.getNumber();                      \u002F\u002F修改\n            VisitorResult visit2 = visit(ctx.calcu(1));        \u002F\u002F修改\n            double right = visit2.getNumber();                    \u002F\u002F修改\n            if (ctx.opt.getType() == RuleSetLexer.MUL) {\n                return VisitorResult.value(left * right);         \u002F\u002F修改\n            } else {\n                return VisitorResult.value(left \u002F right);         \u002F\u002F修改\n            }\n        }\n\n        @Override\n        public VisitorResult visitNumber(RuleSetParser.NumberContext ctx) {\n            \u002F\u002F NUMBER词法直接转为double\n            return VisitorResult.value(Double.parseDouble(ctx.getText())); \u002F\u002F修改\n        }\n\n        \u002F\u002F ---------------------------以下函数为本次新增----------------------------\n        \u002F**\n         *定义数值类型变量，调用calcu进行计算完成后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitNumarg(RuleSetParser.NumargContext ctx) {\n            VisitorResult visit = visit(ctx.calcu());\n            paramDefine.put(ctx.id.getText(), visit.getNumber());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *定义字符型变量，获取到字符串值后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitChararg(RuleSetParser.CharargContext ctx) {\n            paramDefine.put(ctx.id.getText(), ctx.STRING().getText());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *定义布尔型变量，获取到布尔值后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitBoolarg(RuleSetParser.BoolargContext ctx) {\n            paramDefine.put(ctx.id.getText(), ctx.BOOL().getText());\n            return VisitorResult.nil();\n        }\n\n\n        \u002F**\n         *获取所定义的变量值，根据变量名称从保存变量值的map中查找\n        *\u002F\n        @Override\n        public VisitorResult visitArgValue(RuleSetParser.ArgValueContext ctx) {\n            Object value = paramDefine.get(ctx.getText());\n            if (value instanceof Double) {\n                return VisitorResult.value(value);\n            }\n            throw new RuntimeException(\"未定义的参数：\" + ctx.getText() + \" 或参数\" + ctx.getText() + \"定义为非数值型\");\n        }\n        \u002F**\n         *打印变量值，根据变量名称从保存变量值的map中查找后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintArg(RuleSetParser.PrintArgContext ctx) {\n            String argName = ctx.value.getText();\n            Object value = paramDefine.get(argName);\n            if (value == null) {\n                throw new RuntimeException(\"未定义的变量：\" + argName);\n            }\n            System.out.println(value);\n            return super.visitPrintArg(ctx);\n        }\n        \u002F**\n         *打印变量值，获取到布尔变量值后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintBoolean(RuleSetParser.PrintBooleanContext ctx) {\n            System.out.println(ctx.value.getText());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *打印变量值，获取到字符串后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintString(RuleSetParser.PrintStringContext ctx) {\n            System.out.println(ctx.value.getText());\n            return VisitorResult.nil();\n        }\n    }\n```\n\n接下来编写测试代码，如下\n\n``` java\npublic class Test {\n    public static void main(String[] args) {\n        String expression =\n                        \"number a = 1 \\n\" +\n                        \"number b = 2 \\n\" +\n                        \"number c = a + b * 3 \\n\" +\n                        \"string d = \\\"字符串\\\" \\n\" +\n                        \"boolean e = true \\n\" +\n                        \"print(c) \\n\" +\n                        \"print(d) \\n\" +\n                        \"print(e)\";\n        calcute(expression);\n    }\n\n    private static void calcute(String expression) {\n        System.out.println(\"执行:\");\n        System.out.println(expression);\n        System.out.println();\n        MyRuleSetVisitor visitor = new MyRuleSetVisitor();\n        RuleSetLexer lexer = new RuleSetLexer(CharStreams.fromString(expression));\n        lexer.removeErrorListeners();\n        LexicalErrorListener lexicalListener = new LexicalErrorListener();\n        \u002F\u002F添加词法错误监听\n        lexer.addErrorListener(lexicalListener);\n        RuleSetParser parser = new RuleSetParser(new CommonTokenStream(lexer));\n        parser.removeErrorListeners();\n        GrammarErrorListener errorListener = new GrammarErrorListener();\n        \u002F\u002F添加语法法错误监听\n        parser.addErrorListener(errorListener);\n        RuleSetParser.ProgContext calcu = parser.prog(); \u002F\u002F此处由calcu()改为prog()\n        List\u003CString> lexicalError = lexicalListener.getErrMessage();\n        List\u003CString> grammarError = errorListener.getErrMessage();\n        if (!lexicalError.isEmpty()) {\n            System.out.println(lexicalError);\n            return;\n        }\n        if (!grammarError.isEmpty()) {\n            System.out.println(grammarError);\n            return;\n        }\n        VisitorResult result = visitor.visit(calcu);\n    }\n}\n```\n执行结果如下：\n\n\n```\n> Task :Test.main()\n执行:\nnumber a = 1 \nnumber b = 2 \nnumber c = a + b * 3 \nstring d = \"字符串\" \nboolean e = true \nprint(c) \nprint(d) \nprint(e)\n\n7.0\n\"字符串\"\ntrue\n```\n\n根据以上执行结果可以看出，语法已经支持变量的定义及使用且计算结果正确，同时打印函数也可以正常使用，下一章节将继续完善语法，使其支持分支语句。\n\n\n\n","\u003Cp>在上一篇文章中我们完善了四则运算使其支持连续混合运算，并解决了连续运算时包含乘除法的优先级问题，本篇文章我们将继续完善语法，使其支持变量的定义，并在四则混合运算中支持变量的使用。\u003C\u002Fp>\n\u003Ch2>一、语法设计\u003C\u002Fh2>\n\u003Col>\n \u003Cli>\n  \u003Cp>变量定义语法\u003C\u002Fp>\n  \u003Cp>在java语言中变量的定义是这样的\u003Ccode>int a = 1;\u003C\u002Fcode>，可以看出变量的定义通常包含变量类型、变量名称以及变量值，参考java语言变量的定义方式，在我们的语法中变量的定义设计如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>支持三种变量类型\u003Ccode>number\u003C\u002Fcode>、\u003Ccode>string\u003C\u002Fcode>、\u003Ccode>boolean\u003C\u002Fcode>，分别代表数值型、字符型和布尔型。\u003C\u002Fli>\n   \u003Cli>变量名称设计为：\u003Cstrong>变量名称以大小写字母或下划线开头，可以包含数字。\u003C\u002Fstrong>\u003C\u002Fli>\n   \u003Cli>\u003Ccode>number\u003C\u002Fcode>作为数值型的关键字，其定义的变量值可以为整型或者浮点型。\u003C\u002Fli>\n   \u003Cli>\u003Ccode>string\u003C\u002Fcode>作为字符型的关键字，其定义的变量值为用双引号包裹的任意字符。\u003C\u002Fli>\n   \u003Cli>\u003Ccode>boolean\u003C\u002Fcode>作为布尔型的关键字，其定义的变量值为true或false。（后续再支持逻辑运算）\u003C\u002Fli>\n   \u003Cli>\u003Ccode>=\u003C\u002Fcode>作为赋值符号\u003C\u002Fli>\n   \u003Cli>变量定义语句的结尾以分号结尾，分号可以省略。\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>打印函数语法\u003C\u002Fp>\n  \u003Cp>为了方便验证计算结果，我们再设计一种打印函数，设计原则如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>使用print关键字作为打印函数名称\u003C\u002Fli>\n   \u003Cli>print后面使用小括号将要打印的信息进行包裹\u003C\u002Fli>\n   \u003Cli>支持打印字符串\u003C\u002Fli>\n   \u003Cli>支持打印boolean型\u003C\u002Fli>\n   \u003Cli>支持打印变量\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>四则运算语法完善\u003C\u002Fp>\n  \u003Cp>在四则运算语法中引入变量，使其支持使用变量进行计算。\u003C\u002Fp>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2>二、语法定义\u003C\u002Fh2>\n\u003Cp>根据以上设计原则对之前的语法定义进行完善，完善后的结果如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>grammar RuleSet; \u002F\u002F程序名称和.g4名称一致即可\n\nprog: main+      \u002F\u002F 新增\n   ;\n\nmain: setArg SEMI?                                                 \u002F\u002F 新增\n    | print SEMI?                                                  \u002F\u002F 新增\n    ;\n\nsetArg :'number'  id = ID '='  calcu                      #numarg   \u002F\u002F 新增\n       |'string'  id = ID '='  STRING                     #chararg  \u002F\u002F 新增\n       |'boolean' id = ID '='  BOOL                       #boolarg  \u002F\u002F 新增\n       ;\ncalcu: calcu opt=(MUL|DIV) calcu                          # mulAndDiv \n     | calcu opt=(ADD|SUB) calcu                          # addAndSub\n     | '(' calcu ')'                                      # parens\n     | NUMBER                                             # number\n     | ID                                                 # argValue  \u002F\u002F 新增\n     ;\nprint: PRINT '(' value = ID ')'                           # printArg  \u002F\u002F 新增\n     | PRINT '(' value = BOOL ')'                         # printBoolean \u002F\u002F 新增\n     | PRINT '(' value = STRING ')'                       # printString  \u002F\u002F 新增\n     ;\n\nWS : [ \\t\\n\\r]+ -&gt; skip ; \u002F\u002F -&gt;skip表示antlr4在分析语言的文本时，符合这个规则的词法将被无视\nADD : '+' ;\nSUB : '-' ;\nMUL : '*' ;\nDIV : '\u002F' ;\nNUMBER : '-'? [0-9]+('.'([0-9]+)?)? ;        \u002F\u002F 数字正则\n\u002F\u002F以下为本次新增词法\nBOOL : 'true' | 'false' ;\nSTRING : '\"' .*? '\"';\nPRINT : 'print';\nSEMI:  ';';\nfragment ID_LETTER : [a-z] | [A-Z] | '_' ;\nfragment DIGIT : [0-9] ;\nID : ID_LETTER (ID_LETTER | DIGIT)* ;\n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>为方便和上一篇文章中的语法进行对比，对于本次新增的部分使用注释进行了标注，接下来对本次新增的部分进行解释。\u003C\u002Fp>\n\u003Col>\n \u003Cli>\n  \u003Cp>词法部分\u003C\u002Fp>\n  \u003Cp>对于词法部分主要是一些正则表达式的定义，需要理解的地方如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>\u003Ccode>?\u003C\u002Fcode>： 表示匹配或忽略\u003C\u002Fli>\n   \u003Cli>\u003Ccode>*\u003C\u002Fcode>： 表示匹配0次或者多次\u003C\u002Fli>\n   \u003Cli>\u003Ccode>+\u003C\u002Fcode>： 表示匹配1次或者多次\u003C\u002Fli>\n   \u003Cli>\u003Ccode>fragment\u003C\u002Fcode>： 表示一个词法片段，可以被词法引用，但是不能在语法中使用，如 \u003Ccode>DIGIT\u003C\u002Fcode>可以在词法\u003Ccode>ID\u003C\u002Fcode>中使用，但是不能在\u003Ccode>calcu\u003C\u002Fcode>语法中使用，而未被 \u003Ccode>fragment\u003C\u002Fcode>标识的\u003Ccode>ID\u003C\u002Fcode>是可以在\u003Ccode>calcu\u003C\u002Fcode>语法中使用的。\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>语法部分\u003C\u002Fp>\n  \u003Cp>各个语法的解释如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>\n    \u003Cp>\u003Ccode>setArg\u003C\u002Fcode>语法表示变量定义语法，其包含三种规则，分别用来定义\u003Ccode>number\u003C\u002Fcode>、\u003Ccode>string\u003C\u002Fcode>、 \u003Ccode>boolean\u003C\u002Fcode>三种类型的变量，其中的词法\u003Ccode>ID\u003C\u002Fcode>是变量的名称\u003Ccode>=\u003C\u002Fcode>作为赋值符号将右边的值赋给变量，\u003Ccode>string\u003C\u002Fcode>、\u003Ccode>boolean\u003C\u002Fcode>的变量值都是固定的词法，\u003Ccode>number\u003C\u002Fcode>的值为\u003Ccode>calcu\u003C\u002Fcode>语法，而\u003Ccode>calcu\u003C\u002Fcode>语法的规则中包含了\u003Ccode>NUMBER\u003C\u002Fcode>词法，因此\u003Ccode>number\u003C\u002Fcode>变量定义时等号右侧可以是数值也可以是四则运算。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>calcu\u003C\u002Fcode>语法中新增了一个\u003Ccode>ID\u003C\u002Fcode>词法，因为\u003Ccode>ID\u003C\u002Fcode>词法是作为变量定义时的变量的名称的，所以\u003Ccode>calcu\u003C\u002Fcode>就支持了使用变量进行计算。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>print\u003C\u002Fcode>有三种规则，语法的括号内按照上文的设计原则分别匹配了变量、字符串和布尔型。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>main\u003C\u002Fcode>增加此语法是因为\u003Ccode>print\u003C\u002Fcode>和\u003Ccode>setArg\u003C\u002Fcode>之间不存在引用关系，是两种独立的语法，是两个独立的语法树，而在antlr4中想要将所有代码完整执行就只能存在一棵语法树，因此需要一个新的语法将两种语法关联到一起为最终形成一棵语法树做好准备�&#x8;\u003C\u002Fp>\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>&#x8;&#x8;&#xb;H&#x18;&#x1c;&#x1c;���:+�y��y.+yc깧\"x&#x1b;XZ[�9. 9��z+�y��{�#9\u002Fa��+�g*&#x18;&#x1b;XZ[�9�9d#�gh��\"x可表示匹配一个或多个，因此当代码中同时出现\u003Ccode>setArg\u003C\u002Fcode>和\u003Ccode>print\u003C\u002Fcode>时可以多次匹配，最终形成一棵完整的语法树。\u003C\u002Fp>\n\u003Cpre>\u003Ccode>对于`main`和`prog`两种语法可能相对比较难理解，简单的来说如果没有`prog`和`mian`时`setArg`和`calcu`只能独立使用，同时出现在代码中时语法检查无法通过。如果没有`prog`只有`mian`时，根据上一篇文章所讲的语法规则优先级，`setArg`和`calcu`同时出现在代码中时，写在后面的代码会被忽略掉，无法完整执行。\n\n## 三、语法实现\n\n接下来使用idea插件将定义好的.g4文件生成对应的java文件，使用新生成的java文件覆盖之前的文件，至此我们需要思考一个问题之前的文章中`MyRuleSetVisitor`继承`RuleSetBaseVisitor`后因为四则运算的返回值为数值型将泛型指定为了Double，在本次新增的语法中打印函数和变量定义均无返回值类型，该如何兼容这种情况呢？这就需要再定义一种类型，来兼容各种返回值类型，方便后续返回不同类型的值。\n\n定义一个`VisitorResult`类如下：\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cpre>\u003Ccode class=\"language-java\">   \u002F**\n   * visitor访问语法树每个节点的返回结果\n   * 返回结果包含 三种类型 数值型（全部转为double）、字符串、布尔型，每次只可能返回三种类型中的一种，其他类型将抛出运行时异常\n   *\n   * @author dongxingli\n   * createTime 2023\u002F5\u002F11\n   * @version V1.0\n   *\u002F\n   public class VisitorResult {\n\n       private Object value;\n\n       private VisitorResult() {\n\n       }\n\n       private VisitorResult(Object value) {\n           if (value instanceof String \n           || value instanceof Double \n           || value instanceof Boolean \n           || value == null) {\n               this.value = value;\n           } else {\n               throw new RuntimeException(\"不支持的参数类型\" + value);\n           }\n       }\n\n       public Boolean getBool() {\n           if (isBoolean()) {\n               return (Boolean) value;\n           }\n           throw new RuntimeException(\"非Boolean类型\");\n       }\n\n       public Double getNumber() {\n           if (isNumber()) {\n               return (Double) value;\n           }\n           throw new RuntimeException(\"非Number类型\");\n       }\n\n       public String getString() {\n           if (isVarchar()) {\n               return (String) value;\n           }\n           throw new RuntimeException(\"非String类型\");\n       }\n\n       public static VisitorResult value(Object value) {\n           return new VisitorResult(value);\n       }\n\n       \u002F**\n       * 返回NULL\n       *\n       * @return 结果类\n       *\u002F\n       public static VisitorResult nil() {\n           return new VisitorResult();\n       }\n\n       \u002F**\n       * 返回结果是否数值型\n       *\n       * @return 是或否\n       *\u002F\n       public boolean isNumber() {\n           return this.value instanceof Number;\n       }\n\n       \u002F**\n       * 返回结果是否字符串\n       *\n       * @return 是或否\n       *\u002F\n       public boolean isVarchar() {\n           return this.value instanceof String;\n       }\n\n       \u002F**\n       * 返回结果是否布尔型\n       *\n       * @return 是或否\n       *\u002F\n       public boolean isBoolean() {\n           return this.value instanceof Boolean;\n       }\n\n       \u002F**\n       * 返回结果是否为null\n       *\n       * @return 是或否\n       *\u002F\n       public boolean isNull() {\n           return value == null;\n       }\n\n       public Object getValue() {\n           return value;\n       }\n\n       @Override\n       public String toString() {\n           if (isNumber()) {\n               return Double.toString((Double) value);\n           } else if (isVarchar()) {\n               return (String) value;\n           } else if (isBoolean()) {\n               return Boolean.toString((Boolean) value);\n           } else {\n               throw new RuntimeException(\"未知类型\");\n           }\n       }\n   }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接下来使用\u003Ccode>VisitorResult\u003C\u002Fcode>类作为\u003Ccode>RuleSetBaseVisitor\u003C\u002Fcode>的泛型对之前的四则运算代码进行修改，并实现赋值与打印函数的功能，修改后的代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">    public class MyRuleSetVisitor extends RuleSetBaseVisitor&lt;VisitorResult&gt; { \u002F\u002F修改泛型\n\n\n        \u002F**\n         * 语法中定义的参数，key为变量名称\n         *\u002F\n        private final Map&lt;String, Object&gt; paramDefine = new HashMap&lt;&gt;();  \u002F\u002F新增\n\n        @Override\n        public VisitorResult visitAddAndSub(RuleSetParser.AddAndSubContext ctx) {\n            \u002F\u002F 符号左边的calcu语法，\n            \u002F\u002F 它可能是一组带括号或不带括号甲减乘除运算，也可能是一个数字\n            \u002F\u002F 直接visit即可访问它的处理方法拿到最终返回结果\n            VisitorResult visit = visit(ctx.calcu(0));          \u002F\u002F修改\n            double left = visit.getNumber();                       \u002F\u002F修改\n            \u002F\u002F 符号右边的calcu语法\n            VisitorResult visit2 = visit(ctx.calcu(1));        \u002F\u002F修改\n            double right = visit2.getNumber();                    \u002F\u002F修改\n            \u002F\u002F通过别名获取opt类型判断是加还是减\n            if (ctx.opt.getType() == RuleSetLexer.ADD) {\n                return VisitorResult.value(left + right);         \u002F\u002F修改\n            } else {\n                return VisitorResult.value(left - right);        \u002F\u002F修改\n            }\n        }\n\n        @Override\n        public VisitorResult visitMulAndDiv(RuleSetParser.MulAndDivContext ctx) {\n            VisitorResult visit = visit(ctx.calcu(0));          \u002F\u002F修改\n            double left = visit.getNumber();                      \u002F\u002F修改\n            VisitorResult visit2 = visit(ctx.calcu(1));        \u002F\u002F修改\n            double right = visit2.getNumber();                    \u002F\u002F修改\n            if (ctx.opt.getType() == RuleSetLexer.MUL) {\n                return VisitorResult.value(left * right);         \u002F\u002F修改\n            } else {\n                return VisitorResult.value(left \u002F right);         \u002F\u002F修改\n            }\n        }\n\n        @Override\n        public VisitorResult visitNumber(RuleSetParser.NumberContext ctx) {\n            \u002F\u002F NUMBER词法直接转为double\n            return VisitorResult.value(Double.parseDouble(ctx.getText())); \u002F\u002F修改\n        }\n\n        \u002F\u002F ---------------------------以下函数为本次新增----------------------------\n        \u002F**\n         *定义数值类型变量，调用calcu进行计算完成后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitNumarg(RuleSetParser.NumargContext ctx) {\n            VisitorResult visit = visit(ctx.calcu());\n            paramDefine.put(ctx.id.getText(), visit.getNumber());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *定义字符型变量，获取到字符串值后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitChararg(RuleSetParser.CharargContext ctx) {\n            paramDefine.put(ctx.id.getText(), ctx.STRING().getText());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *定义布尔型变量，获取到布尔值后将变量值保存到map中\n        *\u002F\n        @Override\n        public VisitorResult visitBoolarg(RuleSetParser.BoolargContext ctx) {\n            paramDefine.put(ctx.id.getText(), ctx.BOOL().getText());\n            return VisitorResult.nil();\n        }\n\n\n        \u002F**\n         *获取所定义的变量值，根据变量名称从保存变量值的map中查找\n        *\u002F\n        @Override\n        public VisitorResult visitArgValue(RuleSetParser.ArgValueContext ctx) {\n            Object value = paramDefine.get(ctx.getText());\n            if (value instanceof Double) {\n                return VisitorResult.value(value);\n            }\n            throw new RuntimeException(\"未定义的参数：\" + ctx.getText() + \" 或参数\" + ctx.getText() + \"定义为非数值型\");\n        }\n        \u002F**\n         *打印变量值，根据变量名称从保存变量值的map中查找后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintArg(RuleSetParser.PrintArgContext ctx) {\n            String argName = ctx.value.getText();\n            Object value = paramDefine.get(argName);\n            if (value == null) {\n                throw new RuntimeException(\"未定义的变量：\" + argName);\n            }\n            System.out.println(value);\n            return super.visitPrintArg(ctx);\n        }\n        \u002F**\n         *打印变量值，获取到布尔变量值后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintBoolean(RuleSetParser.PrintBooleanContext ctx) {\n            System.out.println(ctx.value.getText());\n            return VisitorResult.nil();\n        }\n        \u002F**\n         *打印变量值，获取到字符串后使用java打印方法进行打印\n        *\u002F\n        @Override\n        public VisitorResult visitPrintString(RuleSetParser.PrintStringContext ctx) {\n            System.out.println(ctx.value.getText());\n            return VisitorResult.nil();\n        }\n    }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接下来编写测试代码，如下\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public class Test {\n    public static void main(String[] args) {\n        String expression =\n                        \"number a = 1 \\n\" +\n                        \"number b = 2 \\n\" +\n                        \"number c = a + b * 3 \\n\" +\n                        \"string d = \\\"字符串\\\" \\n\" +\n                        \"boolean e = true \\n\" +\n                        \"print(c) \\n\" +\n                        \"print(d) \\n\" +\n                        \"print(e)\";\n        calcute(expression);\n    }\n\n    private static void calcute(String expression) {\n        System.out.println(\"执行:\");\n        System.out.println(expression);\n        System.out.println();\n        MyRuleSetVisitor visitor = new MyRuleSetVisitor();\n        RuleSetLexer lexer = new RuleSetLexer(CharStreams.fromString(expression));\n        lexer.removeErrorListeners();\n        LexicalErrorListener lexicalListener = new LexicalErrorListener();\n        \u002F\u002F添加词法错误监听\n        lexer.addErrorListener(lexicalListener);\n        RuleSetParser parser = new RuleSetParser(new CommonTokenStream(lexer));\n        parser.removeErrorListeners();\n        GrammarErrorListener errorListener = new GrammarErrorListener();\n        \u002F\u002F添加语法法错误监听\n        parser.addErrorListener(errorListener);\n        RuleSetParser.ProgContext calcu = parser.prog(); \u002F\u002F此处由calcu()改为prog()\n        List&lt;String&gt; lexicalError = lexicalListener.getErrMessage();\n        List&lt;String&gt; grammarError = errorListener.getErrMessage();\n        if (!lexicalError.isEmpty()) {\n            System.out.println(lexicalError);\n            return;\n        }\n        if (!grammarError.isEmpty()) {\n            System.out.println(grammarError);\n            return;\n        }\n        VisitorResult result = visitor.visit(calcu);\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>执行结果如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&gt; Task :Test.main()\n执行:\nnumber a = 1 \nnumber b = 2 \nnumber c = a + b * 3 \nstring d = \"字符串\" \nboolean e = true \nprint(c) \nprint(d) \nprint(e)\n\n7.0\n\"字符串\"\ntrue\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>根据以上执行结果可以看出，语法已经支持变量的定义及使用且计算结果正确，同时打印函数也可以正常使用，下一章节将继续完善语法，使其支持分支语句。\u003C\u002Fp>",[29],"Antlr4","index,follow",{"code":4,"message":5,"data":32},[33,41,49],{"id":34,"slug":35,"title":36,"summary":37,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":38,"readingMinutes":39,"publishedAt":40},"2101605987801022465","antlr4-04-if-else","Antlr4系列④：支持分支语句","比较运算符、逻辑运算符、if\u002Felse if\u002Felse、代码块block",6668,17,"2026-09-20T17:34:58",{"id":42,"slug":43,"title":44,"summary":45,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":46,"readingMinutes":47,"publishedAt":48},"2101584400070656001","antlr4-02-syntax-check-and-priority","Antlr4系列②：语法检查和多规则的优先级","BaseErrorListener做词法\u002F语法校验、calcu递归支持连续混合运算、用opt=别名解决优先级问题",5762,15,"2026-09-20T16:09:01",{"id":50,"slug":51,"title":52,"summary":53,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":54,"readingMinutes":55,"publishedAt":56},"2101608263357743105","antlr4-05-loops","Antlr4系列⑤：支持循环语句","while循环、break\u002Fcontinue（用异常做控制流跳转）",4801,13,"2026-09-20T17:44:00",{"code":4,"message":5,"data":58},{"prev":59,"next":60},{"id":42,"slug":43,"title":44,"summary":45,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":46,"readingMinutes":47,"publishedAt":48},{"id":34,"slug":35,"title":36,"summary":37,"coverUrl":20,"categoryId":21,"status":22,"topFlag":4,"viewCount":4,"likeCount":4,"wordCount":38,"readingMinutes":39,"publishedAt":40},{"code":4,"message":5,"data":62},[63,68],{"id":21,"name":64,"slug":65,"description":66,"sortOrder":4,"articleCount":67},"技术","tech","编程与技术笔记","5",{"id":69,"name":70,"slug":71,"description":72,"sortOrder":22,"articleCount":73},"1946000000000000002","随笔","essay","生活与思考","0",{"html":75,"toc":76},"\u003Cp>在上一篇文章中我们完善了四则运算使其支持连续混合运算，并解决了连续运算时包含乘除法的优先级问题，本篇文章我们将继续完善语法，使其支持变量的定义，并在四则混合运算中支持变量的使用。\u003C\u002Fp>\n\u003Ch2 id=\"toc-1\">一、语法设计\u003C\u002Fh2>\n\u003Col>\n \u003Cli>\n  \u003Cp>变量定义语法\u003C\u002Fp>\n  \u003Cp>在java语言中变量的定义是这样的\u003Ccode>int a = 1;\u003C\u002Fcode>，可以看出变量的定义通常包含变量类型、变量名称以及变量值，参考java语言变量的定义方式，在我们的语法中变量的定义设计如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>支持三种变量类型\u003Ccode>number\u003C\u002Fcode>、\u003Ccode>string\u003C\u002Fcode>、\u003Ccode>boolean\u003C\u002Fcode>，分别代表数值型、字符型和布尔型。\u003C\u002Fli>\n   \u003Cli>变量名称设计为：\u003Cstrong>变量名称以大小写字母或下划线开头，可以包含数字。\u003C\u002Fstrong>\u003C\u002Fli>\n   \u003Cli>\u003Ccode>number\u003C\u002Fcode>作为数值型的关键字，其定义的变量值可以为整型或者浮点型。\u003C\u002Fli>\n   \u003Cli>\u003Ccode>string\u003C\u002Fcode>作为字符型的关键字，其定义的变量值为用双引号包裹的任意字符。\u003C\u002Fli>\n   \u003Cli>\u003Ccode>boolean\u003C\u002Fcode>作为布尔型的关键字，其定义的变量值为true或false。（后续再支持逻辑运算）\u003C\u002Fli>\n   \u003Cli>\u003Ccode>=\u003C\u002Fcode>作为赋值符号\u003C\u002Fli>\n   \u003Cli>变量定义语句的结尾以分号结尾，分号可以省略。\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>打印函数语法\u003C\u002Fp>\n  \u003Cp>为了方便验证计算结果，我们再设计一种打印函数，设计原则如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>使用print关键字作为打印函数名称\u003C\u002Fli>\n   \u003Cli>print后面使用小括号将要打印的信息进行包裹\u003C\u002Fli>\n   \u003Cli>支持打印字符串\u003C\u002Fli>\n   \u003Cli>支持打印boolean型\u003C\u002Fli>\n   \u003Cli>支持打印变量\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>四则运算语法完善\u003C\u002Fp>\n  \u003Cp>在四则运算语法中引入变量，使其支持使用变量进行计算。\u003C\u002Fp>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"toc-2\">二、语法定义\u003C\u002Fh2>\n\u003Cp>根据以上设计原则对之前的语法定义进行完善，完善后的结果如下：\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>grammar RuleSet; \u002F\u002F程序名称和.g4名称一致即可\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>prog: main+      \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>   ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>main: setArg SEMI?                                                 \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>    | print SEMI?                                                  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>    ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>setArg :'number'  id = ID '='  calcu                      #numarg   \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>       |'string'  id = ID '='  STRING                     #chararg  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>       |'boolean' id = ID '='  BOOL                       #boolarg  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>       ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>calcu: calcu opt=(MUL|DIV) calcu                          # mulAndDiv \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | calcu opt=(ADD|SUB) calcu                          # addAndSub\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | '(' calcu ')'                                      # parens\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | NUMBER                                             # number\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | ID                                                 # argValue  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>print: PRINT '(' value = ID ')'                           # printArg  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | PRINT '(' value = BOOL ')'                         # printBoolean \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     | PRINT '(' value = STRING ')'                       # printString  \u002F\u002F 新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>     ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>WS : [ \\t\\n\\r]+ -> skip ; \u002F\u002F ->skip表示antlr4在分析语言的文本时，符合这个规则的词法将被无视\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>ADD : '+' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>SUB : '-' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>MUL : '*' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>DIV : '\u002F' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>NUMBER : '-'? [0-9]+('.'([0-9]+)?)? ;        \u002F\u002F 数字正则\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u002F\u002F以下为本次新增词法\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>BOOL : 'true' | 'false' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>STRING : '\"' .*? '\"';\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>PRINT : 'print';\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>SEMI:  ';';\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>fragment ID_LETTER : [a-z] | [A-Z] | '_' ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>fragment DIGIT : [0-9] ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>ID : ID_LETTER (ID_LETTER | DIGIT)* ;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>为方便和上一篇文章中的语法进行对比，对于本次新增的部分使用注释进行了标注，接下来对本次新增的部分进行解释。\u003C\u002Fp>\n\u003Col>\n \u003Cli>\n  \u003Cp>词法部分\u003C\u002Fp>\n  \u003Cp>对于词法部分主要是一些正则表达式的定义，需要理解的地方如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>\u003Ccode>?\u003C\u002Fcode>： 表示匹配或忽略\u003C\u002Fli>\n   \u003Cli>\u003Ccode>*\u003C\u002Fcode>： 表示匹配0次或者多次\u003C\u002Fli>\n   \u003Cli>\u003Ccode>+\u003C\u002Fcode>： 表示匹配1次或者多次\u003C\u002Fli>\n   \u003Cli>\u003Ccode>fragment\u003C\u002Fcode>： 表示一个词法片段，可以被词法引用，但是不能在语法中使用，如 \u003Ccode>DIGIT\u003C\u002Fcode>可以在词法\u003Ccode>ID\u003C\u002Fcode>中使用，但是不能在\u003Ccode>calcu\u003C\u002Fcode>语法中使用，而未被 \u003Ccode>fragment\u003C\u002Fcode>标识的\u003Ccode>ID\u003C\u002Fcode>是可以在\u003Ccode>calcu\u003C\u002Fcode>语法中使用的。\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\n  \u003Cp>语法部分\u003C\u002Fp>\n  \u003Cp>各个语法的解释如下：\u003C\u002Fp>\n  \u003Cul>\n   \u003Cli>\n    \u003Cp>\u003Ccode>setArg\u003C\u002Fcode>语法表示变量定义语法，其包含三种规则，分别用来定义\u003Ccode>number\u003C\u002Fcode>、\u003Ccode>string\u003C\u002Fcode>、 \u003Ccode>boolean\u003C\u002Fcode>三种类型的变量，其中的词法\u003Ccode>ID\u003C\u002Fcode>是变量的名称\u003Ccode>=\u003C\u002Fcode>作为赋值符号将右边的值赋给变量，\u003Ccode>string\u003C\u002Fcode>、\u003Ccode>boolean\u003C\u002Fcode>的变量值都是固定的词法，\u003Ccode>number\u003C\u002Fcode>的值为\u003Ccode>calcu\u003C\u002Fcode>语法，而\u003Ccode>calcu\u003C\u002Fcode>语法的规则中包含了\u003Ccode>NUMBER\u003C\u002Fcode>词法，因此\u003Ccode>number\u003C\u002Fcode>变量定义时等号右侧可以是数值也可以是四则运算。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>calcu\u003C\u002Fcode>语法中新增了一个\u003Ccode>ID\u003C\u002Fcode>词法，因为\u003Ccode>ID\u003C\u002Fcode>词法是作为变量定义时的变量的名称的，所以\u003Ccode>calcu\u003C\u002Fcode>就支持了使用变量进行计算。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>print\u003C\u002Fcode>有三种规则，语法的括号内按照上文的设计原则分别匹配了变量、字符串和布尔型。\u003C\u002Fp>\u003C\u002Fli>\n   \u003Cli>\n    \u003Cp>\u003Ccode>main\u003C\u002Fcode>增加此语法是因为\u003Ccode>print\u003C\u002Fcode>和\u003Ccode>setArg\u003C\u002Fcode>之间不存在引用关系，是两种独立的语法，是两个独立的语法树，而在antlr4中想要将所有代码完整执行就只能存在一棵语法树，因此需要一个新的语法将两种语法关联到一起为最终形成一棵语法树做好准备�&#x8;\u003C\u002Fp>\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>&#x8;&#x8;&#xb;H&#x18;&#x1c;&#x1c;���:+�y��y.+yc깧\"x&#x1b;XZ[�9. 9��z+�y��{�#9\u002Fa��+�g*&#x18;&#x1b;XZ[�9�9d#�gh��\"x可表示匹配一个或多个，因此当代码中同时出现\u003Ccode>setArg\u003C\u002Fcode>和\u003Ccode>print\u003C\u002Fcode>时可以多次匹配，最终形成一棵完整的语法树。\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>对于`main`和`prog`两种语法可能相对比较难理解，简单的来说如果没有`prog`和`mian`时`setArg`和`calcu`只能独立使用，同时出现在代码中时语法检查无法通过。如果没有`prog`只有`mian`时，根据上一篇文章所讲的语法规则优先级，`setArg`和`calcu`同时出现在代码中时，写在后面的代码会被忽略掉，无法完整执行。\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>## 三、语法实现\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>接下来使用idea插件将定义好的.g4文件生成对应的java文件，使用新生成的java文件覆盖之前的文件，至此我们需要思考一个问题之前的文章中`MyRuleSetVisitor`继承`RuleSetBaseVisitor`后因为四则运算的返回值为数值型将泛型指定为了Double，在本次新增的语法中打印函数和变量定义均无返回值类型，该如何兼容这种情况呢？这就需要再定义一种类型，来兼容各种返回值类型，方便后续返回不同类型的值。\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>定义一个`VisitorResult`类如下：\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   * visitor访问语法树每个节点的返回结果\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   * 返回结果包含 三种类型 数值型（全部转为double）、字符串、布尔型，每次只可能返回三种类型中的一种，其他类型将抛出运行时异常\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@author\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> dongxingli\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   * createTime 2023\u002F5\u002F11\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@version\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> V1.0\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">   *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">   public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       private\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Object value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       private\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       private\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(Object \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> String \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           ||\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Double \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           ||\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Boolean \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           ||\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> null\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">               this\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">.value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"不支持的参数类型\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Boolean \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getBool\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isBoolean\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (Boolean) value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"非Boolean类型\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Double \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (Double) value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"非Number类型\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> String \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isVarchar\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (String) value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"非String类型\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> static\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(Object \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * 返回NULL\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@return\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> 结果类\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> static\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * 返回结果是否数值型\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@return\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> 是或否\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> boolean\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> isNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">.value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Number;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * 返回结果是否字符串\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@return\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> 是或否\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> boolean\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> isVarchar\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">.value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> String;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * 返回结果是否布尔型\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@return\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> 是或否\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> boolean\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> isBoolean\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">.value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Boolean;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * 返回结果是否为null\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       * \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">@return\u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\"> 是或否\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">       *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> boolean\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> isNull\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> null\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Object \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getValue\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">       public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> String \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">toString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">           if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Double.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">toString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">((Double) value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isVarchar\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (String) value;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isBoolean\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Boolean.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">toString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">((Boolean) value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">               throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"未知类型\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">           }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">       }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">   }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接下来使用\u003Ccode>VisitorResult\u003C\u002Fcode>类作为\u003Ccode>RuleSetBaseVisitor\u003C\u002Fcode>的泛型对之前的四则运算代码进行修改，并实现赋值与打印函数的功能，修改后的代码如下：\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> MyRuleSetVisitor\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuleSetBaseVisitor\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">VisitorResult\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">> { \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改泛型\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         * 语法中定义的参数，key为变量名称\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        private\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> final\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Map&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">String\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Object\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">> paramDefine \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> HashMap&#x3C;>();  \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F新增\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitAddAndSub\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.AddAndSubContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F 符号左边的calcu语法，\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F 它可能是一组带括号或不带括号甲减乘除运算，也可能是一个数字\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F 直接visit即可访问它的处理方法拿到最终返回结果\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            VisitorResult visit \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">calcu\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">));          \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            double\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> visit.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();                       \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F 符号右边的calcu语法\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            VisitorResult visit2 \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">calcu\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">));        \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            double\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> visit2.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();                    \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F通过别名获取opt类型判断是加还是减\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (ctx.opt.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getType\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> RuleSetLexer.ADD) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right);         \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">-\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right);        \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitMulAndDiv\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.MulAndDivContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            VisitorResult visit \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">calcu\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">));          \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            double\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> visit.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();                      \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            VisitorResult visit2 \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">calcu\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">));        \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            double\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> visit2.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();                    \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (ctx.opt.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getType\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> RuleSetLexer.MUL) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">*\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right);         \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            } \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(left \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">\u002F\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> right);         \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.NumberContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">            \u002F\u002F NUMBER词法直接转为double\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(Double.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">parseDouble\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">())); \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F修改\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F ---------------------------以下函数为本次新增----------------------------\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *定义数值类型变量，调用calcu进行计算完成后将变量值保存到map中\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitNumarg\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.NumargContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            VisitorResult visit \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">calcu\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            paramDefine.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">put\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.id.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(), visit.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getNumber\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *定义字符型变量，获取到字符串值后将变量值保存到map中\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitChararg\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.CharargContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            paramDefine.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">put\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.id.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(), ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">STRING\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *定义布尔型变量，获取到布尔值后将变量值保存到map中\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitBoolarg\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.BoolargContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            paramDefine.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">put\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.id.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(), ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">BOOL\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *获取所定义的变量值，根据变量名称从保存变量值的map中查找\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitArgValue\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.ArgValueContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            Object value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> paramDefine.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">get\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">instanceof\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> Double) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">value\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"未定义的参数：\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\"> \" 或参数\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> ctx.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">() \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\"> \"定义为非数值型\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *打印变量值，根据变量名称从保存变量值的map中查找后使用java打印方法进行打印\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitPrintArg\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.PrintArgContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            String argName \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> ctx.value.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            Object value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> paramDefine.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">get\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(argName);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (value \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> null\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">                throw\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuntimeException\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"未定义的变量：\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> argName);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(value);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> super\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitPrintArg\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *打印变量值，获取到布尔变量值后使用java打印方法进行打印\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitPrintBoolean\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.PrintBooleanContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.value.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F**\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">         *打印变量值，获取到字符串后使用java打印方法进行打印\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        @\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">Override\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        public\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult \u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visitPrintString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(RuleSetParser.PrintStringContext \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">ctx\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(ctx.value.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getText\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> VisitorResult.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">nil\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接下来编写测试代码，如下\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> Test\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> static\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> void\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> main\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">String\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">[] \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">args\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        String expression \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"number a = 1 \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"number b = 2 \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"number c = a + b * 3 \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"string d = \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\\"\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">字符串\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\\"\u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\"> \\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"boolean e = true \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"print(c) \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"print(d) \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">\\n\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> +\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">                        \"print(e)\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">        calcute\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(expression);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">    private\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> static\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> void\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> calcute\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(String \u003C\u002Fspan>\u003Cspan style=\"color:#E36209;--shiki-dark:#FFAB70\">expression\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"执行:\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(expression);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        MyRuleSetVisitor visitor \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> MyRuleSetVisitor\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        RuleSetLexer lexer \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuleSetLexer\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(CharStreams.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">fromString\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(expression));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        lexer.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">removeErrorListeners\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        LexicalErrorListener lexicalListener \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> LexicalErrorListener\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F添加词法错误监听\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        lexer.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">addErrorListener\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(lexicalListener);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        RuleSetParser parser \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> RuleSetParser\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> CommonTokenStream\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(lexer));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        parser.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">removeErrorListeners\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        GrammarErrorListener errorListener \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\"> GrammarErrorListener\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">        \u002F\u002F添加语法法错误监听\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        parser.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">addErrorListener\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(errorListener);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        RuleSetParser.ProgContext calcu \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> parser.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">prog\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(); \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F此处由calcu()改为prog()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        List&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">String\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">> lexicalError \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> lexicalListener.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getErrMessage\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        List&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">String\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">> grammarError \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> errorListener.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">getErrMessage\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">!\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">lexicalError.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isEmpty\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(lexicalError);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">        if\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">!\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">grammarError.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">isEmpty\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">()) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">            System.out.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">println\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(grammarError);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">            return\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">        VisitorResult result \u003C\u002Fspan>\u003Cspan style=\"color:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> visitor.\u003C\u002Fspan>\u003Cspan style=\"color:#6F42C1;--shiki-dark:#B392F0\">visit\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">(calcu);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>执行结果如下：\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>> Task :Test.main()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>执行:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>number a = 1 \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>number b = 2 \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>number c = a + b * 3 \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>string d = \"字符串\" \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>boolean e = true \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>print(c) \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>print(d) \u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>print(e)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>7.0\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\"字符串\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>根据以上执行结果可以看出，语法已经支持变量的定义及使用且计算结果正确，同时打印函数也可以正常使用，下一章节将继续完善语法，使其支持分支语句。\u003C\u002Fp>",[77,81],{"id":78,"text":79,"level":80},"toc-1","一、语法设计",2,{"id":82,"text":83,"level":80},"toc-2","二、语法定义"]