10

このプロセスでlexを学習しています.C言語のトークンを生成しています.1行のコメント「//」を認識しようとしていますが、除算演算子と競合しています.

[1-9][0-9]*|0x[0-9a-fA-F][0-9a-fA-F]*           return NUMBER;
[a-zA-Z][a-zA-Z0-9]*                            return IDENT;
/                                               {return DIVIDE;}

[ \t\r\n]
[//]

しかし、例を実行して // を入力すると、2 つの除算演算子として認識されます。コードをどこで変更する必要がありますか。助言がありますか。

編集:

レックスコード:

%{
#include "y.tab.h"
%}
%array
%%
if                                              {return IF;}
while                                           {return WHILE;}
else                                            {return ELSE;}
int                                             {return INT;}
return                                          {return RETURN;}
\/\/[^\r\n]*
[1-9][0-9]*|0x[0-9a-fA-F][0-9a-fA-F]*           return NUMBER;
[a-zA-Z][a-zA-Z0-9]*                            return IDENT;

[+]                                             {return ADD;}
[-]                                             {return SUB;}
[<]                                             {return LESS;}
[>]                                             {return GREAT;}
[*]                                             {return MULT;}
[/]                                             {return DIVIDE;}
[;]                                             {return SEMICOLON;}

\{                                              return LBRACE;
\}                                              return RBRACE;

[ \t\r\n]

\(                                              return LPAREN;

\)                                              return RPAREN;

.                                               return BADCHAR;
%%

以下は私が使用するヘッダーファイルです

typedef enum {END=0, WHILE, IF, ELSE,RETURN, IDENT, LPAREN, RPAREN,INT,LBRACE,RBRACE, SEMICOLON, EQUALITY, DIVIDE, MULT, LESS, GREAT,
 ADD, SUB, NUMBER,BADCHAR} Token;

以下は、実行中の入力です。

//
/
p
Token 16, text /
Token 16, text /
Token 16, text /
Token 5, text p

実行すると、コメントが消費され、除算演算子でさえ無視されます。しかし、p を入力するときに確認してください。上記の演算子は分類されますが、これは行うべきではありません。

Note: Am trying to ignore tabs, newline characters and single line comments. 

Note 2: \/\/[^\r\n]* I have understood where I committed the mistake and wanted to share this.
4

1 に答える 1

8

レックスのマニュアルによると:

Lex で作成された字句解析プログラムは、あいまいな仕様を受け入れ、各入力ポイントで可能な最長一致を選択します。必要に応じて、入力に対して実質的な先読みが実行されますが、入力ストリームは現在のパーティションの最後までバックアップされるため、ユーザーは一般的に自由に操作できます。

したがって、特別なことをする必要はありません -//はより長い/ので、除算演算子が 2 つある場合はコメントよりも優先されます。しかし、あなたはコメント ルールを投稿していません。どこにあるのでしょうか?

編集:気にしないでください。 [//]文字クラスです。角かっこを削除します。また、行末まで一致させる必要があります。そうしないと、空のコメントしか許可されません。したがって、正規表現は次のようになります。

//[^\r\n]*\r\n(サポートしている改行文字に合わせて必要に応じて調整します。これには、改行が正確であることが必要です\r\n)。

編集 2 : @tur1ng は良い点をもたらします - ファイルの最後の行は改行で終わらないかもしれません。調べたところ、Lex は<<EOF>>その正規表現でもサポートしています ( http://pltplp.net/lex-yacc/lex.html.enを参照)。したがって、次のように変更できます。

//[^\r\n]*((\r\n)|<<EOF>>)

于 2010-02-12T04:40:05.780 に答える