后台网站建设招聘局门户网站建设的目标
2026/3/29 16:51:16 网站建设 项目流程
后台网站建设招聘,局门户网站建设的目标,网站建设的项目计划书,彩票网站APP建设antlr4总结 算符优先级问题 同一条规则内#xff0c;运算符分支在前的#xff0c;优先级越高#xff0c;比如#xff1a; expr : expr op(|-) expr #AddSub| expr op(*|/) expr #MulDiv会认为加减运算符优先于乘除运算符#xff0c;这样在计算12*3时#xff…antlr4总结算符优先级问题同一条规则内运算符分支在前的优先级越高比如expr : expr op(|-) expr #AddSub | expr op(*|/) expr #MulDiv会认为加减运算符优先于乘除运算符这样在计算12*3时就会得到错误的结果9。正确的写法是乘除分支在前expr : expr op(*|/) expr #MulDiv | expr op(|-) expr #AddSub算符右结合问题antlr默认是算符左结合像幂运算这样的算符一般要求右结合可以这么写expr : assocright expr ** expr #power | expr op(*|/|%) expr #MulDiv | expr op(|-) expr #AddSub | ( expr ) #Parens注意assocright要写在分支的最左边写在其它位置会有warning。多分支下的标签不可省略多分支规则里要么所有分支给标签否则无法为每个分支自动生成visit函数要么所有分支都不给标签。上例中#AddSub就是一个分支标签这条规则里的每个分支都要有一个标签这样antlr会自动为每个分支生成一个visit函数方便使用者来处理。比如OverridepublicTvisitMulDiv(LumenParser.MulDivContextctx)...OverridepublicTvisitAddSub(LumenParser.AddSubContextctx)单分支规则自然无需手写标签antlr会自动生成visit函数。字面量字面量可以是一个字符也可以是字符串。必须用单引号括起来。下面是例子STRING : (~[\r\n])* ; BOOL : true | false ;上例中true和false都是字符串字面量。错误处理两种方式一个是定制自己的BaseErrorListenerpublicclassSyntaxErrorListenerextendsBaseErrorListener{privateSourcesource;publicSyntaxErrorListener(Sourcesource){this.sourcesource;}OverridepublicvoidsyntaxError(Recognizer?,?recognizer,ObjectoffendingSymbol,intline,intcharPositionInLine,Stringmsg,RecognitionExceptione){// line 和 charPositionInLine 就是错误的行列号StringsourceNamesource.getName();if(!sourceName.isEmpty()){sourceNameString.format(%s:%d:%d: ,sourceName,line,charPositionInLine);}System.err.println(sourceNamemsg);}}然后设置这个Listenerparser.addErrorListener(newSyntaxErrorListener(request.getSource()));parser就是antlr自动为我们生成的语法解析器。antlr框架会在出现语法错误时调用BaseErrorListener然后恢复错误继续解析。若有运行时错误可在每个grammar node里塞入行列号信息从antlr的ParserRuleContext里即可获得比如publicNodesupplySourceSection(Sourcesource,ParserRuleContextctx){Tokenstartctx.getStart();Tokenstopctx.getStop();// 可能为 nullEOFintstartLinestart.getLine();intstartColstart.getCharPositionInLine()1;intendLine(stop!null?stop.getLine():startLine);intendCol(stop!null?stop.getCharPositionInLine()1:startCol);this.sourceSectionsource.createSection(startLine,startCol,endLine,endCol);returnthis;}我这里使用的是graal vm的truffle框架所以把行列号信息设置为每个语法节点的SourceSection。这样当执行到特定节点出错时就可以报出详细的行列号信息。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询