Flex/Bison 的问题
Troubles with Flex/Bison
我尝试通过下一个模式使用 flex/bison 设置语法:
DATA: 1,2,3,4,5 PROGRAM: add,mult,div,read
此输入必须转入
4 add mult div read 5 1 2 3 4 5
其中:4 是 "PROGRAM" 之后的命令数
5是"DATA"之后的数据个数。
目前我有下一个代码。
在asm.y(野牛)中:
%{
#include<stdio.h>
int comm[100];
int data[100];
int ncomm=0;
int ndata=0;
%}
%token NUMBER
%%
PROGR:"DATA: "INPUT" PROGRAM: "COMMANDS
;
COMMANDS:
| INSTR","COMMANDS
;
| NUMBER","INPUT {data[ndata]=; ndata++;}
;
INSTR:NUMBER {comm[ncomm]=; ncomm++;}
|"add" {comm[ncomm]=-10000; ncomm++;}
|"mult" {comm[ncomm]=-10001; ncomm++;}
|"div" {comm[ncomm]=-10002; ncomm++;}
|"minus" {comm[ncomm]=-10003; ncomm++;}
//and so on
;
%%
int main(int argc, char** argv)
{
yyparse();
printf("\n%d ",ncomm);
int i;
for(i=0; i<ncomm; i++)
{
printf("%d ",comm[i]);
}
printf("%d ",ndata);
for(i=0; i<ndata; i++)
{
printf("%d ",data[i]);
}
}
yyerror(char* s)
{
printf("error: %s\n",s);
}
并且在 asm.l(弹性)中:
%{
#include "asm.tab.h"
%}
%%
[0-9]+ {return NUMBER;}
%%
所以,毕竟程序没有打印正确的数据,但是,例如
对于
DATA: PROGRAM: add
它打印
DATA: PROGRAM: add
并等待下一次输入。
另一方面,
DATA: 5 PROGRAM: add
它打印
DATA: error: syntax error
0 0
而且我不知道我做错了什么。
你还有很多工作要做。当你说它适用于 DATA: PROGRAM: add
时,嗯,它不适用:你被 Lex 的 "feature" 咬住了:无法识别的字符打印在标准输出上。
所以:
告诉 Flex 您不希望未知字符通过。
%option nodefault
你需要告诉 Bison 将使用 "DATA:"
等标记。类似于:
%token ADD "add"
%token DATA "DATA:"
然后确保在文件的其余部分完全 "DATA:"
或 DATA
,例如不要使用 "DATA: "
。
您需要 scanner/lexer 识别您需要的所有标记:不仅是数字,还有关键字(或标识符),例如 add
、mult
等。类似:
"+" return ADD;
还有"DATA:"
.
"DATA:" return DATA;
确保告诉您的解析器生成器 NUMBER
有一个值:
%token <int> NUMBER
并告诉你扫描仪计算它。
你还有很多东西要学。在尝试做这一切之前,一定要尝试基本的 examples from Bison's documentation,并完全理解它们。
我尝试通过下一个模式使用 flex/bison 设置语法:
DATA: 1,2,3,4,5 PROGRAM: add,mult,div,read
此输入必须转入
4 add mult div read 5 1 2 3 4 5
其中:4 是 "PROGRAM" 之后的命令数 5是"DATA"之后的数据个数。 目前我有下一个代码。
在asm.y(野牛)中:
%{
#include<stdio.h>
int comm[100];
int data[100];
int ncomm=0;
int ndata=0;
%}
%token NUMBER
%%
PROGR:"DATA: "INPUT" PROGRAM: "COMMANDS
;
COMMANDS:
| INSTR","COMMANDS
;
| NUMBER","INPUT {data[ndata]=; ndata++;}
;
INSTR:NUMBER {comm[ncomm]=; ncomm++;}
|"add" {comm[ncomm]=-10000; ncomm++;}
|"mult" {comm[ncomm]=-10001; ncomm++;}
|"div" {comm[ncomm]=-10002; ncomm++;}
|"minus" {comm[ncomm]=-10003; ncomm++;}
//and so on
;
%%
int main(int argc, char** argv)
{
yyparse();
printf("\n%d ",ncomm);
int i;
for(i=0; i<ncomm; i++)
{
printf("%d ",comm[i]);
}
printf("%d ",ndata);
for(i=0; i<ndata; i++)
{
printf("%d ",data[i]);
}
}
yyerror(char* s)
{
printf("error: %s\n",s);
}
并且在 asm.l(弹性)中:
%{
#include "asm.tab.h"
%}
%%
[0-9]+ {return NUMBER;}
%%
所以,毕竟程序没有打印正确的数据,但是,例如
对于
DATA: PROGRAM: add
它打印
DATA: PROGRAM: add
并等待下一次输入。
另一方面,
DATA: 5 PROGRAM: add
它打印
DATA: error: syntax error
0 0
而且我不知道我做错了什么。
你还有很多工作要做。当你说它适用于 DATA: PROGRAM: add
时,嗯,它不适用:你被 Lex 的 "feature" 咬住了:无法识别的字符打印在标准输出上。
所以:
告诉 Flex 您不希望未知字符通过。
%option nodefault
你需要告诉 Bison 将使用
"DATA:"
等标记。类似于:%token ADD "add" %token DATA "DATA:"
然后确保在文件的其余部分完全
"DATA:"
或DATA
,例如不要使用"DATA: "
。您需要 scanner/lexer 识别您需要的所有标记:不仅是数字,还有关键字(或标识符),例如
add
、mult
等。类似:"+" return ADD;
还有
"DATA:"
."DATA:" return DATA;
确保告诉您的解析器生成器
NUMBER
有一个值:%token <int> NUMBER
并告诉你扫描仪计算它。
你还有很多东西要学。在尝试做这一切之前,一定要尝试基本的 examples from Bison's documentation,并完全理解它们。