2017-04-14 6 views
2

私はフレックスとバイソンの新しいので、私と一緒に耐える。 yylrorでyyllocを使用して、ファイル名とともにエラーが発生した場所を表示しようとしています。これは私がファイル名を追跡するために使用できるchar *ファイル名をインクルードするためにYYLTPYEを再定義する必要があることを知っています。私が持っているFlexとBisonの本によると、それは私が.LファイルにYYLTYPEを初期化するためにYY_USER_ACTIONマクロを使用することをお勧めしますので、私はそれには、以下の、yylloc宣言されていないエラーを解決するには?

#define YY_USER_ACTION yylloc.filename = filename; yylloc.hel = 0; \ 
     yylloc.first_line = yylloc.last_line = yylineno;   \ 
     yylloc.first_column = yycolumn; yylloc.last_column = yycolumn+yyleng-1; \ 
     yycolumn += yyleng; 

を含むが、私は、コンパイルしようとすると、プロジェクトでは、yyllocが宣言されていないというエラーが表示されます。

私は、このquestionのChris Doddによって提供されているソリューションを試しましたが、この問題を解決するのに役立っていません。このエラーを解決するためのあらゆる助けが大いに評価されています。

ここ.Lで完全なコードは次のとおりです。

%option noyywrap nodefault yylineno case-insensitive 
%{ 
    #include "need.h" 
    #include "numbers.tab.h" 

    int yycolumn = 1; 

    #define YY_USER_ACTION yylloc.filename = filename; yylloc.hel = 0; \ 
     yylloc.first_line = yylloc.last_line = yylineno;   \ 
     yylloc.first_column = yycolumn; yylloc.last_column = yycolumn+yyleng-1; \ 
     yycolumn += yyleng; 

%} 

Integers [-]?(0|[1-9][0-9]*) 
Float  [.][0-9]+ 
Exp   [eE][-]?(0|[1-9][0-9]*) 
Octal  [-]?(00|0[1-7][0-7]*) 
Hexa  [-]?(0[xX][0-9A-F]+) 
tomsNotNumbers [^ \t\n\v\f\r]+ 

%% 

{Integers}{Float}?{Exp}? { 
           printf("%s is a number.\n", yytext); 
           possibleNumbers++; // increment by 1 as an input was given -M 
           actualNumbers++; // increment by 1 as an input did match our pattern -M 
          } 

{Octal} { 
      printf("%s is a number.\n", yytext); 
      possibleNumbers++; // increment by 1 as an input was given -M 
      actualNumbers++; // increment by 1 as an input did match our pattern -M 
     } 

{Hexa} { 
      printf("%s is a number.\n", yytext); 
      possibleNumbers++; // increment by 1 as an input was given -M 
      actualNumbers++; // increment by 1 as an input did match our pattern -M 
     } 

{tomsNotNumbers} { 
        printf("%s is not a number.\n", yytext); 
        yyerror(warning, "This isn't a number."); 
        possibleNumbers++; // increment by 1 as an input was given -M 
        failedNumbers++; // increment by 1 as the input has failed to match our patterns -M 
       } 

[\n] /*Do nothing for newline*/ 

. /*Do nothing for anything else*/ 

%% 

.Y今のちょうど空である、唯一の.tab.h

need.hためneed.hと1のために含まれています:yyllocので

#include <stdlib.h> 
#include <stdarg.h> 
#include <string.h> 

int possibleNumbers = 0; 
int actualNumbers = 0; 
int failedNumbers = 0; 

typedef struct YYLTYPE 
{ 
    int first_line; 
    int first_column; 
    int last_line; 
    int last_column; 
    char *filename; /* use to keep track of which file we're currently in */ 
    int hel; /* no errors = 0, warning = 1, error = 2, fatal = 3 */ 
} YYLTYPE; 

char *name; /*using for test purposes*/ 

# define YYLTYPE_IS_DECLARED 1 

