2017-01-12 3 views
0

私はlexとyaccにとってかなり新しいです。私は入力テキストを認識するための文法を試していました:ESCREVER 1;またはESCREVER 1 + 2;しかし、私はそれが私に構文エラーを表示しようとすると、私は問題がパーサ番号または単語ESCREVERだと思う。あなたがESCREVER 1;を入力すると構文エラーlex yacc

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

%{ 

    #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; 
} 

答えて

2

スキャナの仕様では、これら二列の両方が一致スペース:ここ

は私のフレックス/ 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コードです最初の規則によって空間が解釈されます。 Flexは書き込まれた順番で規則を使用するので、空白無視の規則を上に移動するだけで、最初にチェックされます。

関連する問題