0

小さなプロジェクトの単純なパーサー/レクサーの例に取り組んでいますが、問題が発生しました。

私はこれらの行に沿ってコンテンツを解析しています:

Name SEP Gender SEP Birthday
Name SEP Gender SEP Birthday

…は、 、、または空白SEPのいずれか (複数ではない!) です。|,

ここで、フィールドの順序をレクサーの順序にロックしたくなかったので、非常に単純なトークンのセットを使用してこれを lex しようとしています。

%token <string> SEP
%token <string> VAL
%token NL

%token EOF

ここで、たとえば、genderフィールドに決定ごとの値の小さなセットが含まれていない場合、解析エラーを生成するように指示されています{male,female,neither,unspecified}。パーサーをラップしてこれに対処することはできますが、将来の拡張のために、この要件をオートマトンにエンコードしたいと考えています。

私の最初の試みは、次のように見えて、恐ろしく失敗しました:

doc:
   | EOF              { [] }
   | it = rev_records { it }
   ;

rev_records:
           | (* base-case: empty *) { [] }
           | rest = rev_records; record; NL  { record :: rest }
           | rest = rev_records; record; EOF { record :: rest }
           ;

record:
   last_name = name_field; SEP; first_name = name_field; SEP;
   gender = gender_field; SEP; favourite_colour = colour_field; SEP;
   birthday = date_field
   { {last_name; first_name; gender; favourite_colour; birthday} }

name_field: str = VAL { str }

gender_field:
            | VAL "male" { Person.Male }
            | VAL "female" { Person.Female }
            | VAL "neither" { Person.Neither }
            | VAL "unspecified" { Person.Unspecified }
            ;

ええ、サイコロはありません。明らかに、構造化されていないレクシングに対する私の試みは、すでにうまくいっていません。

このようなものを解析する慣用的な方法は何ですか?

4

1 に答える 1