2

C に似た言語用の語彙および構文アナライザーを作成する必要があります。この言語では、「記号 % から行末までのすべて」をコメントとして定義します。次の宣言は正しいですか?

Flex
...
[%][^\n]*[\n]  { return T_COMMENT; }
[\n]   { return T_NEWLINE; }

Bison
...
comment:com text newline;
text: |name text|digit text;

...
com: T_COMMENT   { printf("%s",yytext); };
newline: T_NEWLINE  { printf("%s",yytext); };

また、引用記号 " を定義する必要があります。次は正しいですか (flex)?

"\""   { return T_QUOTE; }

flex と bison の入力ファイルにはコンパイル エラーはありませんが、この C ライクな言語で書かれたプログラムをテスト入力として使用すると、結果として 1 行目に字句エラーが発生します。この行には字句エラーはありません。私のプログラムは次のように始めなければなりません: PROGRAM name_of_program とそれに対応する改行 次の宣言を行います: Flex

"PROGRAM"  { return T_PROGRAM; }

バイソン

%start programma
%token T_PROGRAM
...
programma:PROGRAM name newline function STARTMAIN dec_var command ENDMAIN eof;
...
PROGRAM: T_PROGRAM  { printf("%s",yytext); };
...

(大文字の単語は言語の一部であるため、PROGRAM のように定義されます) 何か間違ったことを書きますか? 問題は改行の定義にあると思いますが、よくわかりません。

ご回答ありがとうございます。長い投稿で申し訳ありません。

4

1 に答える 1

2

通常、コメントはレクサーによって処理され、パーサーには渡されません。あなたの言語が真に C に似ている場合、ほとんどの場合、改行は他の空白と同じように扱われるべきです。コメントと引用符で囲まれた文字列は注目すべき例外です。引用符で囲まれた文字列は通常、開始状態を使用してレクサーによってキャプチャされ、パーサー全体に渡されます。

フレックス コードで文字セットが多すぎます。特定の 1 文字のみを一致させたい場合は、セットを作成する必要はありません。必要に応じてバックスラッシュでエスケープして、文字を入力するだけです。さらに、.改行以外の文字を意味します。

name_of_programまた、トークンの定義はありません。これが C スタイルの識別子であると仮定すると、識別子パターンとトークンを flex で宣言し、それを bison に渡すことができます。

最後に、flex から bison に渡されるトークンにはすべて大文字を使用し、bison 内で使用されるトークンには小文字を使用するという命名規則を採用することをお勧めします。

したがって、あなたが説明したことから、次のことがわかります。

example.l:

%%

\%.* /* comment */
\n { return T_NEWLINE; }
\' { return T_QUOTE; }
PROGRAM { return T_PROGRAM; }
[A-Za-z_][A-Za-z0-9_]* { yylval.id = yytext; return T_IDENTIFIER; }

%%

例.y:

%%

programma: T_PROGRAM T_IDENTIFIER T_NEWLINE function STARTMAIN dec_var command ENDMAIN eof;

text: 
    | name text
    | digit text;

%%

eofそこにトークンが必要かどうかわかりません。

これが役立つことを願っています。

于 2010-09-12T03:13:49.370 に答える