簡體   English   中英

如何停止解析並重置yacc?

[英]How to stop parsing and reset yacc?

我正在編寫作業控制外殼。 我使用Yacc和Lex進行解析。 我的語法中最重要的規則是pipeline_list ,它是由逗號分隔的管道列表。 因此,管道列表的示例如下:

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

我用pipeline規則代表管道(如下所示)。 在該規則內,我執行以下操作:

1.調用execute_pipeline()執行管道。 如果在管道執行過程中發生任何錯誤, execute_pipeline()將返回-1

2.檢查execute_pipeline()的返回值,如果它是-1 ,則停止解析其余的輸入,並確保在主函數中再次調用YACC時重新啟動(如下所示)。 這樣做的基本原理是:以下面的管道cd ..; ls -al為例: cd ..; ls -al cd ..; ls -al 我的目的是將一個目錄上移,然后列出其內容。 但是,如果在管道列表中執行第一個管道(即"cd .." )失敗,則繼續執行第二個管道(即" ls -al" )將列出當前目錄的內容(而不是家長),這是錯誤的! 因此,在解析長度為n的管道列表時,如果執行某些管道k > 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()

您可以使用YYABORT; 放棄當前解析並立即從yyparse返回失敗的操作。 您可以使用YYACCEPT; 立即從yyparse返回成功。

這兩個宏只能在語法中的動作中直接使用-不能在該動作調用的其他函數中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM