2.编写AST和语法规范
type
status
date
slug
summary
tags
category
icon
password
编写AST和语法规范
语法规范
我们首先来想一想我们需要什么语法,这里可以学习一下C#和Python:
首先要一个赋值语句,像这样:(Python语法)
因为我们要编写一个脚本语言,所以在这里我们学习一下python。现在分析一下:
首先需要一个标识符a,中间是一个‘=’符号,右边是一个值类型
那么我们的语句就是:
<id> = <value>
第一章讲过,csly使用bnf/ebnf,我们这里使用ebnf,因为ebnf更加便捷,而且现在csly有很多特性是只有ebnf才能有的,所以我们在这里使用ebnf。
现在书写一下:
其中,[d]表示丢弃,我们不需要这个元素。
那么接下来的就好写多了:
我们翻译一下:
写完!
AST
我们现在需要进行分析,将我们获得的元素组合成一个个“产品”,也就是一个个类的实例。
虽然这些“产品”不一,可我们现在需要将这些产品聚合到一起,我们需要一个接口,让它成为基类。
这个类就叫AST吧。
接下来就是将AST分类。虽然我们有不同的值,不同的语法,但我们大致的可以分为两大类:
- expr :包含id,各种value,二元表达式
- statement:包含各种句子
其中expr有GetValue();statement有Run()。
statement则包括:
- if
- while
- for
- 函数定义
- 类的定义
- return
value包括:
- IntValue : int
- StringValue : string
- DoubleValue : double
- BoolValue : bool
我们在编写ebnf表达式的时候也必须要有这些部分。
那么现在,我们需要花费大量的时间来构建这一体系。
Parser
在构建完这个体系后。我们开始准备连接AST和语法规范。我们新建一个Parser类。
csly在连接上使用方法+修饰器的方法来构建,例如:
形如:
在ebnf语法中,分为终端和非终端。终端就是由Token枚举中的元素组成,而非终端就像上面的statement一样,必须要定义。也就是说,一个ebnf语句最终都必须指向非终端集合。
对于有0到多个语句,我们使用*来表示,1到多个用+表示,0或1个用?表示。而csly最终传递给我们的,可以看下面这张图:
普通终端 | * | + | ? | 非终端 | 终端与非终端的组合 |
Token <Lexer> | List <> | List <> | ValueOption <> | AST | Group <Lexer,AST> |
这里用Lexer来表示我们写的Token枚举。
现在,我们可以来编写我们的Parser类了。
至于expr应该如何编写,请看下一章。
Loading...