私はコンパイラ構築のコースを取っています。現在私が実装している言語用のレクサーを書くのが私の現在の課題です。私は、レクサーが連結トークンを認識しなければならないという要件をどのように満たすかを理解できません。つまり、空白で区切られていないトークンです。例:文字列39if
は、数字39
およびキーワードif
として認識されるはずです。同時に、不正な入力に遭遇した場合には、レクサーはexit(1)
でなければならない。空白で区切られていないトークンをlex/flexで認識させる方法は?
コードの簡易版私が持っている:私はこの(または私の完全なバージョン)を実行し、それを入力39if
を渡すと、エラールールがマッチした、出力はERROR: 39if
、です
%{
#include <stdio.h>
%}
%option main warn debug
%%
if |
then |
else printf("keyword: %s\n", yytext);
[[:digit:]]+ printf("number: %s\n", yytext);
[[:alpha:]][[:alnum:]]* printf("identifier: %s\n", yytext);
[[:space:]]+ // skip whitespace
[[:^space:]]+ { printf("ERROR: %s\n", yytext); exit(1); }
%%
(私は、入力として39 if
に入ったかのようにすなわち、同じ。)
number: 39
keyword: if
:私はそれがしたいのですがの場合、エラールールが数値ルールやキーワードルールよりも長い可能性のある入力と一致し、フレックスがそのルールを優先するという理由があります。つまり、私はこの状況をどのように解決するか考えていません。すべてのエラーでない入力を拒否する明示的な正規表現を書くことは実用的ではないようです。そして、レクサーエラーを処理するために "キャッチオール"ルールをどのように書くべきかわかりません。
UPDATE:私はちょうどキャッチオールルールが. { exit(1); }
も作ることができると仮定が、私は「私は1行目に混乱しました」よりも、いくつかのよりよいデバッグ出力を取得したいのですが。
a)簡易版を実行しましたか? b)それは何が間違っているのですか? –
@IraBaxter申し訳ありませんが、最後の段落のスペキュレーションで失われている間、私のテストケースについて明示するのを忘れてしまったようです。答えは** a)**はいです。 ** b)**は、2つのトークンの代わりにレクサーエラーを報告します。 (私はそれらを質問に加えました。) – millimoose
ああ。はい、あなたの "^スペース"ルールは、スペースのないシーケンスを食べるので、 "39if"を消費します。秘密:長いルールが安全に最初に来ない限り、正規表現が重なるルールは避けてください。あなたの場合、私は(私はlex-pertではない)置き換えるものを使用したいと思う:^スペース:それは "数字ではなく、文字ではなくスペースである"。 ... –