這是古代懸而未決(如果沒有別的)問題。如果您編寫一些代碼,如
if (a == b) then
if (b == c) then
do_something;
else
do_something_else;
解析器在決定「其他」屬於哪個「if」時會出現問題。 一個解決方案是添加一個分隔符,如「endif」。例如:
if (a == b) then
if (b == c) then
do_something;
endif;
else
do_something_else;
endif;
不再被縮進混淆(我故意做錯了),現在很清楚該怎麼做。
這就是爲什麼像下面列出不起作用的一個語法(它產生了很多衝突):
stmtlist: stmt
| stmtlist stmt
stmt: ifequal
| something_else
ifequal: IFEQUAL '(' expr ',' expr ')' stmtlist opt_lt_gt
opt_lt_gt:
| SMALLER stmtlist
| LARGER stmtlist
| SMALLER stmtlist LARGER stmtlist
但只要語句列表以某種方式從IFEQUAL聲明,例如分離通過使用大括號,問題就消失了。
stmtlist: '{' stmtseq '}'
stmtseq: stmt
| stmtseq stmt
另一種可能性是禁止stmtlist中的不完整的語句。這會或多或少地加倍你的語法。它可能看起來像
fullifequal: IFEQUAL '(' expr ',' expr ')' fstmtlist SMALLER fstmtlist LARGER fstmtlist
fstmtlist: fullstmt
| fstmtlist fullstmt
fullstmt: fullifequal
| some_other
ifequal: IFEQUAL '(' expr ',' expr ')' fstmtlist opt_lt_gt
opt_lt_gt:
| SMALLER fstmtlist
| LARGER fstmtlist
| SMALLER fstmtlist LARGER fstmtlist
個人而言,我更喜歡在大括號解決方案,因爲它很容易閱讀,不限制的「ifequal」語句和解析器代碼中的語句會更短。但我想你會需要另一種解決方案。