目录
一 . 上机目的 1
二 . 上机题目:简单函数绘图语言的解释器 1
2.1 题目简述 1
2.2 语句的语法和语义(syntax & semantics) 2
2.3 记号的语法和语义 4
三 、 题目与要求 5
四 、实验过程 5
1.结构设计 5
2.词法分析器(Lexical Analyzer, aka Scanner) 6
3.语法分析器(Syntactic Analyzer, aka Parser) 9
4.语义分析器 10
五 、心得体会 11
六 、实验结果 11
Windows 环境下编译 12
Linux 环境下编译 14
Running 14
题目与要求
题目:为函数绘图语言编写一个解释器
解释器接受用绘图语言编写的源程序,经语法和语义分析之后,将源程序所规定的图形显示在显示屏(或窗口)中。
目的:通过自己动手编写解释器,掌握语言翻译特别是语言识别的基本方法。
四 、实验过程
1.结构设计
本编译器采用一趟扫描,以语法分析器为核心,语法分析器通过词法分析器从代码源文件中读入与分析 词素,通过递归下降分析生成对应的抽象语法树(Abstract Syntax Tree),并检测代码中的语法错误。本文转载自http://www.biyezuopin.vip/onews.asp?id=15610
语法分析器在生成抽象语法树后将其传递给语义分析器,由语义分析器进行语义分析,生成最终的可执 行代码,此处为了保证代码跨平台的兼容性,笔者选择使用 cmake 构建整个项目,整个项目中使用平台无关的标准库函数,最终生成 python 代码使用 tkinter 库进行绘图。
/*
* simple compiler developed by arttnba3, Xidian University
* 2021.11
*/
#include
#include
#include
#include "message/message.h"
#include "scanner/scanner.h"
#include "parser/parser.h"
#include "semantic/semantic.h"
using namespace std;
int main(int argc, char **argv, char **envp)
{
char choice;
// check the params
if (argc < 2)
err_exit("Usage: ./A3compiler [object file]", "", -EFAULT);
// init the scanner, open the input file
if (!init_scanner(argv[1]))
err_exit("failed to open the source file: %s", argv[1], -EFAULT);
// test for scanner
if (argv[2] && !strcmp(argv[2], "test"))
{
cout << "Testing Token..." << endl;
struct token *t;
t = get_token();
for (int i = 0; !(t->type == ERRORTOKEN || t->type == NONTOKEN); i++)
{
cout << "token " << i << ": " << "letme: " << ((t->lexme) ? t->lexme : "NULL") << " type: " << t->type << " val: " << t->val << " func ptr: " << (size_t)(t->func_ptr) << endl;
t = get_token();
}
exit(0);
}
// parsing the code, translate into python code
cout << "Start to parse..." << endl;
parser();
// close the scanner
cout << "Done." << endl;
close_scanner();
close_drawer();
// run the python to draw the pic
while (true)
{
cout << "Interpretation done. run it now? [Y/n]" << endl;
cin.get(choice);
if (toupper(choice) == 'Y' || choice == '\n')
{
cout << "Press enter to exit..." << endl;
system("python3 ./drawer.py");
break;
}
else if (toupper(choice) == 'N')
{
cout << "Result saved in ./drawer.py" << endl;
exit(0);
}
else
{
cout << "Invalid choice" << endl;
}
}
}