【读书笔记】-【编程语言的实现模式】-【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解析器 ...
随机推荐
- Base: 一种 Acid 的替代方案
原文链接: BASE: An Acid Alternative Pdf下载链接: Base 数据库 ACID,都不陌生:原子性.一致性.隔离性和持久性,这在单台服务器就能搞定的时代,很容易实现,但是到 ...
- [LeetCode] Find Median from Data Stream
Find Median from Data Stream Median is the middle value in an ordered integer list. If the size of t ...
- VirtualBox不能为虚拟电脑 Ubuntu 打开一个新任务
今天在用Vbox中的Ubuntu系统准备测试Python代码时,Vbox报了一个错误:"不能为虚拟电脑 Ubuntu 打开一个新任务".因为之前用的时候还好好的,也不知道是不是最近 ...
- JAVA常见错误处理方法 和 JVM内存结构
OutOfMemoryError在开发过程中是司空见惯的,遇到这个错误,新手程序员都知道从两个方面入手来解决:一是排查程序是否有BUG导致内存泄漏:二是调整JVM启动参数增大内存.OutOfMemor ...
- 【原】 COCOS2D—LUA 获取剪贴板内容
android下: local luaj = require ("framework.luaj") local ok,ret = luaj.callStaticMethod( ...
- Xcode报错:“Your build settings specify a provisioning profile with the UUID..... however, no such provisioning profile was found”
运行环境: Xcode5 & 5.0及以上版本 对工程进行Archive打包的时候出现如下错误 问题描述: Code Sign error: No matching provisionin ...
- Invalid Image Path - No image found at the path referenced under key "CFBundleIconFile": Icon.png
I got the same error when uploading my app. Moving all icon files to the Asset Catalog works if your ...
- 创建 iPhone/iOS8 弹出菜单(窗口)
基本步骤 添加视图:主视图与弹出视图 关联视图 配置弹出视图 编码实现:弹出菜单样式及控制器委托 override func prepareForSegue(segue: UIStoryboardSe ...
- [转]阎宏博士的JAVA与模式
阎宏,1964年出生于天津市.1987年毕业于中国科技大学近代物理系,1990年于中科院理论物理所获硕士学位,1992年获博士学位,翌年赴日本京都大学进行博士后研究工作. 作者曾于美国花旗银行(Cit ...
- iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)
本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...