2009-05-08 12 views
3

とのデータの上に残され、それにもかかわらず、私は解析とLEX/yaccのに対して完全に新たなんだ、と私は私の頭の上の方法で、おそらくだけど、:トークン化は、私を許しLEX/yaccの

私はかなりを書いていますPLYを使った基本的な電卓ですが、入力は必ずしも方程式ではないかもしれませんし、解析するかどうかを判断する必要があります。極端な入力は、解析された方程式に完全に評価されるものであり、解析して計算したり、方程式のようなものではなく、解析に失敗したり、うまくいくものです。

灰色の領域は、方程式のような部分を持つ入力です。その部分は、パーサが把握して取り除くものです。これは私が欲しいものではありません。文字列の一部がピックアップされてトークン化されないようにする必要があります。エラーを返すことができますが、どうすればいいか分かりません。

私は、基本的に「残っているものをキャッチする」トークンをどのように定義できるのか誰にも分かりますか?それとも私がこれを扱う良い方法はありますか?

答えて

1

yaccにはerrorトークンが組み込まれています。 equationに一致しない行はbadlineによって処理されます

line: goodline | badline ;

badline : error '\n' /* Error-handling action, if needed */

goodline : equation '\n' ;

:あなたは、通常のように何かをするでしょう。

エラー処理操作でyyerrokを使用して、エラー処理が次の行でリセットされるようにすることができます。

+0

それはトリックでした。私はちょうどfalseを返したt_errorトークンを追加し、すべてが完全に起こります。ありがとう! – bck

0

私は通常、別のコマンドリーダーを使用して完全なコマンド(おそらくあなたのケースの行)をホスト変数文字列にしてから、字句解析ツールが文字列を解析するように手配します終わりに達する。これはセットアップが難しいですが、いくつかのクラスのエラー報告を簡単にします。私はこのテクニックを日常的に使ってきた場所の1つに、3つのコメント慣習、2つの引用符付き文字列、および私の歯をエッジに設定するためのいくつかの厄介な点があります。

それ以外の場合は、Yacc 'error'トークンを使用したDonのアドバイスが有効です。

1

トークン(入力の終わり)を定義し、レクサーが入力の最後にそれを出力させます。

あなたは、これらのトークンを持っていた場合は前:だから、

'1' 'PLUS' '1' 

あなたが今持っているでしょう:

'1' 'PLUS' '1' 'END_OF_INPUT' 

さて、あなたはあなたのパーサーであなたのトップレベルのルールを定義することができます。 (例えば)の代わりに:

Equation ::= EXPRESSION 

あなたは明らかに

Equation ::= EXPRESSION END_OF_INPUT 

があるでしょう、あなたはPLY構文でこれらを書き換える必要があるでしょうが、これはあなたの道のほとんどを取得する必要があります。

+0

これは、標準のyaccがどのように動作するかを示しています。それ以上のトークンが残っていない場合のみ、accepotsが有効になります。 – Ingo

0

すでに解決策を見つけたようですが、あなたや他の人が別の方法に興味がある場合に備えて、別の提案を追加します。

あなたはPLYを使用していますが、コンパイラをPython環境で実行したいからです。そうであれば、他のツールも考えてみてください。そのような仕事のために、私はPythonコードジェネレータを持つANTLR(http://www.antlr.org)をよく使用します。 ANTLRは、レクサーレベルで入力を束ねるようなことをするためのたくさんのトリックを持っているので、パーサーはそれを決して見ることができません(例えばコメント)、より大きな文法の中でサブルール(例えば方程式)を呼び出す能力ルールは入力を処理せずにマッチしました...やりたいこととやや同じように聞こえる)と、非常に良い左因子分解アルゴリズムです。

ANTLRsの解析機能とStringTemplate(http://www.stringtemplate.org)エンジンを組み合わせると、素晴らしい組み合わせが得られ、どちらもPythonをサポートしています。

関連する問題