/dragon

A compiler that is written by go.

Primary LanguageGoApache License 2.0Apache-2.0

  • dragon 使用 golang 编写的一个编译器前端。包含:词法分析器、语法分析器、计算器、脚本语言等。
.
├── LICENSE
├── README.md
├── calculator             #计算器
│   ├── calculator.go
│   └── example_test.go
├── example_test.go
├── go.mod
├── lexer                  #词法分析器
│   ├── example_test.go
│   ├── graphic.go
│   ├── lexer.go
│   ├── token.go
│   ├── token_reader.go
│   └── token_type.go
├── main.go  
├── parser                 #语法分析器
│   ├── ast_node.go
│   ├── ast_node_type.go
│   ├── example_test.go
│   └── parser.go
└── script                 #脚本语言
    └── script.go
  • 词法分析器

lexer 能够为语法分析器、计算器、简单脚本语言生产 Token。

  • 语法分析器

parser 能够解析简单的表达式、变量声明和初始化语句、赋值语句。

它支持的语法规则:

additionSubtractionExpression  //加法、减法的表达式的规则
    : multiplyDivideExpression //乘法、除法的表达式规则,优先级高于加法、减法。
    | multiplyDivideExpression Add additionSubtractionExpression //表达式 + 表达式
    | multiplyDivideExpression Sub additionSubtractionExpression //表达式 - 表达式
    ;
multiplyDivideExpression  //乘法、除法的表达式的规则
    : primary_expression  //一元表达式
    | primary_expression Mul multiplyDivideExpression //表达式 * 表达式
    | primary_expression Div multiplyDivideExpression //表达式 / 表达式
    ;
primary_expression //一元表达式的规则
    : IntLiteral   //int的字面量
    ;
program -> intDeclare | expressionStatement | assignmentStatement
	intDeclare -> 'int' Id ( = add) ';'
	expressionStatement -> add ';'
		add -> multiply ( (+ | -) multiply)*
			multiply -> primary ( (* | /) primary)*
				primary -> IntLiteral | Id | (add)
	assignmentStatement -> Id = add ';'
		add -> multiply ( (+ | -) multiply)*
			multiply -> primary ( (* | /) primary)*
				primary -> IntLiteral | Id | (add)
  • 计算器

语法规则:

additionSubtractionExpression  //加法、减法的表达式的规则
    : multiplyDivideExpression //乘法、除法的表达式规则,优先级高于加法、减法。
    | multiplyDivideExpression Add additionSubtractionExpression //表达式 + 表达式
    | multiplyDivideExpression Sub additionSubtractionExpression //表达式 - 表达式
    ;
multiplyDivideExpression  //乘法、除法的表达式的规则
    : primary_expression  //一元表达式
    | primary_expression Mul multiplyDivideExpression //表达式 * 表达式
    | primary_expression Div multiplyDivideExpression //表达式 / 表达式
    ;
primary_expression //一元表达式的规则
    : IntLiteral   //int的字面量
    ;

program -> add
	multiply | multiply + add
		multiply -> primary | primary * multiply

存在问题:计算的结合性是有问题的。递归项在右边,会自然的对应右结合。真正需要的是左结合。

  • 脚本语言解释器

script 一个脚本解释器。可以进入一个REPL界面。

运行脚本: 在命令行执行命令:

go run ../dragon

你可以依次敲入命令。比如:

go run ../dragon
It is a script language. It is written by golang!
Input your code.
>
> 2+3;
> 2+2*3;
> 2*2+3*4;
> 2+3+4/2;  
> exit();  //退出REPL界面。