2017-08-31 8 views
0

私はジョブコントロールシェルを作成しています。私は解析のためにYaccとLexを使う。私の文法の最上位のルールは、pipeline_listです。これはコンマで区切られたパイプラインのリストです。yaccの解析とリセットを停止するには?

cmd1 | cmd2; cmd3; cmd4 | cmd5 <newline> 
cmd1 <newline> 
<nothing> <newline> 

Iは(以下を示した)pipelineルールパイプラインを表す次のよう従って、pipelinelistsの例です。そのルールの中で、私は以下のようにします:

1.パイプラインを実行するにはexecute_pipeline()を呼び出します。 execute_pipeline()は、パイプラインの実行に問題があれば-1を返します。

execute_pipeline()の戻り値をチェックし、それが-1であれば、入力の残りの部分を解析し、停止、および主な機能(下記参照)に再び呼び出されたときYACCは新鮮な始まりを確認してください。これを行うための論理的根拠は次のとおりです。 たとえば、次のパイプライン担当者を取る:cd ..; ls -al。ここで私の意図は、1つのディレクトリを移動し、その内容を一覧表示することです。しかしながら、パイプラインリスト内の第1のパイプライン(すなわち、"cd ..")の実行に失敗した場合、第2のパイプライン(すなわち、" ls -al")を実行するために続けて実行すると、カレントディレクトリの内容(親ではない)この理由から、長さがnのパイプラインリストを解析するときに、あるパイプラインの実行が失敗した場合、残りのパイプラインリスト(パイプラインk+1..n)を破棄して、yyparse()の次の呼び出しが真新しい(すなわち、readline()から新しい入力を受け取ります - 下のコードを参照してください)。 場合は、次のことを試してみましたが、それは動作しません:

pipeline: 
simple_command_list redirection_list background pipeline_terminator // ignore these 
{ 
if (execute_pipeline() == -1) 
{ 
    // do some stuff 
    // then call YYABORT, YYACCEPT, or YYERROR, but none of them works 
} 
} 


int main() 
{ 
    while(1) 
    { 
     char *buffer = readline("> "); 
     if (buffer) 
     { 
      struct yy_buffer_state *bp; 
      bp = yy_scan_string(buffer); 
      yy_switch_to_buffer(bp); 

      yyparse() 

      yy_delete_buffer(bp); 

      free(buffer); 
     } // end if 

    } // end while 
    return 0; 
} // end main() 
+0

提案:パーサーでコマンドを実行しないでください。ツリーを構築し、パーサーエラーがない場合は別のパスで評価します。パーサの状態とのやりとりを心配することなくエラーを処理できます。 – Kaz

答えて

0

あなたは現在の解析を中止し、すぐに故障ではyyparseから復帰するアクションでYYABORT;を使用することができます。 YYACCEPT;を使用すると、yyparseからの成功をすぐに返すことができます。

これらのマクロは両方とも、文法のアクションで直接使用することができます。アクションによって呼び出される他の関数では使用できません。

+0

YYABORTを使用しようとしましたが(上記のコードのセクションを参照)、動作しませんでした。 – joenatech7

+0

上記のコードセクションは構文的に正しくなく、bisonからエラーが返されます。正しく使用され、YYABORTは正常に動作します。 [mvce](https://stackoverflow.com/help/mcve)を作成して、発生している問題を表示してみてください。 –

関連する問題