# define YYLLOC_DEFAULT(Current, Rhs, N)             \ 
    do                      \ 
     if (N)                    \ 
     {                     \ 
      (Current).first_line = YYRHSLOC (Rhs, 1).first_line;       \ 
      (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \ 
      (Current).last_line = YYRHSLOC (Rhs, N).last_line;        \ 
      (Current).last_column = YYRHSLOC (Rhs, N).last_column;       \ 
      (Current).filename = YYRHSLOC (Rhs, 1).filename;        \ 
      (Current).hel = YYRHSLOC (Rhs, 1).hel;          \ 
     }                     \ 
     else                    \ 
     { /* empty RHS */                 \ 
      (Current).first_line = (Current).last_line = YYRHSLOC (Rhs, 0).last_line;  \ 
      (Current).first_column = (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \ 
      (Current).filename = NULL;              \ 
      (Current).hel = 0;                \ 
     }                     \ 
    while (0) 

typedef enum errorSeverity 
{ 
    warning = 1, error, fatal 
} errorLevel; 

void yyerror(errorLevel errlvl, char *s, ...) 
{ 
    va_list ap; 
    va_start(ap, s); 
    char *errLvls[3] = {"Warning", "Error", "Fatal"}; 

    fprintf(stderr, "%s: %s: , %n", name, errLvls[errlvl - 1], yylloc.first_line); 
    vfprintf(stderr, s, ap); 
    fprintf(stderr, "\n"); 
} 

main(int argc, char **argv) 
{ 
    printf("argv[0] = %s, argv[1] = %s.\n", argv[0], argv[1]); 
    if(argc > 1) 
    { 
     if((yyin = fopen(argv[1], "r")) == NULL) 
     { 
      perror(argv[1]); 
      exit(1); 
     } 
     name = argv[1]; 
    } else 
     name = "(stdin)"; 

    printf("Filename1: %s", name); 
    yylex(); 
    printf("Filename2: %s", name); 
    // print out the report. -M 
    printf("Out of %d possible numbers, there were %d numbers, and %d not numbers.\n", possibleNumbers, actualNumbers, failedNumbers); 
} 

答えて

2

は通常バイソン入力ファイルを持たないが迷惑のビットになるだろう、バイソン、生成されたパーサーで定義されています。あなたはバイソンプロローグでディレクティブ%locationsを含める

  1. 、または

  2. あなたの参照:場合は生成されたヘッダファイルで宣言を、生成されたパーザにyyllocを定義し、配置します

    バイソン任意のバイソンアクションでの位置(nの場合は@n)。

ルール内の場所への明示的な参照がない場合は、通常、ディレクティブを追加することをお勧めします。

Chris Doddは、リンクされた質問では、YYLTYPEの定義を、bison生成のヘッダーファイルを#includeに含めることが重要です。あるいは、#includeの構造体の定義を%code requiresセクションのバイソンプロローグに直接挿入することもできます。 %code requiresセクションが生成されたヘッダにコピーされるため、flexファイルの定義を心配する必要はありません。ところで


、私はあなたがyyllocを初期化YY_USER_INITを使用するためのものだと思います。 YY_USER_INITの拡張は、フレックススキャナ独自の初期化の前に1回だけ実行されます。 YY_USER_ACTIONの拡張は、すべてのスキャナアクション(空のアクションを含む)の前に実行され、yylloc構造体を現在のトークンで更新するために使用される可能性があります。

+0

ありがとうございました。%locationを追加し、YYLTYPEの定義を.yファイルの%code requiresブロックに配置することで、エラーを解決することができました。それは今、 'yylloc'への未定義の言及を何度も言いつつ、collect @にヒットします:error:ldは1つの終了ステータスを返しました。これは私のパーサーにはまだ何もないので、何かが恋しいのですか? –

+0

bisonで生成されたパーサーを実行ファイルにリンクしましたか? 番号: – rici

+0

はここに私のメイクだnumbers.lのnumbers.y \tバイソン-d numbers.y \tフレックスnumbers.l \tのgcc lex.yy.cをnumbers.tab.h -lfl –

関連する問題