lex&中的语法错误yacc文件

时间:2017-01-12 14:48:22

标签: bison flex-lexer yacc lex

我对lex和yacc很新。我正在尝试使用语法来识别输入文本:ESCREVER 1;ESCREVER 1+2;但每次我尝试它时都会显示语法错误,我认为问题在于解析数字或单词ESCREVER

这是我的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;
}

1 个答案:

答案 0 :(得分:2)

扫描仪规范中的这两行都匹配空格:

.          {return yytext[0];}
[ \n\t]    {  }

当您键入ESCREVER 1;时,第一个规则会解释该空间。由于Flex按照编写顺序使用规则,因此您只需将空白忽略规则向上移动,因此首先进行检查。