summaryrefslogtreecommitdiff
path: root/src/cmd/gc/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r--src/cmd/gc/subr.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 74ca4cc2c..9d0c84ac4 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -6,6 +6,7 @@
#include "md5.h"
#include "y.tab.h"
#include "opnames.h"
+#include "yerr.h"
typedef struct Error Error;
struct Error
@@ -120,14 +121,47 @@ yyerrorl(int line, char *fmt, ...)
fatal("too many errors");
}
+extern int yystate, yychar;
+
void
yyerror(char *fmt, ...)
{
+ int i;
+ static int lastsyntax;
va_list arg;
- if(strcmp(fmt, "syntax error") == 0) {
- yyerrorl(lexlineno, "syntax error near %s", lexbuf);
+ if(strncmp(fmt, "syntax error", 12) == 0) {
nsyntaxerrors++;
+
+ if(debug['x'])
+ print("yyerror: yystate=%d yychar=%d\n", yystate, yychar);
+
+ // only one syntax error per line
+ if(lastsyntax == lexlineno)
+ return;
+ lastsyntax = lexlineno;
+
+ // look for parse state-specific errors in list (see go.errors).
+ for(i=0; i<nelem(yymsg); i++) {
+ if(yymsg[i].yystate == yystate && yymsg[i].yychar == yychar) {
+ yyerrorl(lexlineno, "syntax error: %s", yymsg[i].msg);
+ return;
+ }
+ }
+
+ // plain "syntax error" gets "near foo" added
+ if(strcmp(fmt, "syntax error") == 0) {
+ yyerrorl(lexlineno, "syntax error near %s", lexbuf);
+ return;
+ }
+
+ // if bison says "syntax error, more info"; print "syntax error: more info".
+ if(fmt[12] == ',') {
+ yyerrorl(lexlineno, "syntax error:%s", fmt+13);
+ return;
+ }
+
+ yyerrorl(lexlineno, "%s", fmt);
return;
}