Bison lex&;yacc文件
我对莱克斯和亚克还很陌生。我正在尝试一种语法来识别输入文本:Bison lex&;yacc文件,bison,flex-lexer,yacc,lex,Bison,Flex Lexer,Yacc,Lex,我对莱克斯和亚克还很陌生。我正在尝试一种语法来识别输入文本:escliver 1或ESCRIVER 1+2但每次我尝试它时都会显示语法错误,我认为问题在于解析数字或单词escliver 这是我的flex/lex代码 %{ #include "gram.h" int yyerror(const char *s); %} /* letras [A-Za-z]+ */ /* id ({letras})({letras}|{digito})* */ %% "ESCREVER"
escliver 1代码>或<代码>ESCRIVER 1+2
但每次我尝试它时都会显示语法错误,我认为问题在于解析数字或单词escliver
这是我的flex/lex代码
%{
#include "gram.h"
int yyerror(const char *s);
%}
/* letras [A-Za-z]+ */
/* id ({letras})({letras}|{digito})* */
%%
"ESCREVER" {return ESCREVER; }
"TERMINAR" {return TERMINAR; }
[0-9]+ { yylval.num =atoi(yytext);
return NUM; }
[A-Za-z0-9]* { yylval.str=strdup(yytext);
return TEXTO;}
"/" |
"-" |
"+" |
"*" |
"=" |
. {return yytext[0];}
[ \n\t] { }
%%
int yywrap(){ return 1; }
YACC代码:
%{
#include <stdio.h>
int yylex(void);
int yyerror(const char *s);
%}
%union{
char *str; /* para strings*/
int num; /* para inteiros */
}
%token TERMINAR ESCREVER
%token SUBTRACAO
%token MULTIPLICACAO
%token DIVISAO
%token SOMA
%token<num> NUM /*para inteiros*/
%token<str> TEXTO /*MUDAR PARA VAR*/
%type<num> elemento
%type<num> expr
%type<num> lista
%start s
%%
s:linha s
|TERMINAR ';' {return 0;}
;
linha: ESCREVER lista';' {printf("%d",$2);}
| VARS
;
lista: lista ',' elemento
| elemento
;
elemento:NUM
|expr
;
VARS :
| NUM
| TEXTO
| expr
| TEXTO '=' VARS ';' /* para delcaracoes */
;
expr : NUM SOMA expr {$$=$1+$3;}
| NUM SUBTRACAO expr {$$=$1-$3;}
| NUM MULTIPLICACAO expr {$$=$1*$3;}
| NUM DIVISAO expr {$$=$1/$3;}
| NUM '+' expr {$$=$1+$3;}
| NUM '=' expr {$$=$1=$3;}
| NUM '-' expr {$$=$1-$3;}
| NUM '*' expr {$$=$1*$3;}
| NUM '/' expr {$$=$1/$3;}
| NUM {$$=$1; }
;
%%
int yyerror(char const *s) {
fprintf(stderr,"Erro: %s\n",s);
return 0;
}
int main(int argc, char *argv[]) {
extern FILE *yyin;
if (argc > 1) {
if((yyin=fopen(argv[1],"r"))==NULL){
fprintf(stderr,"erro ao abrir o ficheiro \"%s\".\n",argv[1]);
return 1;
}
} else
printf("introduza comandos: \n");
yyparse();
return 0;
}
%{
#包括
int yylex(无效);
int yyerror(常量字符*s);
%}
%联合{
char*str;/*para字符串*/
int num;/*第i段*/
}
%埃斯里维尔令牌终端
%代币
%象征多重性
%代币除草
%象征性躯体
%令牌编号/*第i段*/
%令牌TEXTO/*MUDAR PARA VAR*/
%elemento型
%类型表达式
%lista型
%开始
%%
s:琳哈s
|终端“;”{返回0;}
;
林哈:艾斯里维尔·利斯塔';'{printf(“%d”,$2);}
|瓦尔斯
;
lista:lista','elemento
|埃莱门托
;
元素:NUM
|expr
;
变量:
|NUM
|TEXTO
|expr
|TEXTO'='VARS';'/*帕拉德卡拉科斯酒店*/
;
expr:NUM SOMA expr{$$=$1+$3;}
|NUM SUBTRACAO expr{$$=$1-$3;}
|NUM multipacao expr{$$=$1*$3;}
|NUM divisiao expr{$$=$1/$3;}
|NUM'+'expr{$$=$1+$3;}
|NUM'='expr{$$=$1=$3;}
|NUM'-'expr{$$=$1-$3;}
|NUM'*'expr{$$=$1*$3;}
|NUM“/”expr{$$=$1/$3;}
|NUM{$$=$1;}
;
%%
int yyerror(字符常量*s){
fprintf(标准,“错误:%s\n”,s);
返回0;
}
int main(int argc,char*argv[]){
外部文件*yyin;
如果(argc>1){
if((yyin=fopen(argv[1],“r”)==NULL){
fprintf(标准,“erro ao abrir o ficheiro\%s\”\n,argv[1]);
返回1;
}
}否则
printf(“公司简介:\n”);
yyparse();
返回0;
}
扫描仪规格中的这两行都与空格匹配:
. {return yytext[0];}
[ \n\t] { }
当您键入
escliver 1时代码>空间由第一条规则解释。由于Flex按照写入规则的顺序使用这些规则,您只需向上移动空白忽略规则,因此首先选中它。扫描仪规格中的这两行都与空格匹配:
. {return yytext[0];}
[ \n\t] { }
当您键入escliver 1时代码>空间由第一条规则解释。由于Flex按照规则的编写顺序使用这些规则,因此您可以将空白忽略规则上移,因此首先选中它