项目介绍
将lisp风格的函数转换为C风格的函数
* LISP C
*
* 2 + 2 (add 2 2) add(2, 2)
* 4 - 2 (subtract 4 2) subtract(4, 2)
* 2 + (4 - 2) (add 2 (subtract 4 2)) add(2, subtract(4, 2))
涉及的知识点
该项目虽小,却向我们展示了编译器的一些东西: 词法分析,抽象语法树,语法树遍历等
词法分析
public List<Token> tokens(String input) throws Exception {
List<Token> tokenList = new ArrayList<Token>();
int currentPos = 0;
while (currentPos < input.length()) {
char currentChar = input.charAt(currentPos);
if ('(' == currentChar) {
tokenList.add(new Token().setType("paren").setValue("("));
currentPos++;
continue;
} else if (')' == currentChar) {
tokenList.add(new Token().setType("paren").setValue(")"));
currentPos++;
continue;
} else if (Character.isWhitespace(currentChar)) {
currentPos++;
continue;
} else if (Character.isDigit(currentChar)) {
StringBuilder digitsBuilder = new StringBuilder();
while (Character.isDigit(currentChar)) {
digitsBuilder.append(currentChar);
currentChar = input.charAt(++currentPos);
}
tokenList.add(new Token().setType("number").setValue(digitsBuilder.toString()));
continue;
} else if (isAlphabet(currentChar)) {
StringBuilder charsBuilder = new StringBuilder();
while (isAlphabet(currentChar)) {
charsBuilder.append(currentChar);
currentChar = input.charAt(++currentPos);
}
tokenList.add(new Token().setType("name").setValue(charsBuilder.toString()));
continue;
} else {
throw new Exception("I dont know what this character is: " + currentChar);
}
}
return tokenList;
}
语法树
* 它的抽象语法树(AST)看起来或许是这样的:
* {
* type: 'Program',
* body: [{
* type: 'CallExpression',
* name: 'add',
* params: [{
* type: 'NumberLiteral',
* value: '2'
* }, {
* type: 'CallExpression',
* name: 'subtract',
* params: [{
* type: 'NumberLiteral',
* value: '4'
* }, {
* type: 'NumberLiteral',
* value: '2'
* }]
* }]
* }]
* }
项目github地址(Java实现版本)
https://github.com/AnoxiaTown/TheSuperTinyCompiler
JS中文版
https://github.com/starkwang/the-super-tiny-compiler-cn/blob/master/super-tiny-compiler-chinese.js
网友评论