基于JavaCC的语法描述

使用JavaCC从token序列中识别出"语句" “表达式” “函数调用” 等语法单位的方法。

只要为JavaCC描述“语句” “表达式” “函数调用” 这样的语法单位各自是由怎样的token序列构成的,就能够对该语法进行分析(parse)。

例如:最简单的赋值表达式可以描述为“符号” “ “=” ” ”表达式“ 的排列。 换言之, 如果存在”符号“ ” ”=“ “ ”表达式“ 这样的排列 那就是赋值表达式。这个规则在JavaCC中表示成下面这样:

assign():
{}
{
  <IDENTIFIER> "=" expr()
}

assign()对应赋值表达式,<IDENTIFIER>对应token标示符,"="对应"="token。
像<IDENTIFIER>这样已经在扫描器中定义的token,在描述解析器时可以直接使用。其他的如"="这样的固定字符串也因为可以表示token,所以也能在规则中使用。 另外,表达式expr()自身也是多个token构成的,这样的情况下需要进一步对expr()的规则进行描述,以下是伪描述:

expr():
{}
{
expr() "+" expr()
或expr() "-" expr()
或expr() "*" expr()
..
.
}

终端符与非终端符

JavaCC中将"语句" "函数调用" "表达式" 等非token的语法单位称为非终端符,并将非终端符像java的函数调用一样在后面加上括号写成stmt()或expr()。
终端符可以归纳为token。使用在扫描器中定义的名称,可以写成<INDENTIFIER>或<LONG>。并且JavaCC中除了扫描器中定义的token以外, "="、"+"、"==" 这样的字符串字面量也可以作为终端符来使用

种类 含义
终端符 token <IDENTIFIER>、<LONG>、"="、"=="
非终端符 由终端符排列组成的语法单位 stmt()、expr()、assign()

在画语法时,终端符位于树的枝干的末端(终端),非终端符由于是由其他符号的列组成的,所以位于分叉处。

JavaCC的EBNF表示法

JavaCC使用EBNF(Extended Backus-Naur-Form)的表示法来描述语法规则。下表中罗列了JavaCC的解析器生成所使用的EBNF表示法。

种类 例子
终端符 <IDENTIFIER>或","
非终端符 name()
连接 <UNISGNED><LONG>
重复0次或多次 (","expr())*
重复1次或多次 (stmt())+
选择 <CHAR>丨<SHORT>丨<INT>丨<LONG>
可以省略 [<ELSE>stmt()]

1. 连接

连接是指特定符号相连续的模式。例如C语言continue语句是保留字continue和分号的排列。JavaCC中将该规则写成如下形式:

<CONTINUE> ";"

<CONTINUE>是表示保留字continue的终端符,“:”是表示字符自身的终端符。

2. 重复0次或多次

下面的写法表示0个或多个语句排列:

(stmt())*

下面的例子,函数的参数是由逗号分隔的表达式排列组成的,即expr之后排列着0个或多个逗号和expr的组合:

expr() ("," expt())*

3. 重复1次或多次

(stmt())+

上面的代码描述了非终端符stmt()重复1次或多次。

4. 选择

选择即为从多个选项中选择1个的规则。例如cflat的类型由void、char、unsigned、char等:

<VOID> | <CHAR> | <UNSIGNED> | <CHAR> | ...

5. 可以省略

定义变量时可以设置初始值也可以不设置,这种在JavaCC中可以写成:

storage() typeref() name() ["=" expr()] ";"

