問題タブ [menhir]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
parsing - トークンの内容に基づくパーサー レバーでの分岐
小さなプロジェクトの単純なパーサー/レクサーの例に取り組んでいますが、問題が発生しました。
私はこれらの行に沿ってコンテンツを解析しています:
…は、 、、または空白SEP
のいずれか (複数ではない!) です。|
,
ここで、フィールドの順序をレクサーの順序にロックしたくなかったので、非常に単純なトークンのセットを使用してこれを lex しようとしています。
ここで、たとえば、gender
フィールドに決定ごとの値の小さなセットが含まれていない場合、解析エラーを生成するように指示されています{male,female,neither,unspecified}
。パーサーをラップしてこれに対処することはできますが、将来の拡張のために、この要件をオートマトンにエンコードしたいと考えています。
私の最初の試みは、次のように見えて、恐ろしく失敗しました:
ええ、サイコロはありません。明らかに、構造化されていないレクシングに対する私の試みは、すでにうまくいっていません。
このようなものを解析する慣用的な方法は何ですか?
parsing - GADT / 存在タイプのペイロードから有用な情報を抽出するにはどうすればよいですか?
生成されたパーサーでMenhirのインクリメンタル解析 APIとイントロスペクション APIを使用しようとしています。たとえば、特定の LR(1) スタック エントリに関連付けられたセマンティック値を決定したいとします。つまり、パーサーによって以前に消費されたトークンです。
Menhir の type にカプセル化された抽象解析チェックポイントが与えられると'a env
、LR オートマトンから「スタック要素」を抽出できます。次のようになります。
type 要素は、LR(1) オートマトンのスタック内の 1 つのエントリを記述します。フォームのスタック要素では
Element (s, v, startp, endp)
、s
は (非初期) 状態でv
あり、セマンティック値です。値v
は、状態の入力シンボル A に関連付けられs
ます。つまり、値v
は状態に入る直前にスタックにプッシュされましたs
。したがって、一部の type'a
の場合、状態s
には type が'a lr1state
あり、値v
には type'a
...があります。値を使って何か有用なことを行うには、状態を調べ
v
て型に関する情報を取得する必要があります。これまでのところ、型は抽象的であるため、検査する方法はありません。検査 API (§9.3) は、この目的のためにさらにツールを提供します。'a
s
'a lr1state
s
よし、かっこいい!そこで、インスペクション API に飛び込みます。
端末の型は、一般化された代数データ型 (GADT) です。タイプ 'a terminal の値は、終端記号を表します (セマンティック値なし)。インデックス 'a は、このシンボルに関連付けられた意味値の型です ...
タイプ 'a 非終端記号も GADT です。タイプ 'a 非終端記号の値は、非終端記号 (意味値なし) を表します。インデックス 'a は、このシンボルに関連付けられた意味値の型です ...
これらをつなぎ合わせると、次のようなものが得られます (ここで、「コマンド」は私の文法の非終端記号の 1 つであり、したがってN_command
ですstring nonterminal
)。
残念ながら、これは私にとって非常に紛らわしいタイプエラーを引き起こしています:
これは私のレベルを少し上回っています!上記でやろうとしたことができない理由を理解していると確信しています。しかし、私は私の代替手段が何であるかを理解していません。実際、Menhir のマニュアルでは、この複雑さについて具体的に言及しています。
v
この関数を使用して、スタック要素のセマンティック値にアクセスできますElement (s, v, _, _)
。実際、シンボル の大文字と小文字を区別するとincoming_symbol s
、型に関する情報が'a
得られるため、値を使用して何か有用な処理を行うことができますv
。
わかりましたが、それは私がやったと思ったことです、上記: match
on 'ingによるケース分析、単一の特定のタイプincoming_symbol s
のケースを引き出します: 。v
string
tl;dr: この GADT から文字列ペイロードを抽出し、それを使って何か役に立つことをするにはどうすればよいですか?