2017-12-28 10 views
0

私はYaccプログラミングを始める前に、入力テキストファイル に正しくペアのかっこのシーケンスが含まれているかどうかをチェックするプログラムを書くのは簡単な作業です。誤ったシーケンス は、「構文エラー!」として通知されます。私はバイソンとフレックスを使用します。bison yacc yyerrorは機能しません

例正しいデータ: (()()((())())()) が、 (() が正しくありません

私の問題は、私はそれが動作するはずだと思うことですが、。 。yyerror関数は、たぶん私は何か間違ったことをやっている動作していないように、私を修正してください思える ここに私のコード Yaccのコードです:。

%{ 
int yylex(); 
void yyerror(char* x); 
%} 
%% 
S: S A 
|A 
; 
A: '('S')' 
    |'(' ')' 
    ; 

とのlexコード:

%{ 
#include "y.tab.h" 
%} 
%% 
[\(\)] return(yytext[0]); 
. {printf("%c - error!\n",yytext[0]);} 

%% 
void yyerror(char* x) 
{ 
    printf("syntax error"); 
    exit(1); 
} 

したがって、問題は構文エラーを発生させないということですが、どのくらい括弧を書くかは関係ありません。 編集: は、ここで私はそれをコンパイル方法は次のとおりです。 screen

+0

印刷しないでください。あなたが提供されたエラーを印刷します。 – EJP

+0

exit(1)も機能しないので、問題はありません。それはyyerrorメソッドを入力しません –

+0

私はコメントではなく、答えとしてそれを投稿した理由です。それは間違ったままです。 – EJP

答えて

1

あなたはyyparse()を呼び出します(最低でも)main()機能を提供する必要があります。それ以外の場合はlibflmainが使用されます。そのmainyyparse()を呼び出しません。むしろ、EOFが通知されるまで繰り返しyylexを呼び出します。 (libflは、バイソンではなく、Flexの一部ですので、yyparseにも依存できません)

実際には-lflとリンクする必要はありません。 main()の定義は役に立ちません。ライブラリ内の他の唯一のものは、yywrap()のダミー定義です。 yywrap()を定義しないので、ライブラリ関数が呼び出されます。しかし、むしろライブラリに依存するよりも、単にあなたのフレックスコード(直前%%)に

%option noyywrap 

を追加することができ、その後、生成されたスキャナはyywrap()を呼び出すことはありません。

bisonを呼び出すときに-yフラグを使用する必要もありません。 -yを使用する唯一の理由は、bisonで従来のyaccファイルを処理できることです。私はあなたがフラグを使用しているので、生成されたパーサーはy.tab.cと呼ばれていると思います。フラグがなければ、z5.tab.cと呼ばれ、ヘッダファイルはz5.tab.hとなります。あなたはそれらの名前を使うことができます。 (それとも-oフラグを使用して、あなたはそれを使用したい正確なファイル名をバイソン言うことができる。)

を最後に、あなたのlexのファイルに関する2つのノート:括弧のため

  1. パターンはちょうどかもしれません書かれたバックスラッシュエスケープする文字クラス内の括弧を必要はありません

    [()] { return yytext[0]; } 
    

    ]-\以外の文字が内側に特別な意味を持っていないので、文字クラス。

  2. パターン.は改行文字と一致しません。そのため、入力の改行文字はエラーメッセージを生成しません。実際、改行文字と一致するパターンはないので、改行を入力するとデフォルトルールが呼び出されます。デフォルトのルールのようなものであることを定義するバイソン、ECHOに相当します。

    fputs(yytext, yyout); 
    

    (またはfprintf(yyout, "%s", yytext);)あなたは改行を入力すると、余分な改行が出力されている理由ですこと。

+0

私はあなたの助言に従いました。そして、私はgccコマンドを使った後、未定義のリファレンス '@ winmain16'を得ました。 –

+0

これで、%option noyywrapで動作しませんでしたが、int main()とyywrapを追加したときに動作し始めました。私は作業コードと適切なコンパイル方法を投稿します。 –

+0

'main'を提供する必要があります。 '%option noyywrap'は' yywrap'を指定する必要がないことを意味します。それは私の答えではっきりしていませんか? – rici

-1

だから、lexのための適切なコードは次のとおりです。

%{ 
#include "z5.tab.h" 
%} 

%% 
[\(\)] return(yytext[0]); 
. {printf("%c - error!\n",yytext[0]);} 
\n ; 
%% 
int main(void) 
{ 
    yyparse(); 
    return 0; 
} 

int yywrap(void) 
{ 
    return 0; 
} 
void yyerror(char* x) 
{ 
    printf("syntax error"); 
    exit(1); 
} 

し、それをコンパイルする適切な方法は次のとおりです。 ` "構文エラー"`

flex s5.l 
bison -d z5.y 
gcc lex.yy.c z5.tab.c -L"C:\GnuWin32\lib" 
+0

Yywrapは0ではなく1を返します。0は、yyinが別の入力ストリームに変更されたため、EOFが報告されても入力が増えたことを意味します。しかし、あなたはそれをしていません。 yywrapの必要性を避けるために、 '%option noyywrap'を使うのがよいでしょう。 – rici

関連する問題