语法选择冲突

在解释什么事语法选择冲突之前,先看一个语文相关的不太恰当的例子,这个例子对理解语法选择冲突有帮助。

特别是2,3的,他们的前3字都是一样的,但是他们的含义是不同的,2是“为” “了解” ,3是“为了” “解决”。对于人的思维来说能够快速的分辨出其中的区别,但是对计算机来说并不简单。如果能明白上面的例子,那么差不多就能理解javacc中的语法选择冲突大概是怎么一会事了。

现在就看一下javacc出现了语法选择冲突的例子。

void  parse():
{}
{assignExp()| functionExp()}void assignExp():
{Token t;double v;
}
{t=<ID> <EQUALS> v=calc(){//TODO 实现赋值表达式的动作System.out.println(t.image+"="+v);}}void functionExp():
{Token t;
}
{<ID> <LPAREN> (<ID>(<COMMA> <ID>)*)?<RPAREN>
}

在对这个jj文件执行javacc命令时候,会抛出这样的提示信息

Warning: Choice conflict involving two expansions atline 66, column 4 and line 67, column 6 respectively.A common prefix is: <ID>Consider using a lookahead of 2 for earlier expansion.

这提示就是告诉你,有两个选择冲突,因为他们的都是以<ID>token开头的,以及他们在语法文件的位置信息,并建议你用lookahead去处理这个冲突。也就说当javacc解析到<ID>时,有两条路可以走,但是这条路的路标和路口太相似了,javacc不知道该选着哪条路。

说白了就是javacc默认是生成LL(1) 解析器,为了保持解析性能,javacc不会自动的去处理这种需要向前探索才能确定语法分支的事情,但是它提供了lookahead让用户主动指定要如何向前探索功能,通过此功能,javacc就可以处理上面的语法选择冲突。

LOOKAHEAD

顾名思义就是展望,前瞻探索的含义。

当消费token的语法指针P在token1的位置时碰到了lookahead命令,就会派出L指针前去探查后面的token是否符号lookaheand的定义,如果符合就选择该语法分支,不符合就选择别的分支。

lookahead的构造方式如下

LOOKAHEAD ( amount, expansion, { boolean_expression } )

使用时必须至少存在三个条件中的一个。如果存在多个,则用逗号分隔。

amount  表示要展望的token数量,当expansion存在时,而没有明确指定amount  时默认是2147483647,其他情况,如果没有在options里指定默认的lookahead的amount数量则默认是0。

expansion 表示要展望的匹配的规则表达式,默认是当前分支要扩展的规则。

boolean_expression 布尔表达式,默认是true。

例子1:

//还是以解决上面的冲突为例子
void  parse():
{}
{LOOKAHEAD(2)assignExp()| functionExp()}

通过在第一个分支上加上了lookahead(2)解决了语法选择冲突,这个lookahead的含义是,先去展望2个token,看看这两个token是否跟  <ID> "=" 匹配,此时它等价与

LOOKAHEAD(2,<ID> <EQUALS>)

例子2:

void TypeDeclaration() :
{}
{LOOKAHEAD(ClassDeclaration())ClassDeclaration()
|InterfaceDeclaration()
}

这个lookahead的含义是,先去展望token,直到展望的token完全匹配ClassDeclaration的定义并且展望的token数小于2147483647。其实不建议这样使用lookahead,这样的效率是比较低下,应该尽可能的完善lookahead的匹配条件,例如可以改成这样

void TypeDeclaration() :
{}
{LOOKAHEAD(10, ( "abstract" | "final" | "public" )* "class" )ClassDeclaration()
|InterfaceDeclaration()
}

例子3:

void BC() :
{}
{"b"[ LOOKAHEAD( { getToken(1).kind == C && getToken(2).kind != C } )<C:"c">]
}

其含义,当消费token到“b”时,先去执行一下布尔表达式,看看是否符号布尔表达式条件,符号就往下走对应的语法分支。这个 布尔表达式是先判断一下下一个(getToken(1).kind)==c并且下下个(getToken(2).kind)!= c。

上一篇:JAVACC使用总结(三):通过四则运算解析,初探语法分析_IT不码农的博客-CSDN博客

下一篇: JAVACC使用总结(五):语法进阶-集合函数递归脚步_IT不码农的博客-CSDN博客

JAVACC使用总结(四):LOOKAHEAD解决语法选择冲突的利刃相关推荐

  1. ie11不兼容java_IE11浏览器网页不兼容的四种解决方法

    Edge浏览器已然成为最新win10系统的默认浏览器,但是用户量却远远不及IE11,IE11虽然性能得到了大的改进,但在浏览网页的时候还是会出现一些兼容性的问题,下面小编就讲为大家分享IE 11浏览器 ...

  2. w7计算机防火墙无法更改,win7系统提示防火墙无法更改某些设置错误代码0x8007437的原因及四种解决方法...

    win7系统提示"防火墙无法更改某些设置,错误代码0x8007437",这该怎么办呢?下面脚本之家的小编就带来win7系统提示防火墙无法更改某些设置错误代码0x8007437的原因 ...

  3. win10系统如果更改战网服务器,win10系统无法登录战网的四种解决方法

    很多游戏玩家们在windows10系统电脑中,都碰到了无法登录战网进行游戏的情况,这该怎么办呢?我们要如何解决呢?在下面,系统城小编给大家整理了一大波win10系统无法登录战网的解决方案!感兴趣的朋友 ...

  4. Eclipse SVN 冲突的 介绍 及 四种解决方式

    1.为什么会出现冲突 <1>两个开发人员,Harry和Sally,分别从服务器端下载了文件A. <2>Harry修改之后,A变成了A',Sally修改之后,A变成了A" ...

  5. W ndows主进程已停止,windows主进程rundll32已停止工作的四种解决方法介绍

    操作系统出现:windows主进程rundll32已停止工作 这种出错的提示,一般是在Windows7操作系统之中,可能会有很多种原因导致的,所以还需要逐一排查,解决之. 这是一个很少见的问题,开机后 ...

  6. 计算机提示无法识别优盘,win7电脑无法识别u盘的四种解决方法

    很多朋友把U盘插win7电脑拷贝资料文件的时候发现没响应,提示无法识别,重新拔插了之后也无法读取.检查确定自己U盘没有问题,那么很可能是系统设置出现问题,这该怎么解决?针对此疑问,小编和大家说下win ...

  7. 微信 android 闪退问题怎么解决方法,如何解决微信闪退问题 四种解决微信闪退无法登录的原因及方法分享...

    微信闪退无法登录怎么办?现在使用微信的用户越来越多,即方便又快捷,有的朋友在使用时候可能会遇到微信闪退无法登陆的情况,今天小编为大家带来了四种解决微信闪退无法登录的原因及方法分享,感兴趣的朋友快来了解 ...

  8. Springboot单体架构搭建|第四章 前端框架选择和菜单管理

    第四章 前端框架选择和菜单管理 前言 vue-element-admin 改造vue-element-admin 菜单管理 用户&&角色&&菜单 总结 前言 该架构是参 ...

  9. 计算机颜色偏蓝,电脑屏幕颜色偏蓝的四种解决方法

    电脑用久了显示器会出现偏色,比如电脑屏幕颜色偏蓝,虽然不影响正常使用,但看着就不舒服,看久了会影响眼睛视力.有什么办法解决?针对此问题,今天小编给大家整理了显示颜色不正常的原因及其及解决方法. 方案一 ...

  10. 台式计算机显示器发蓝,电脑屏幕颜色偏蓝的四种解决方法

    电脑用久了显示器会出现偏色,比如电脑屏幕颜色偏蓝,虽然不影响正常使用,但看着就不舒服,看久了会影响眼睛视力.有什么办法解决?针对此问题,今天小编给大家整理了显示颜色不正常的原因及其及解决方法. 方案一 ...

最新文章

  1. 8 Great Java 8 Features No One's Talking about--转载
  2. 阿里云 Serverless 助力企业全面拥抱云原生
  3. 素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现)
  4. 阿诗玛的传说|阿诗玛民间故事
  5. 提取多个字段_动态合并多个工作表,数据再多也不怕
  6. canvas路径剪切和判断是否在路径内
  7. linux分区没有cde显示,HP unix无法进入CDE的排查步骤
  8. exists sql用法_彻底弄懂sql select各种查询用法
  9. NumPy:数组计算
  10. @SuppressWarnings(resource)
  11. 苹果Mac修改图标的一种简单方法
  12. 阿里 Lindorm 数据库联手 Hightopo ,开启工业物联超融合存储模式
  13. 《Git 教程 - 廖雪峰》
  14. 3d打印计算机设计打孔操作,干货:3D打印,建模时你需要注意这10个技巧
  15. Jinji2 模板引擎简介
  16. 2022年第十七届研电赛报名|安谋科技(Arm China)命题:基于特定开发平台的理性智能体设计
  17. 第九届蓝桥杯JavaB组省赛真题
  18. 沐风老师3dsMax手把手教系列:椅子建模(款式001)
  19. 【王道】操作系统OS第二章进程管理(二[1])
  20. ImportError: Couldn‘t import Django

热门文章

  1. Cisco(61)——双出口策略路由PBR+NAT
  2. 中国省市区 json
  3. 小白入门必学——python循环语句
  4. 可视化常用效果,js+css 实现人物百分比、象形图
  5. 苹果录屏没声音_不会真有人MacBook录屏没声音吧?别用了SoundFlower了!
  6. 古人说的雅事,通常是做什么?
  7. 计算机管理调整磁盘分区,win7系统硬盘分区调整方法图解
  8. 中国新药研发方向与国外存在较大差异
  9. love2d 1. 入门
  10. 漫聊科技发展史——1. 人工智能的发展史