[英]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)* ‘}’
我想用這些限制修改上述內容:
我的答案:
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_break
和stmt_w_case_w_break
(對於stmt_wo_case...
也是如此),您知道這會給我們帶來什么嗎? 在每個地方,我們都需要某種規則,無論有沒有,我們都將規則的數量增加一倍……隨着您做出的此類決策的數量呈指數增長。
這是正確的嗎?
不。語法節目只是說“只有switch
、 break
和continue
可以有case some-constant:
標簽,而其他的可以有some-constant:
。
要說case
label 只能用於直接在 switch 內部的命令, switch
的主體,或者可能是 switch 主體的復合語句的主體,必須是語句或語句列表可以有case
標簽的類型,而出現在別處的語句或語句列表必須是不能有case
標簽的類型的語句。
所以定義一個語法標記,比如MayBeLabeledStatement
,它可以有一個case
label 和另一個語法標記,比如Statement
,它不能有一個case
label。 兩種語句都可以擴展為各種語句(表達式、 if
、 while
等),但MayBeLabeledStatement
的語句也可能有case
標簽。 此外, MayBeLabeledStatement
中的所有語句都應該是Statement
類型的語句,不能有case
標簽——除非您可能需要考慮如何處理switch
中的單個語句(可能是復合語句,也可能不是復合語句)。
同樣,您將需要不同的語法標記來處理while
或switch
內的語句(允許break
)與那些不在while
或switch
內的語句,另一個用於處理while
或 switch 內的語句(允許continue)
與不在while
內的語句。 您可能還需要一些組合,對於在while
內且直接在switch
內的語句與在while
內且不直接在switch
內的語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.