go/parser: avoid endless loop in case of internal error
go/parser: avoid endless loop in case of internal error

Factored the error synchronization code into two functions
syncStmt and syncDecl. Because they may return w/o advancing
the scanner, there is potential for endless loops across
multiple parse functions; typically caused by an incorrect
token list in these functions (e.g., adding token.ELSE to
syncStmt will cause the parser to go into an endless loop
for test/syntax/semi7.go without this mechanism). This would
indicate a compiler bug, exposed only in an error situation
for very specific source files. Added a mechanism to force
scanner advance if an endless loop is detected. As a result,
error recovery will be less good in those cases, but the parser
reported a source error already and at least doesn't get stuck.

R=rsc, rsc
CC=golang-dev
http://codereview.appspot.com/5784046

h8liu/golang,h8liu/golang,h8liu/golang,h8liu/golang,h8liu/golang,h8liu/golang,h8liu/golang