基于EBNF语法的描述的更多相关文章

  1. 基于HOG-3D的时空描述子

    作者提出一种新的基于局部描述子的行为识别算法.

  2. Flink 的Window 操作(基于flink 1.3描述)

    Window是无限数据流处理的核心,Window将一个无限的stream拆分成有限大小的”buckets”桶,我们可以在这些桶上做计算操作.本文主要聚焦于在Flink中如何进行窗口操作,以及程序员如何 ...

  3. 网站实现微信登录之回调函数中登录逻辑的处理--基于yii2开发的描述

    上一篇文章网站实现微信登录之嵌入二维码中描述了如何在自己的登录页面内嵌入登录二维码,今天的这篇文章主要是描述下在扫码成功之后微信重定向回网站后登录逻辑的处理,其实也就是验证身份信息,授权用户登录的逻辑 ...

  4. 网站实现微信登录之嵌入二维码——基于yii2开发的描述

    之前写了一篇yii2获取登录前的页面url地址的文章,然后发现自己对于网站实现微信扫码登录功能的实现不是很熟悉,所以,我会写2-3篇的文章来描述下一个站点如何实现微信扫码登录的功能,来复习下微信扫码登 ...

  5. 【转】微信小程序原理

    微信小程序原理 kamidox 关注 2016.11.05 09:42* 字数 2356 阅读 14621评论 5喜欢 75赞赏 1 微信小程序使用了前端技术栈 JavaScript/WXML/WXS ...

  6. 用25行JavaScript语句实现一个简单的编译器

    原文:https://www.iteye.com/news/32680 译者注:即使对于专业程序员来说,构造一个编译器也是颇具挑战性的任务,本文将会引导你抽丝剥茧,一探究竟! 我已经写了几篇与编程语言 ...

  7. xmake 描述语法和作用域详解

    xmake的工程描述文件xmake.lua虽然基于lua语法,但是为了使得更加方便简洁得编写项目构建逻辑,xmake对其进行了一层封装,使得编写xmake.lua不会像些makefile那样繁琐 基本 ...

  8. 基于语法分析器GOLD Parser开发的数学表达式计算器

    最近发现一款文法分析神器,看完官网(http://goldparser.org/)的介绍后感觉很犀利的样子,于是就拿来测试了一番,写了一个数学表达式分析的小程序,支持的数学运算符如下所示:常规运算:+ ...

  9. ANTLR4权威指南 - 第5章 设计语法

    在第I部分,我们熟悉了ANTLR,并在一个比较高的层次上了解了语法以及语言程序.现在,我们将要放慢速度来学习下实现更实用任务的一些细节上的技巧,例如建立内部数据结构,提取信息,生成输入对应的翻译内容等 ...

随机推荐

  1. flask内容

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  2. JS_高程4.变量,作用域和内存问题(1)

    1.基本类型和应用类型的值 ECMAScript变量可能包含两种不同数据类型的值: 基本类型值——简单的数据段.(5种基本的数据类型,按值访问,因为可以操作保存在变量中的实际的值.) 引用类型值——多 ...

  3. hql 语法详解

    HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hib ...

  4. Hibernate(11)_基于外键的双向1对1

    一.基于外键的双向1对1 对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素.为many-to-one元素增加unique="true&q ...

  5. Java身份证归属地目录树

    数据库结构: web管理界面: 目录树: 视频: 应用场景:

  6. SOFABolt 源码分析

    SOFABolt 是一个轻量级.高性能.易用的远程通信框架,基于netty4.1,由蚂蚁金服开源. 本系列博客会分析 SOFABolt 的使用姿势,设计方案及详细的源码解析.后续还会分析 SOFABo ...

  7. Android:困扰了我一个晚上的问题 Failed to resolve: com.android.support:recyclerview-v7.25.3.1

      为了解决这个问题,做了各种尝试: 1)重装sdk: 2)重装android studio: 最终发现是一个标点符号搞错了,如下:   而且通过查找这个问题,了解到: 1)sdk路径,<use ...

  8. spring mvc \ spring boot 允许跨域请求 配置类

    用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...

  9. Linux系统下分析内存使用情况的管理工具

    有许多办法可以获得Linux系统上所安装内存的信息,并查看其中有多少内存正在使用中.有的命令会展示大量的细节,而有的命令则提供了简洁(但不一定容易理解)的结果.在这篇文章中将介绍一些更有用的工具,帮助 ...

  10. Win10系统的SurfacePro4无法修改启动顺序怎么办

    必须要把底部的开关关闭,否则启动顺序无法修改