本项目由STVM改进而来,STVM地址
由于一些原因(详见后记),我不得不先从编译器开始编写。
有一些代码,在现阶段可能是废弃的,但是我无法确定将来我会使用到他,我把这些代码整合并放在了history目录里。代码阅读者和用户都不用理会。
随着项目的不断开发,依赖库的接口定义也逐渐稳定了下来。
依赖库位于src/include
中,其中的template
目录是依赖库的模板(即接口定义),如果你想要移植Stamon,只需要实现template
目录中定义的接口即可。
为了示范,我将接口用C语言的标准库实现了一遍,并把代码放到stdc_implemented
中。
如果你所在的平台支持C语言的标准库(具体标准为C89),那么可以直接使用stdc_implemented
作为依赖库。
几乎所有的文件都有了大大小小的改动。
词法分析器已经写完了,语法分析器尚且写到了表达式分析的部分。
词法分析器的源码位于src/compiler/Lexer.cpp
。
Lexer.cpp
里的代码都被stamon::c
(c
指的是compiler)这个命名空间封装了起来。
如果你想要调用Lexer.cpp
,可以编写以下代码:
```C++
using namespace stamon::c; ```
接下来我想讲一讲词法分析器的架构(了解该架构前,你应该要会编译原理):
Token
是基本词法单元类,其成员如下:
Token(int line, int tok_type)
:构造函数,line参数表示该token所在的行号,tok_type表示该token的类型编号(具体请参见Lexer.cpp
中的TOKEN_TYPE
)lineNo
:这是一个整数变量,表示该token所在的行号type
:返回一个整数,即该token的类型编号除Token
类外,还有StringToken
、IdenToken
、IntToken
、DoubleToken
。这些都是Token
的子类,如果一个Token是字面量或者标识符,你需要将其转化成对应的子类才能获取信息。具体请参见Lexer.cpp
中的相关定义。
Lexer
是词法分析器类,其接口如下:
int getLineTok(int line, String text)
:分析一行的token,line是行号,text是文本(不包含换行符)。分析后的token会加入到缓存中。返回解析到的位置,如果返回值是text的长度就说明解析到末尾,即解析成功;否则说明解析失败。Token* getTok()
:从缓存中读取出(并删除)一个Token。Token* peek(int index)
:查看第index个Token(但不删除)。Lexer在分析前,应当先把源码分解成逐行的文本,然后从第一行到最后一行依次调用getLineTok。
具体的用法请参见Lexer.cpp
和测试样例
新增了词法分析器的测试样例,位于test_case/lexer/
中。
如果你想要编译运行测试样例,请将测试样例中的test.cpp
覆盖到test/test.cpp
当中,然后使用Makefile调试。
怎么说呢,这个logo有点简陋?
无论是调试你自己编写的测试代码,抑或是调试测试样例,都至少需要配置好以下工具:
gcc (x86_64-posix-seh-rev1, Built by MinGW-Builds project) 13.1.0
或TDM-GCC 10
等)注意:该项目的Makefile是基于win32的,如果你想要移植该项目到别的系统,请尝试修改Makefile。
编译该项目时默认依赖库采用stdc_implemented
,如果你所在的平台不支持C标准库,请自行实现依赖库。
你可以在命令行中键入以下指令:
make build
:编译项目,生成一个test.exe
,即项目可执行文件make run
:运行项目make zip
:将项目可执行文件进行压缩 (该指令需要用到strip和upx)这次的更新比以往所有的更新都更加全面,并且该项目的开发方针也进行了大幅度的改善。
之所以变动会这么大,是因为我要在二月份参加一个重要的创新比赛,这也就意味着我必须在二月份开发出一个能运行的语言。
再加上我的学业(临近中考),所以我会变得很忙。
最后...祝大家中国新年快乐!