1 /*
2  * routines for printing error messages
3  */
4 
5 #include "defs.h"
6 #include <stdarg.h>
7 
8 extern FILE *inc_file;
9 extern char inc_file_name[];
10 void FileError(char *fmt, ...);
11 
12 /*
13  * VM: print error message with file coordinates.
14  * Do it in style acceptable to emacs.
15  */
FileError(char * fmt,...)16 void FileError(char *fmt, ...) {
17   va_list args;
18 
19   fprintf(stderr, "%s:%d: ", input_file->name, input_file->lineno);
20   va_start(args, fmt);
21   vfprintf(stderr, fmt, args);
22   va_end(args);
23   fprintf(stderr, "\n");
24 }
25 
fatal(char * msg)26 void fatal(char *msg)
27 {
28     fprintf(stderr, "fatal - %s\n", msg);
29     done(2);
30 }
31 
32 
no_space()33 void no_space()
34 {
35     fprintf(stderr, "fatal - out of space\n");
36     done(2);
37 }
38 
39 
open_error(char * filename)40 void open_error(char *filename)
41 {
42     fprintf(stderr, "fatal - cannot open \"%s\"\n", filename);
43     done(2);
44 }
45 
46 
unexpected_EOF()47 void unexpected_EOF()
48 {
49   FileError("unexpected end-of-file");
50   done(1);
51 }
52 
53 
print_pos(char * st_line,char * st_cptr)54 void print_pos(char *st_line, char *st_cptr)
55 {
56     register char *s;
57 
58     if (st_line == 0) return;
59     for (s = st_line; *s != '\n'; ++s)
60     {
61 	if (isprint(*s) || *s == '\t')
62 	    putc(*s, stderr);
63 	else
64 	    putc('?', stderr);
65     }
66     putc('\n', stderr);
67     for (s = st_line; s < st_cptr; ++s)
68     {
69 	if (*s == '\t')
70 	    putc('\t', stderr);
71 	else
72 	    putc(' ', stderr);
73     }
74     putc('^', stderr);
75     putc('\n', stderr);
76 }
77 
78 int read_errs = 0;
79 
error(int lineno,char * line,char * cptr,char * msg,...)80 void error(int lineno, char *line, char *cptr, char *msg, ...)
81 {
82   char sbuf[512];
83   va_list args;
84 
85   va_start(args, msg);
86   vsprintf(sbuf, msg, args);
87   va_end(args);
88   FileError("%s", sbuf);
89   read_errs++;
90 }
91 
syntax_error(int lineno,char * line,char * cptr)92 void syntax_error(int lineno, char *line, char *cptr) {
93   error(lineno, line, cptr, "syntax error");
94   exit(1);
95 }
96 
unterminated_comment(int lineno,char * line,char * cptr)97 void unterminated_comment(int lineno, char *line, char *cptr) {
98   error(lineno, line, cptr, "unmatched /*");
99   exit(1);
100 }
101 
unterminated_string(int lineno,char * line,char * cptr)102 void unterminated_string(int lineno, char *line, char *cptr) {
103   error(lineno, line, cptr, "unterminated string");
104   exit(1);
105 }
106 
unterminated_text(int lineno,char * line,char * cptr)107 void unterminated_text(int lineno, char *line, char *cptr) {
108   error(lineno, line, cptr, "unmatched %%{");
109   exit(1);
110 }
111 
unterminated_union(int lineno,char * line,char * cptr)112 void unterminated_union(int lineno, char *line, char *cptr) {
113   error(lineno, line, cptr, "unterminated %%union");
114   exit(1);
115 }
116 
over_unionized(char * cptr)117 void over_unionized(char *cptr) {
118   error(input_file->lineno, line, cptr, "too many %%union declarations");
119   exit(1);
120 }
121 
repeat_location_defined(char * cptr)122 void repeat_location_defined(char *cptr) {
123   error(input_file->lineno, line, cptr, "too many %%location declarations");
124   exit(1);
125 }
126 
illegal_tag(int lineno,char * line,char * cptr)127 void illegal_tag(int lineno, char *line, char *cptr) {
128   error(lineno, line, cptr, "illegal tag");
129 }
130 
illegal_character(char * cptr)131 void illegal_character(char *cptr) {
132   error(input_file->lineno, line, cptr, "illegal character");
133 }
134 
used_reserved(char * s)135 void used_reserved(char *s) {
136   error(input_file->lineno, 0, 0, "illegal use of reserved symbol %s", s);
137 }
138 
tokenized_start(char * s)139 void tokenized_start(char *s) {
140   error(input_file->lineno, 0, 0, "the start symbol %s cannot be declared to be a token", s);
141 }
142 
retyped_warning(char * s)143 void retyped_warning(char *s) {
144   FileError("the type of %s has been redeclared", s);
145 }
146 
147 
reprec_warning(char * s)148 void reprec_warning(char *s) {
149   FileError("the precedence of %s has been redeclared", s);
150 }
151 
152 
revalued_warning(char * s)153 void revalued_warning(char *s) {
154   FileError("the value of %s has been redeclared", s);
155 }
156 
157 
terminal_start(char * s)158 void terminal_start(char *s) {
159   error(input_file->lineno, 0, 0, "the start symbol %s is a token", s);
160 }
161 
restarted_warning()162 void restarted_warning() {
163   FileError("the start symbol has been redeclared");
164 }
165 
no_grammar()166 void no_grammar() {
167   error(input_file->lineno, 0, 0, "no grammar has been specified");
168 }
169 
terminal_lhs(int lineno)170 void terminal_lhs(int lineno) {
171   error(lineno, 0, 0, "a token appears on the lhs of a production");
172 }
173 
prec_redeclared()174 void prec_redeclared() {
175   error(input_file->lineno, 0, 0, "conflicting %%prec specifiers");
176 }
177 
unterminated_action(int lineno,char * line,char * cptr)178 void unterminated_action(int lineno, char *line, char *cptr) {
179   error(lineno, line, cptr, "unterminated action");
180 }
181 
unterminated_arglist(int lineno,char * line,char * cptr)182 void unterminated_arglist(int lineno, char *line, char *cptr) {
183   error(lineno, line, cptr, "unterminated argument list");
184 }
185 
bad_formals()186 void bad_formals() {
187   error(input_file->lineno, 0, 0, "bad formal argument list");
188 }
189 
dollar_warning(int a_lineno,int i)190 void dollar_warning(int a_lineno, int i) {
191   int slineno = input_file->lineno;
192   input_file->lineno = a_lineno;
193   FileError("$%d references beyond the end of the current rule", i);
194   input_file->lineno = slineno;
195 }
196 
dollar_error(int lineno,char * line,char * cptr)197 void dollar_error(int lineno, char *line, char *cptr) {
198   error(lineno, line, cptr, "illegal $-name");
199 }
200 
at_warning(int a_lineno,int i)201 void at_warning(int a_lineno, int i) {
202   int slineno = input_file->lineno;
203   input_file->lineno = a_lineno;
204   FileError("@%d references beyond the end of the current rule", i);
205   input_file->lineno = slineno;
206 }
207 
at_error(int lineno,char * line,char * cptr)208 void at_error(int lineno, char *line, char *cptr) {
209   error(lineno, line, cptr, "illegal @-name");
210 }
211 
untyped_lhs()212 void untyped_lhs() {
213   error(input_file->lineno, 0, 0, "$$ is untyped");
214 }
215 
untyped_rhs(int i,char * s)216 void untyped_rhs(int i, char *s) {
217   error(input_file->lineno, 0, 0, "$%d (%s) is untyped", i, s);
218 }
219 
unknown_rhs(int i)220 void unknown_rhs(int i) {
221   error(input_file->lineno, 0, 0, "$%d is untyped (out of range)", i);
222 }
223 
default_action_warning(char * s)224 void default_action_warning(char *s) {
225   FileError("the default action for %s assigns an undefined value to $$", s);
226 }
227 
inconsistent_trial_action_warning(char * s)228 void inconsistent_trial_action_warning(char *s) {
229   FileError("inconsistent trial actions for %s", s);
230 }
231 
undefined_goal(char * s)232 void undefined_goal(char *s) {
233   error(input_file->lineno, 0, 0, "the start symbol %s is undefined", s);
234 }
235 
undefined_symbol_warning(char * s)236 void undefined_symbol_warning(char *s) {
237   fprintf(stderr, "warning - the symbol %s is undefined\n", s);
238 }
239 
unused_destructor_warning(int lineno)240 void unused_destructor_warning(int lineno)
241 {
242   error(lineno, 0, 0, "unused %%destructor");
243 }
244