[英]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.