ebnf范式_基于EBNF语法的描述

基于JavaCC的语法描述

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

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

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

assign():

{}

{

"=" expr()

}

assign()对应赋值表达式,对应token标示符,"="对应"="token。

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

expr():

{}

{

expr() "+" expr()

或expr() "-" expr()

或expr() "*" expr()

..

.

}

终端符与非终端符

JavaCC中将"语句" "函数调用" "表达式" 等非token的语法单位称为非终端

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书系统介绍了经典的编译理论和技术,同时也包含了面向对象语言等当前较新语言的编译技术。本书更可贵之处在于提供了较完整的适用于教学实践的样例语言,是一本理论和实践内容相结合的、不可多得的好书。 本书可用作大专院校教材、教师参考书以及编译器研究人员的参考资料。 <br>目 录<br>译者序<br>前言<br>第1章 概论 1<br>1.1 为什么要用编译器 2<br>1.2 与编译器相关的程序 3<br>1.3 翻译步骤 5<br>1.4 编译器中的主要数据结构 8<br>1.5 编译器结构中的其他问题 10<br>1.6 自举与移植 12<br>1.7 TINY样本语言与编译器 14<br>1.7.1 TINY语言 15<br>1.7.2 TINY编译器 15<br>1.7.3 TM机 17<br>1.8 C-Minus:编译器项目的一种语言 18<br>练习 19<br>注意与参考 20<br>第2章 词法分析 21<br>2.1 扫描处理 21<br>2.2 正则表达式 23<br>2.2.1 正则表达式的定义 23<br>2.2.2 正则表达式的扩展 27<br>2.2.3 程序设计语言记号的正则表达式 29<br>2.3 有穷自动机 32<br>2.3.1 确定性有穷自动机的定义 32<br>2.3.2 先行、回溯和非确定性自动机 36<br>2.3.3 用代码实现有穷自动机 41<br>2.4 从正则表达式到DFA 45<br>2.4.1 从正则表达式到NFA 45<br>2.4.2 从NFA到DFA 48<br>2.4.3 利用子集构造模拟NFA 50<br>2.4.4 将DFA中的状态数最小化 51<br>2.5 TINY扫描程序的实现 52<br>2.5.1 为样本语言TINY实现一个扫描<br>程序 53<br>2.5.2 保留字与标识符 56<br>2.5.3 为标识符分配空间 57<br>2.6 利用Lex 自动生成扫描程序 57<br>2.6.1 正则表达式的Lex 约定 58<br>2.6.2 Lex输入文件的格式 59<br>2.6.3 使用Lex的TINY扫描程序 64<br>练习 65<br>编程练习 67<br>注意与参考 67<br>第3章 上下文无关文法及分析 69<br>3.1 分析过程 69<br>3.2 上下文无关文法 70<br>3.2.1 与正则表达式比较 70<br>3.2.2 上下文无关文法规则的说明 71<br>3.2.3 推导及由文法定义的语言 72<br>3.3 分析树与抽象语法树 77<br>3.3.1 分析树 77<br>3.3.2 抽象语法树 79<br>3.4 二义性 83<br>3.4.1 二义性文法 83<br>3.4.2 优先权和结合性 85<br>3.4.3 悬挂else问题 87<br>3.4.4 无关紧要的二义性 89<br>3.5 扩展的表示法:EBNF语法 89<br>3.5.1 EBNF表示法 89<br>3.5.2 语法 91<br>3.6 上下文无关语言的形式特性 93<br>3.6.1 上下文无关语言的形式定义 93<br>3.6.2 文法规则和等式 94<br>3.6.3 乔姆斯基层次和作为上下文无关<br>规则的语法局限 95<br>3.7 TINY语言的语法 97<br>3.7.1 TINY的上下文无关文法 97<br>3.7.2 TINY编译器的语法树结构 98<br>练习 101<br>注意与参考 104<br>第4章 自顶向下的分析 105<br>4.1 使用递归下降分析算法进行自顶向下<br>的分析 105<br>4.1.1 递归下降分析的基本方法 105<br>4.1.2 重复和选择:使用EBNF 107<br>4.1.3 其他决定问题 112<br>4.2 LL(1)分析 113<br>4.2.1 LL(1)分析的基本方法 113<br>4.2.2 LL(1)分析与算法 114<br>4.2.3 消除左递归和提取左因子 117<br>4.2.4 在LL(1)分析中构造语法树 124<br>4.3 First集合和Follow集合 125<br>4.3.1 First 集合 125<br>4.3.2 Follow 集合 130<br>4.3.3 构造LL(1)分析表 134<br>4.3.4 再向前:LL(k)分析程序 135<br>4.4 TINY语言的递归下降分析程序 136<br>4.5 自顶向下分析程序中的错误校正 137<br>4.5.1 在递归下降分析程序中的错误<br>校正 138<br>4.5.2 在LL(1)分析程序中的错误校正 140<br>4.5.3 在TINY分析程序中的错误校正 141<br>练习 143<br>编程练习 146<br>注意与参考 148<br>第5章 自底向上的分析 150<br>5.1 自底向上分析概览 151<br>5.2 LR(0)项的有穷自动机与LR(0)分析 153<br>5.2.1 LR(0)项 153<br>5.2.2 项目的有穷自动机 154<br>5.2.3 LR(0)分析算法 157<br>5.3 SLR(1)分析 160<br>5.3.1 SLR(1)分析算法 160<br>5.3.2 用于分析冲突的消除二义性<br>规则 163<br>5.3.3 SLR(1)分析能力的局限性 164<br>5.3.4 SLR(k)文法 165<br>5.4 一般的LR(1)和LALR(1)分析 166<br>5.4.1 LR(1)项的有穷自动机 166<br>5.4.2 LR(1)分析算法 169<br>5.4.3 LALR(1)分析 171<br>5.5 Yacc:一个LALR(1)分析程序的<br>生成器 173<br>5.5.1 Yacc基础 173<br>5.5.2 Yacc选项 176<br>5.5.3 分析冲突与消除二义性的规则 180<br>5.5.4 描述Yacc分析程序的执行 183<br>5.5.5 Yacc中的任意值类型 184<br>5.5.6 Yacc中嵌入的动作 185<br>5.6 使用Yacc生成TINY分析程序 186<br>5.7 自底向上分析程序中的错误校正 188<br>5.7.1 自底向上分析中的错误检测 188<br>5.7.2 应急方式错误校正 188<br>5.7.3 Yacc中的错误校正 189<br>5.7.4 TINY中的错误校正 192<br>练习 192<br>编程练习 195<br>注意与参考 197<br>第6章 语义分析 198<br>6.1 属性和属性文法 199<br>6.1.1 属性文法 200<br>6.1.2 属性文法的简化和扩充 206<br>6.2 属性计算算法 207<br>6.2.1 相关和赋值顺序 208<br>6.2.2 合成和继承属性 212<br>6.2.3 作为参数和返回值的属性 219<br>6.2.4 使用扩展数据结构存储属性值 221<br>6.2.5 语法分析时属性的计算 223<br>6.2.6 语法中属性计算的相关性 226<br>6.3 符号表 227<br>6.3.1 符号表的结构 228<br>6.3.2 说明 230<br>6.3.3 作用域规则和块结构 232<br>6.3.4 同层说明的相互作用 236<br>6.3.5 使用符号表的属性文法的一个<br>扩充例子 237<br>6.4 数据类型和类型检查 241<br>6.4.1 类型表达式和类型构造器 242<br>6.4.2 类型名、类型说明和递归类型 246<br>6.4.3 类型等价 248<br>6.4.4 类型推论和类型检查 253<br>6.4.5 类型检查的其他主题 255<br>6.5 TINY语言的语义分析 257<br>6.5.1 TINY的符号表 258<br>6.5.2 TINY语义分析程序 259<br>练习 260<br>编程练习 264<br>注意与参考 264<br>第7章 运行时环境 266<br>7.1 程序执行时的存储器组织 266<br>7.2 完全静态运行时环境 269<br>7.3 基于栈的运行时环境 271<br>7.3.1 没有局部过程的基于栈的环境 271<br>7.3.2 带有局部过程的基于栈的环境 281<br>7.3.3 带有过程参数的基于栈的环境 284<br>7.4 动态存储器 286<br>7.4.1 完全动态运行时环境 286<br>7.4.2 面向对象的语言中的动态存储器 287<br>7.4.3 堆管理 289<br>7.4.4 堆的自动管理 292<br>7.5 参数传递机制 292<br>7.5.1 值传递 293<br>7.5.2 引用传递 294<br>7.5.3 值结果传递 295<br>7.5.4 名字传递 295<br>7.6 TINY语言的运行时环境 296<br>练习 297<br>编程练习 303<br>注意与参考 304<br>第8章 代码生成 305<br>8.1 中间代码和用于代码生成的数据<br>结构 305<br>8.1.1 三地址码 306<br>8.1.2 用于实现三地址码的数据结构 308<br>8.1.3 P-代码 310<br>8.2 基本的代码生成技术 312<br>8.2.1 作为合成属性的中间代码或目标<br>代码 312<br>8.2.2 实际的代码生成 314<br>8.2.3 从中间代码生成目标代码 317<br>8.3 数据结构引用的代码生成 319<br>8.3.1 地址计算 319<br>8.3.2 数组引用 320<br>8.3.3 栈记录结构和指针引用 325<br>8.4 控制语句和逻辑表达式的代码生成 328<br>8.4.1 if 和while 语句的代码生成 328<br>8.4.2 标号的生成和回填 330<br>8.4.3 逻辑表达式的代码生成 330<br>8.4.4 if 和while 语句的代码生成过程<br>样例 331<br>8.5 过程和函数调用的代码生成 334<br>8.5.1 过程和函数的中间代码 334<br>8.5.2 函数定义和调用的代码生成过程 336<br>8.6 商用编译器中的代码生成:两个案<br>例研究 339<br>8.6.1 对于80×86的Borland 3.0版C编<br>译器 339<br>8.6.2 Sun SparcStation的Sun 2.0 C编<br>译器 343<br>8.7 TM:简单的目标机器 346<br>8.7.1 Tiny Machine的基本结构 347<br>8.7.2 TM模拟器 349<br>8.8 TINY语言的代码生成器 351<br>8.8.1 TINY代码生成器的TM接口 351<br>8.8.2 TINY代码生成器 352<br>8.8.3 用TINY编译器产生和使用TM<br>代码文件 354<br>8.8.4 TINY编译器生成的TM代码文<br>件示例 355<br>8.9 代码优化技术考察 357<br>8.9.1 代码优化的主要来源 358<br>8.9.2 优化分类 360<br>8.9.3 优化的数据结构和实现技术 362<br>8.10 TINY代码生成器的简单优化 366<br>8.10.1 将临时变量放入寄存器 366<br>8.10.2 在寄存器中保存变量 367<br>8.10.3 优化测试表达式 367<br>练习 368<br>编程练习 371<br>注意与参考 372<br>附录A 编译器设计方案 373<br>附录B 小型编译器列表 381<br>附录C Tiny Machine模拟器列表 417<br>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值