2012-06-14 52 views
0

我寫了一個flex/bison prog語言解析器。目前差不多完成了(我認爲完成了,只需要處理語法錯誤)。在特定的班級中,會出現一些奇怪的問題。關於移位/減少警告的野牛

我相信問題出在解析器中。我停止看今天編譯控制檯,我又回到了它,看到一件壞事:

parser.y: conflicts: 801 shift/reduce, 237 reduce/reduce 

之後,我重新建立解析器和閱讀的結果,發現問題後馬上做到了。

input: 
    | input expression { std::cout << $2; } 
    ; 

expression: 
     expression comparing expression { $$ = new AExpOperation($1, $2, $3); } 
    | expr2 { $$ = $1; } 
    | TNEW identifier TLBRACKET TRBRACKET { $$ = new AExpNewArray(NULL, $2); } 
    | TLPAREN expression TRPAREN { $$ = new AExpParent($2); } 
    ; 

expr2: 
     TPLUS expr2 { $$ = $2; } 
    | TMINUS expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | TBNOT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | TNOT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | expr2 TINCREMENT { $$ = new AExpFastOp($1, $2, false); } 
    | TINCREMENT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | expr2 TDECREMENT { $$ = new AExpFastOp($1, $2, false); } 
    | TDECREMENT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    ; 

comparing: 
     TEQ | TNE | TLT | TLE | TGT | TGE | TPLUS | TMINUS | TDIVIDE | TMULT | TOR | TAND 
    | TBXOR | TLSHIFT | TRSHIFT | TZFILL | TBOR | TBAND | TBNOT | TEQA | TNEA | TINSTANCEOF 
    ; 

identifier: 
     TNUMBER { $$ = new AExpression($1); } 
    | TNAME { $$ = new AExpression($1); } 
    | TSTRING { $$ = new AExpression($1); } 
    | TFALSE { $$ = new AExpression($1); } 
    | TTRUE { $$ = new AExpression($1); } 
    | TNULL { $$ = new AExpression($1); } 
    | TTHIS { $$ = new AExpression($1); } 
    ; 

只是這個小部分得到了,爲什麼我沒有理解錯誤:

parser.y: warning: 1 useless nonterminal and 9 useless rules 
parser.y:40.25-29: warning: useless nonterminal: expr2 
parser.y:69.11-28: warning: useless rule: expression: expr2 
parser.y:75.11-34: warning: useless rule: expr2: TPLUS expr2 
parser.y:76.11-63: warning: useless rule: expr2: TMINUS expr2 
parser.y:77.11-62: warning: useless rule: expr2: TBNOT expr2 
parser.y:78.11-61: warning: useless rule: expr2: TNOT expr2 
parser.y:79.11-68: warning: useless rule: expr2: expr2 TINCREMENT 
parser.y:80.11-67: warning: useless rule: expr2: TINCREMENT expr2 
parser.y:81.11-68: warning: useless rule: expr2: expr2 TDECREMENT 
parser.y:82.11-67: warning: useless rule: expr2: TDECREMENT expr2 

爲什麼它說t此外表達式2是沒用的,例如?

現在我想知道有多少不好轉變/減少和減少/減少?

嗯,我需要一個線索。

+1

對於轉換/減少衝突,您是否對操作員有任何優先級聲明?如果沒有,你會得到大量的轉換/減少衝突,因爲'野牛'不知道運營商的優先級是什麼。 – templatetypedef

回答

1

簡而言之,您確實想要解決您的班次/減少並減少/減少衝突。衝突是解析器生成器說的方式,它不知道你想要應用哪個生產,只要給出一個特定的(模糊的)輸入。

我認爲「無用」是野牛的說法,沒有可能的輸入,非終端expr2可以應用。

關於您的語法的一些觀察:(1)您的表達非終端似乎缺少identifier的規則。我讀你的語法的方式,「a + 2」不是一個有效的表達式。 (2)沒有聲明分隔符讓我困擾 - 這沒有錯,但我認爲你引入了模棱兩可的機會。也許這是你正在解析的語言的一個約束。

一種可能的策略:臨時刪除一元運算符功能(expr2)並讓解析器的其餘部分工作;然後再添加該功能。

1

它告訴你規則expr2永遠不能減少,因爲沒有生產的expr2不包含遞歸expr2,這意味着無限(有限)輸入可以匹配一個expr2

您可能意思是生產expr2: identifier生產 - 增加這將使useless rule警告消失,但仍然會留下一些轉移/減少和減少/衝突得到解決。