概述
继续利用黑盒工具实现我们的功能。上一篇实现了命令行执行单行四则运算,这一篇改良一下,不用命令行,把多个四则运算写在一个文件上,直接读文档解析执行输出所有运算结果。那也算是做出了一门编程语言,叫四则运算语言。
因为四则运算的功能已经做好,只要修改一下输入输出逻辑就好。
整体分支代码在这里,其实就是另一个分支。
修改
首先修改入口文件main.c
之前通过命令行输入,所以输入来自标准输入流
yyin = stdin;
新的输入来自一个文件,所以执行时需要输入文件名。先定义一个文件指针
FILE *fp;
再要判断命令执行时有没有输入文件名,所以要判断参数个数是否是2,不是2就报错
argc != 2
拿到文件名以读方式打开
fp = fopen(argv[1], "r");
最后把文件指针赋值给yyin,就换了一种输入方式
yyin = fp;
main方法代码如下,新的完整文件在这里。
int main(int argc, char **argv) {
extern int yyparse(void);
extern FILE *yyin;
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage:%s filename", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "%s not found.\n", argv[1]);
exit(1);
}
yyin = fp;
if (yyparse()) {
fprintf(stderr, "Error ! \n");
exit(1);
}
}
修改词法分析内容
修改nl.l文件,新的完整代码在这里
要多加一个分号(';')token,用来表示一个四则语句的结束。
";" return SEMICOLON;
然后把换行符那个单独识别的token去掉,原来是这行,去掉
"\n" return CR;
把换行符放到空白符号判断里面,让它在分析的时候直接被忽略,中括号是正则表达式的语法,识别到这三个符号任意一个之后,什么都不做,所以后面直接分号结束
[ \t\n] ;
修改语法分析内容
修改nl.y文件,新的完整代码在这里
token定义加上分号的token名SEMICOLON,去掉之前换行的token名CR
%token SEMICOLON ADD SUB MUL DIV LP RP MOD
语法规则加上语句列表(statement_list)的定义,语句列表可以是单个语句(statement),也可以是另一个列表后面跟一个语句,其实就是多个语句
statement_list
: statement
| statement_list statement
;
还要有语句的定义,定义成表达式(expression)后面跟一个分号(SEMICOLON),每当解析到一个语句时,计算其中的表达式,并打印它的值
statement
: expression SEMICOLON
{
NL_Value v = nl_eval_expression($1);
nl_print_value(&v);
}
;
而表达式的定义就改成了单个加法表达式
expression
: add_expression
;
其它地方都没有变。这样就修改完毕了,录个屏看看效果。要是能放视频就太好了。
结束
这篇十分短,但目的达到了,下一篇,尝试支持变量,用变量存储一些值,让我们可以复用一些值。