形如:[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)递归下降的语法解析器】的更多相关文章

  1. HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)

    装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...

  2. 《JavaScript设计模式与开发实践》读书笔记之中介者模式

    1. 中介者模式 中介者模式的作用就是用来解除对象与对象之间的紧耦合关系,增加中介者后,所有相关对象都通过中介者来通信,而不再相互引用 1.1中介者模式的例子 以泡泡堂游戏为例,先定义一个玩家构造函数 ...

  3. 《JavaScript设计模式与开发实践》读书笔记之享元模式

    1. 享元模式 享元模式是一种用于性能优化的模式,享元模式的核心是运用共享技术来有效支持大量细粒度的对象 1.1 传统的文件上传方法 以文件上传为例,文件上传功能可以选择依照队列,一个一个的排队上传, ...

  4. ARM体系结构与编程读书笔记——处理器的运行模式

    ARM处理器共有7种运行模式,如下表: 处理器模式 描述 用户模式(User, usr) 正常程序执行的模式 快速中断模式(FIQ, fiq) 用于高速数据传输和通道处理 外部中断模式(IRQ, ir ...

  5. 《图解设计模式》读书笔记2-2 Factory Method模式

    目录 类图 代码 角色介绍 思想 类图 代码 //产品类,任意可"use"的产品都可继承该类 public abstract class Product { public abst ...

  6. 《图解设计模式》读书笔记2-1 Template Method模式

    目录 模板方法模式 类图 思想: 模板方法模式 在父类中定义流程,在子类中实现具体的方法. 类图 代码 //抽象类 public abstract class AbstractDisplay { pu ...

  7. 【读书笔记】iOS-设计模式

    一个可复用的解决方案,用于处理特定场景下的常见问题.一种设计模式并不是一个可以直接转化为代码的已完工设计.它是对于如何解决问题的一种描述或者模板,可以用在许多不同的场合. 参考资料:<iOS W ...

  8. Android(java)学习笔记187:Android中操作XML数据(使用Pull解析器)

    1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...

  9. Android(java)学习笔记130:Android中操作XML数据(使用Pull解析器)

    1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...

随机推荐

  1. IOS APP 国际化 程序内切换语言实现 不重新启动系统(支持项目中stroyboard 、xib 混用。完美解决方案)

    上篇 IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源 介绍了纯代码刷新 实现程序内切换语言. 但效率底下,也存在一些问题.暂放弃. ...

  2. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  3. Kernel Function--核函数收集

    转自 http://www.zhizhihu.com/html/y2010/2292.html Kernel Functions Below is a list of some kernel func ...

  4. OGG-01232 Receive TCP params error: TCP/IP error 104 (Connection reset by peer), endpoint:

    源端: 2015-02-05 17:45:49 INFO OGG-01815 Virtual Memory Facilities for: COM anon alloc: mmap(MAP_ANON) ...

  5. Linux 求文件交集 差集等

    使用comm命令 假设两个文件FILE1和FILE2用集合A和B表示,FILE1内容如下: a b c e d a FILE2内容如下: c d a c 基本上有两个方法,一个是comm命令,一个是g ...

  6. Android杂谈--小知识点总结(1)

    此知识点总结是开发过程中遇到的比较棘手或者恶心的地方,所以随时更新,以备不时之需 1. viewFlipper中的item如何动态设置高度? 例如: <ViewFlipper android:l ...

  7. Spring3 MVC请求参数获取的几种方法

    Spring3 MVC请求参数获取的几种方法 一.      通过@PathVariabl获取路径中的参数 @RequestMapping(value="user/{id}/{name}&q ...

  8. Web服务器性能监控分析与优化

    Web服务器性能监控分析与优化 http://www.docin.com/p-759040698.html

  9. WebDriver兼容SeleniumRC(基于C#)

    WebDriver兼容SeleniumRC(基于C#)http://www.automationqa.com/forum.php?mod=viewthread&tid=3535&fro ...

  10. Android之线程回掉更新ui

    一:工作线程中的回掉更新UI public class MainActivity extends AppCompatActivity { private int i; private Callback ...