簡體   English   中英

C 中 shell 的 LL1 語法不明確或沖突

[英]ambiguous or conflict in LL1 grammar for a shell in C

我正在為執行 shell 實現的項目實現 LL(1) 解析器。 我一直在嘗試解決語法中的沖突:

Parsing mode: LL(1).

Grammar:

     1. COMMAND_LINE -> COMPLETE_COMMAND PIPED_CMD
     2. PIPED_CMD -> PIPE COMPLETE_COMMAND PIPED_CMD
     3.            | ε
     4. COMPLETE_COMMAND -> CMD_PREFIX CMD CMD_SUFFIX
     5. CMD_PREFIX -> REDIRECTION CMD_PREFIX
     6.             | ε
     7. CMD_SUFFIX -> REDIRECTION CMD_SUFFIX
     8.             | CMD_ARG CMD_SUFFIX
     9.             | ε
    10. REDIRECTION -> REDIRECTION_OP WORD
    11.              | ε
    12. CMD -> WORD
    13. CMD_ARG -> WORD CMD_ARG
    14.          | SINGLE_QUOTE WORD DOUBLE_QUOTE CMD_ARG
    15.          | DOUBLE_QUOTE WORD DOUBLE_QUOTE CMD_ARG
    16.          | ε
    17. REDIRECTION_OP -> HERE_DOC
    18.                 | APPEND
    19.                 | INFILE
    20.                 | OUTFILE

我使用 syntax-cli 檢查我的語法,而 ll(1) 解析器是一個自制的實現,如果需要我可以鏈接我的解析器實現。 syntax-cli 檢測到的沖突是:

管道 單詞 單引號 雙引號 HERE_DOC 附加 輸入文件 外檔 $
CMD_SUFFIX 9 7/8 7/8 7/8 7/8 7/8 7/8 7/8 9
重定向 11 11 11 11 10/11 10/11 10/11 10/11 11
命令參數 16 13/16 14/16 15/16 16 16 16 16 16

我也試過這個語法:


COMMAND_LINE     
                 : COMPLETE_COMMAND PIPED_CMD
                 ;
PIPED_CMD        
                 : PIPE COMPLETE_COMMAND PIPED_CMD
                 |
                 ;
COMPLETE_COMMAND 
                 : REDIRECTION CMD REDIRECTION CMD_ARG REDIRECTION
                 ;
REDIRECTION      
                 : REDIRECTION_OP WORD
                 | 
                 ;

CMD              
                 : WORD
                 ;
CMD_ARG          
                 : WORD REDIRECTION CMD_ARG
                 | SINGLE_QUOTE WORD DOUBLE_QUOTE REDIRECTION CMD_ARG
                 | DOUBLE_QUOTE WORD DOUBLE_QUOTE REDIRECTION CMD_ARG
                 | REDIRECTION
                 ;
REDIRECTION_OP
                 : HERE_DOC
                 | APPEND
                 | INFILE
                 | OUTFILE
                 ;

但是解析器在使用多個重定向時不起作用......

如果沒有代表您的更多規范,則無法確保擁有全部。 但事實上,這個語法是有歧義的。

要構建 LL(1) 分析器,您必須能夠說出,對於分析器堆棧上的符號的任意組合(符號是終端或非終端尚未讀取)和輸入緩沖區中的任何單詞,應該采用什么規則申請。

將自己置於代碼以WORD開頭的情況(這是輸入緩沖區中的第一件事)

您首先嘗試分析COMMAND_LINE

如果輸入緩沖區以WORD開頭,那么只有一個規則可以導致COMMAND_LINE ,即規則COMPLETE_COMMAND PIPED_CMD (無論如何,無論輸入什么,只有這條規則。要么我們可以應用它,要么它是語法錯誤。但現在, 沒有理由引發語法錯誤,此規則與以WORD開頭的規則兼容)。

所以,現在,在你的堆棧上你有COMPLETE_COMMAND PIPED_CMD ,並且在輸入緩沖區中,仍然是相同的WORD

堆棧頂部唯一可能的規則是COMPLETE_COMMAND -> CMD_PREFIX CMD CMD_SUFFIX

所以,現在,在你的堆棧上你有CMD_PREFIX CMD CMD_SUFFIX PIPED_CMD

並在輸入緩沖區WORD中等待

可以從CMD_PREFIX應用 2 條規則:
CMD_PREFIX -> REDIRECTION CMD_PREFIX
CMD_PREFIX -> ε

他們都不能以WORD開頭。 所以要么我們說我們這里有一個空的CMD_PREFIX (后面是一個以WORD開頭的CMD

或者我們可以將其視為后跟空前綴的REDIRECTION REDIRECTION可以是REDIRECTION -> ε

所以在這一點上兩者都是可能的。 要么我們有一個CMD_PREFIX(ε)要么我們有一個CMD_PREFIX(REDIRECTION(ε), ε) (或者更多的遞歸)。

對於要成為 LL(1) 的文法,我們不應該更深入地決定。 從這一點來看,只要知道下一個詞位是WORD ,我們也應該能夠在其中進行選擇。 我們不是。

(事實上 ,即使使用 LL(1) 以外的其他語法,我們也無法決定)

暫無
暫無

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

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