lex / yaccを使用して残ったデータをトークン化する
質問
お許しください。私は構文解析とlex / yaccにまったく慣れていないので、おそらく頭を抱えていますが、それでもなお:
私はPLYを使ってかなり基本的な計算機を書いていますが、その入力は常に方程式であるとは限らないので、解析するときに計算するかどうかを判断する必要があります。入力の極値は、完全に評価されて方程式を完全に評価するもの(解析して問題なく計算するもの)、または方程式とはまったく異なるものであり、解析に失敗して正常に処理されるものです。
灰色の領域は方程式のような部分を持つ入力であり、パーサーはその部分を取得して解決します。これは私が望むものではありません-エラーをスローバックできるように、文字列の一部がピックアップされトークン化されなかったかどうかを知る必要がありますが、これを行う方法がわかりません。
基本的に「残っているものをキャッチ」トークンを定義する方法を知っている人はいますか?または、これを処理するより良い方法はありますか?
解決
yaccには組み込みのerror
トークンがあります。通常は次のようにします:
line: goodline | badline ;
badline : error '\n' /* Error-handling action, if needed */
goodline : equation '\n' ;
equation
と一致しない行は、badline
によって処理されます。
次の行のエラー処理が確実にリセットされるように、エラー処理アクションでyyerrok
を使用できます。
他のヒント
トークン(入力の終わり)を定義し、入力の終わりにレクサーがトークンを出力するようにします。
以前、これらのトークンがある場合:
'1' 'PLUS' '1'
これで次のようになります:
'1' 'PLUS' '1' 'END_OF_INPUT'
これで、パーサーでトップレベルのルールを定義できます。代わりに(たとえば):
Equation ::= EXPRESSION
次のものがあります
Equation ::= EXPRESSION END_OF_INPUT
明らかに、これらをPLY構文で書き換える必要がありますが、これでほとんどの方法が得られるはずです。
通常、別の「コマンドリーダー」を使用して完全なコマンド(おそらくあなたの場合は1行)をホスト変数文字列に取得し、字句解析器が文字列を分析するように手配します。最後に到達します。これは設定が困難ですが、エラー報告のいくつかのクラスを簡単にします。このテクニックを日常的に使用している場所の1つには、3つのコメント規則、2つの引用符付き文字列、および歯をエッジに設定するためのいくつかの厄介な複数行コマンドがあります(コンテキスト依存トークン化-うん!)。
それ以外の場合、Yaccの「エラー」トークンを使用したDonのアドバイスは適切です。
すでに解決策を見つけているように見えますが、別のアプローチに興味がある場合に備えて、別の提案を追加します。
PLYを使用していると言いますが、コンパイラをPython環境で実行したいのですか?もしそうなら、他のツールも検討するかもしれません。そのような仕事には、Pythonコードジェネレーターを備えたANTLR( http://www.antlr.org )をよく使用します。 。 ANTLRには、レクサーレベルで大量の入力を食べるなどのことを行うための多くのトリックがあり、パーサーはそれを見ることができません(コメントなど)、大きな文法内でサブルール(方程式など)を呼び出す機能(一度終了する必要があります)これ以上の入力を処理せずにルールが一致しました...あなたがやりたいことのように聞こえます)と非常に素晴らしい左ファクタリングアルゴリズム。
ANTLRの解析機能とStringTemplateの使用の組み合わせ( http://www.stringtemplate.org )エンジンは素晴らしい組み合わせを作成し、両方がPythonをサポートします(他の多くのものの中でも)。