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按照规则的编写顺序使用这些规则,因此您可以将空白忽略规则上移,因此首先选中它