私は小さなシェルを実装しており、lex&yacc を使用してコマンドを解析しています。Lex は からコマンドを読み取りstdin
、yacc は の後にコマンドを実行しyyparse
ます。
問題は、構文エラーがある場合、yacc がエラーを表示して最初から解析することです。この場合、構文エラーであるcmd1 >>> cmd2
ため、実行につながりcmd2
ます。>>>
私の質問は、構文エラーが発生した後に現在のコマンドの残りを破棄する方法です。
私は小さなシェルを実装しており、lex&yacc を使用してコマンドを解析しています。Lex は からコマンドを読み取りstdin
、yacc は の後にコマンドを実行しyyparse
ます。
問題は、構文エラーがある場合、yacc がエラーを表示して最初から解析することです。この場合、構文エラーであるcmd1 >>> cmd2
ため、実行につながりcmd2
ます。>>>
私の質問は、構文エラーが発生した後に現在のコマンドの残りを破棄する方法です。
ユーザーが式を入力できるようにするプロンプトを備えた対話型言語を作成する場合、入力ストリーム全体で単純に yacc を使用するのはお勧めできません。yacc は、ある行の何かについて混乱し、その後の行を誤解する可能性があります。たとえば、ユーザーが最初の行の括弧のバランスを崩している可能性があります。または閉じられていない文字列リテラルの場合、yacc は入力の後続の行を消費し続け、構造を閉じようとします。
ユーザーからの入力行を収集し、それを 1 つの単位として解析することをお勧めします。行の終わりは、Yacc に関する限り、単純に入力の終わりです。
FILE *
lex を使用している場合、ストリームからではなくメモリ内のバッファから文字を読み取るように lex をリダイレクトする方法があります。YY_INPUT
Lex ファイルで定義できるマクロのドキュメントを探して、基本的に Lex が入力文字を取得するために使用するコードを指定します。
類推時間:インタラクティブなユーザー入力を直接処理するために lex/yacc で開発されたスキャナーを使用することは、を使用scanf
してユーザー入力を処理することに少し似ています。行をバッファにキャプチャしてから解析するのは、sscanf
. 見積もり:
制御を取り戻したり、スキャンを再開したり、一致しなかった場合は入力を破棄したりするのはとても簡単なので、(戻り値がチェックされている限り) sscanf で文字列を解析することは完全に適切です。 [comp.lang.c FAQ 、12.20]。