【读书笔记】-【编程语言的实现模式】-【LL(1)递归下降的语法解析器】

时间:2022-05-20 18:16:57

形如:[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();
}
}
```