簡體   English   中英

用ebnf語法描述c

[英]Describing c with ebnf grammar

這是 EBNF 中描述 C 的語法:

stmt->  (CASE CONST ‘:’)* expression ‘;’
      | (CASE CONST ‘:’)* IF ‘(’ expression ‘)’ stmt [ELSE stmt]
      | (CASE CONST ‘:’)* WHILE ‘(’ expression ‘)’ stmt
      | (CASE CONST ‘:’)* SWITCH ‘(’ expression ‘)’ stmt
      | (CASE CONST ‘:’)* RETURN [expression] ‘;’
      | (CASE CONST ‘:’)* BREAK ‘;’
      | (CASE CONST ‘:’)* CONTINUE ‘;’
      | ‘{’ (stmt)* ‘}’

我想用這些限制修改上述內容:

  1. CASE 標簽只能用於直接包含在命令 SWITCH 中的命令,不能用於其嵌套的 IF 或 WHILE 命令中。
  2. BREAK 命令只能出現在 WHILE 命令或一個 SWITCH 命令中,包括這些嵌套命令。
  3. CONTINUE 命令只能出現在 WHILE 命令中,包括嵌套命令。

我的答案:

stmt-> ( CONST ‘:’)* expression ‘;’
     | ( CONST ‘:’)* IF ‘(’ expression ‘)’ stmt [ELSE stmt]
     | (CASE CONST ‘:’)* SWITCH ‘(’ expression ‘)’ stmt
     | ( CONST ‘:’)* WHILE ‘(’ expression ‘)’ stmt
     | (CASE CONST ‘:’)* BREAK ‘;’
     | (CASE CONST ‘:’)* CONTINUE ‘;’
     | ( CONST ‘:’)* RETURN [expression] ‘;’
     | ‘{’ (stmt)* ‘}’

這是正確的嗎?

你面臨的任務非常復雜。 作為一種方法(我認為這里沒有足夠的地方來完全解釋它)你可以首先開始寫類似的stmt非終結符,一個接受case語句,一個不接受。 它們必須都源自您發布的原始stmt

stmt_w_case ->  (CASE CONST ‘:’)* expression ‘;’
      | (CASE CONST ‘:’)* IF ‘(’ expression ‘)’ stmt [ELSE stmt]
      | (CASE CONST ‘:’)* WHILE ‘(’ expression ‘)’ stmt
      | (CASE CONST ‘:’)* SWITCH ‘(’ expression ‘)’ stmt
      | (CASE CONST ‘:’)* RETURN [expression] ‘;’
      | (CASE CONST ‘:’)* BREAK ‘;’
      | (CASE CONST ‘:’)* CONTINUE ‘;’
      | ‘{’ (stmt)* ‘}’

stmt_wo_case ->  expression ‘;’
      | IF ‘(’ expression ‘)’ stmt [ELSE stmt]
      | WHILE ‘(’ expression ‘)’ stmt
      | SWITCH ‘(’ expression ‘)’ stmt
      | RETURN [expression] ‘;’
      | BREAK ‘;’
      | CONTINUE ‘;’
      | ‘{’ (stmt)* ‘}’

現在您說您只想在switch語句中使用stmt_w_case ,那么 while stmt應該更改為stmt_w_case而所有其他必須更改為stmt_wo_case ,如

stmt_w_case ->  (CASE CONST ‘:’)* expression ‘;’
      | (CASE CONST ‘:’)* IF ‘(’ expression ‘)’ stmt_wo_case [ELSE stmt_wo_case]
      | (CASE CONST ‘:’)* WHILE ‘(’ expression ‘)’ stmt_wo_case
      | (CASE CONST ‘:’)* SWITCH ‘(’ expression ‘)’ stmt_w_case
      | (CASE CONST ‘:’)* RETURN [expression] ‘;’
      | (CASE CONST ‘:’)* BREAK ‘;’
      | (CASE CONST ‘:’)* CONTINUE ‘;’
      | ‘{’ (stmt_w_case)* ‘}’

stmt_wo_case ->  expression ‘;’
      | IF ‘(’ expression ‘)’ stmt_wo_case [ELSE stmt_wo_case]
      | WHILE ‘(’ expression ‘)’ stmt_wo_case
      | SWITCH ‘(’ expression ‘)’ stmt_w_case
      | RETURN [expression] ‘;’
      | BREAK ‘;’
      | CONTINUE ‘;’
      | ‘{’ (stmt_wo_case)* ‘}’

(查看stmt_wo_case如何將它的條件傳播到括號{}之間的嵌入stmt ,對於stmt_w_case也是如此)

然后你可以說:

stmt -> stmt_wo_case

你的語法已經准備好了(但可能你以后會遇到麻煩,見下文)

break語句的情況下,您應該對新語法執行相同的操作,但要小心,因為在這種情況下,您可以將break很好地嵌套在if語句或類似語句的任何語句中。 對於我們剛剛分叉的每條規則...。您需要執行不同的stmt_w_case_no_breakstmt_w_case_w_break (對於stmt_wo_case...也是如此),您知道這會給我們帶來什么嗎? 在每個地方,我們都需要某種規則,無論有沒有,我們都將規則的數量增加一倍……隨着您做出的此類決策的數量呈指數增長。

這是正確的嗎?

不。語法節目只是說“只有switchbreakcontinue可以有case some-constant:標簽,而其他的可以有some-constant:

要說case label 只能用於直接在 switch 內部的命令, switch的主體,或者可能是 switch 主體的復合語句的主體,必須是語句或語句列表可以有case標簽的類型,而出現在別處的語句或語句列表必須是不能有case標簽的類型的語句。

所以定義一個語法標記,比如MayBeLabeledStatement ,它可以有一個case label 和另一個語法標記,比如Statement ,它不能有一個case label。 兩種語句都可以擴展為各種語句(表達式、 ifwhile等),但MayBeLabeledStatement的語句也可能有case標簽。 此外, MayBeLabeledStatement中的所有語句應該是Statement類型的語句,不能有case標簽——除非您可能需要考慮如何處理switch中的單個語句(可能是復合語句,也可能不是復合語句)。

同樣,您將需要不同的語法標記來處理whileswitch內的語句(允許break )與那些不在whileswitch內的語句,另一個用於處理while或 switch 內的語句(允許continue)與不在while內的語句。 您可能還需要一些組合,對於在while內且直接在switch內的語句與在while內且不直接在switch內的語句。

暫無
暫無

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

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