【读书笔记】-【编程语言的实现模式】-【LL(1)递归下降的语法解析器】
形如:[a,b,c] [a,[b,cd],f] 为 嵌套列表
其ANTLR文法表示:
list :'[' elements ']'; // 匹配方括号
elements : elements (',' element)*; // 匹配list的逗号
element : NAME | list; // element是NAME或者嵌套的list
NAME : ('a'..'z' | 'A'..'Z')+; // NAME含有至少一个字母
具体实现:
```
public class Token {
public int type;
public String text;
public Token(int type, String text) {
this.type = type;
this.text = text;
}
@Override
public String toString() {
String tname = ListLexer.tokenNames[type];
return "";
}
}
```
```
public class ListLexer extends Lexer{
public static int NAME = 2;
public static int COMMA = 3;
public static int LBRACK = 4;
public static int RBRACK = 5;
public static String[] tokenNames = {"n/a","","NAME","COMMA","LBRACK","RBRACK"};
public String getTokenName(int x) {
return tokenNames[x];
}
boolean isLETTER() {
return c >= 'a' && c = 'A' && c ");
}
Token NAME() {
// NAME由一个或者多个字母组成
StringBuilder buf = new StringBuilder();
do {
buf.append(c);
consume();
} while(isLETTER());
return new Token(NAME, buf.toString());
}
void WS() {
// 忽略所有空白符
while (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
consume();
}
}
}
```
```
public abstract class Lexer {
public static final char EOF = (char)-1;
public static final int EOF_TYPE = 1; // 表示EOF的词法类型
String input; // 待解析的字符串
int p = 0; // 当前输入字符串的下标
char c; // 当前字符
public Lexer(String input) {
this.input = input;
c = input.charAt(p);
}
public void consume() {
// 向前移动一个字符,检验输入是否结束
p++;
if (p >= input.length()) {
c = EOF;
} else {
c = input.charAt(p);
}
}
public void match(char x) {
if (c == x) {
consume();
} else {
throw new Error("expecting "+ x + "; found"+c);
}
}
public abstract Token nextToken();
public abstract String getTokenName(int tokenType);
}
```
```
public class ListParser extends Parser{
public ListParser(Lexer input) {
super(input);
}
public void list() {
match(ListLexer.LBRACK);
elements();
match(ListLexer.RBRACK);
}
void elements() {
element();
while(lookahead.type == ListLexer.COMMA) {
match(ListLexer.COMMA);
element();
}
}
void element() {
if (lookahead.type == ListLexer.NAME) {
match(ListLexer.NAME);
} else if(lookahead.type == ListLexer.LBRACK) {
list();
} else {
throw new Error("expecting name or list; found"+lookahead);
}
}
}
```
```
public class Parser {
Lexer input;
Token lookahead;
public Parser(Lexer input) {
this.input = input;
consume();
}
public void match(int x) {
if (lookahead.type == x) {
consume();
} else {
throw new Error("expecting "+ input.getTokenName(x) + "; found"+ lookahead);
}
}
public void consume() {
lookahead = input.nextToken();
}
}
```
```
public class TestParser {
public static void main(String[] args) {
ListLexer lexer = new ListLexer("[a,[b,ccb],c]");
ListParser parser = new ListParser(lexer);
parser.list();
}
}
```
【读书笔记】-【编程语言的实现模式】-【LL(1)递归下降的语法解析器】的更多相关文章
- HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...
- 《JavaScript设计模式与开发实践》读书笔记之中介者模式
1. 中介者模式 中介者模式的作用就是用来解除对象与对象之间的紧耦合关系,增加中介者后,所有相关对象都通过中介者来通信,而不再相互引用 1.1中介者模式的例子 以泡泡堂游戏为例,先定义一个玩家构造函数 ...
- 《JavaScript设计模式与开发实践》读书笔记之享元模式
1. 享元模式 享元模式是一种用于性能优化的模式,享元模式的核心是运用共享技术来有效支持大量细粒度的对象 1.1 传统的文件上传方法 以文件上传为例,文件上传功能可以选择依照队列,一个一个的排队上传, ...
- ARM体系结构与编程读书笔记——处理器的运行模式
ARM处理器共有7种运行模式,如下表: 处理器模式 描述 用户模式(User, usr) 正常程序执行的模式 快速中断模式(FIQ, fiq) 用于高速数据传输和通道处理 外部中断模式(IRQ, ir ...
- 《图解设计模式》读书笔记2-2 Factory Method模式
目录 类图 代码 角色介绍 思想 类图 代码 //产品类,任意可"use"的产品都可继承该类 public abstract class Product { public abst ...
- 《图解设计模式》读书笔记2-1 Template Method模式
目录 模板方法模式 类图 思想: 模板方法模式 在父类中定义流程,在子类中实现具体的方法. 类图 代码 //抽象类 public abstract class AbstractDisplay { pu ...
- 【读书笔记】iOS-设计模式
一个可复用的解决方案,用于处理特定场景下的常见问题.一种设计模式并不是一个可以直接转化为代码的已完工设计.它是对于如何解决问题的一种描述或者模板,可以用在许多不同的场合. 参考资料:<iOS W ...
- Android(java)学习笔记187:Android中操作XML数据(使用Pull解析器)
1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...
- Android(java)学习笔记130:Android中操作XML数据(使用Pull解析器)
1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...
随机推荐
- Metaweblog在Android上使用
同步发表于http://avenwu.net/2015/02/04/metaweblog metaweblog是一个博客接口协议,目前主流的博客平台均支持该协议,比如博客园,CSDN,WordPres ...
- asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” http:// ...
- IIS网站属性中没有ASP.NET选项
打开IIS6,右击属性,居然没有发现ASP.NET的配置选项,虽然好久没搞这个了,但是印象中绝对是有一个ASP.NET选项卡的.我很奇怪,我以为是.net framework 2.0没安装,下载下来安 ...
- Xcode8新特性和iOS10新特性
从 Xcode 8.0 开始,目前所有的插件都无法工作! NSLog 无法输出 -- 此bug等待正式版本... Xcode 提供了文档注释快捷键option + cmd + / 但是要把系统升级到1 ...
- 【转】sql里面的split
CREATE function [dbo].[SplitString]( @Input nvarchar(max), @Separator nvarchar(max)=',', @RemoveEmpt ...
- __new__ 的简单应用
用__new__与__init__不同,通过继承内建类型对象,__new__可以用来创建一个简单的新类型,在__new__加入一些动作以完成创建. class RoundFloat(float): d ...
- 测试卡尔曼滤波器(Kalman Filter)
真实的温度测试数据,通过加热棒加热一盆水测得的真实数据,X轴是时间秒,Y轴是温度: 1)滤波前 2)滤波后(p=10, q=0.0001, r=0.05, kGain=0;) 2)滤波后(p=10, ...
- drupal7 Views Bulk Operations (VBO)
介绍 drupal通常用views制作列表,列表也应该能实现某些操作,例如删除.审批等,并且应该是批量进行的,VBO的存在就是为了实现views批量操作功能.事实上,drupal把操作统称为actio ...
- 浅析MongoDB数据库的海量数据存储应用
[摘要]当今已进入大数据时代,特别是大规模互联网web2.0应用不断发展及云计算所需要的海量存储和海量计算发展,传统的关系型数据库已无法满足这方面的需求.随着NoSQL数据库的不断发展和成熟,可以较好 ...
- [LeetCode] 桶排序的特殊解,例 Sort Color
Sort Colors Given an array with n objects colored red, white or blue, sort them so that objects of t ...