1 /* Copyright 2002 Rene Rivera.
2 ** Distributed under the Boost Software License, Version 1.0.
3 ** (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
12 # yyacc - yacc wrapper
14 # Allows tokens to be written as `literal` and then automatically
15 # substituted with #defined tokens.
18 # yyacc file.y filetab.h file.yy
21 # file.yy yacc grammar with ` literals
25 # filetab.h array of string <-> token mappings
28 # Documented and p moved in sed command (for some reason,
29 # s/x/y/p doesn't work).
31 # Take basename as second argument.
33 # reversed order of args to be compatible with GenFile rule
35 # Reimplemented as a C program for portability. (Rene Rivera)
39 char * copy_string(char * s, int l);
40 char * tokenize_string(char * s);
41 int cmp_literal(const void * a, const void * b);
49 int main(int argc, char ** argv)
59 FILE * token_output_f = 0;
60 FILE * grammar_output_f = 0;
61 FILE * grammar_source_f = 0;
63 grammar_source_f = fopen(argv[3],"r");
64 if (grammar_source_f == 0) { result = 1; }
67 literal literals[1024];
72 if (fgets(l,2048,grammar_source_f) != 0)
77 char * c1 = strchr(c,'`');
80 char * c2 = strchr(c1+1,'`');
83 literals[t].string = copy_string(c1+1,c2-c1-1);
84 literals[t].token = tokenize_string(literals[t].string);
100 literals[t].string = 0;
101 literals[t].token = 0;
102 qsort(literals,t,sizeof(literal),cmp_literal);
106 while (literals[i].string != 0)
108 if (strcmp(literals[p-1].string,literals[i].string) != 0)
110 literals[p] = literals[i];
115 literals[p].string = 0;
116 literals[p].token = 0;
119 token_output_f = fopen(argv[2],"w");
120 if (token_output_f != 0)
123 while (literals[i].string != 0)
125 fprintf(token_output_f," { \"%s\", %s },\n",literals[i].string,literals[i].token);
128 fclose(token_output_f);
134 grammar_output_f = fopen(argv[1],"w");
135 if (grammar_output_f != 0)
138 while (literals[i].string != 0)
140 fprintf(grammar_output_f,"%%token %s\n",literals[i].token);
143 rewind(grammar_source_f);
146 if (fgets(l,2048,grammar_source_f) != 0)
151 char * c1 = strchr(c,'`');
154 char * c2 = strchr(c1+1,'`');
158 literal * replacement = 0;
159 key.string = copy_string(c1+1,c2-c1-1);
161 replacement = (literal*)bsearch(
162 &key,literals,t,sizeof(literal),cmp_literal);
164 fprintf(grammar_output_f,"%s%s",c,replacement->token);
169 fprintf(grammar_output_f,"%s",c);
175 fprintf(grammar_output_f,"%s",c);
185 fclose(grammar_output_f);
199 static char * usage[] = {
200 "yyacc <grammar output.y> <token table output.h> <grammar source.yy>",
206 for (u = usage; *u != 0; ++u)
208 fputs(*u,stderr); putc('\n',stderr);
212 char * copy_string(char * s, int l)
214 char * result = (char*)malloc(l+1);
220 char * tokenize_string(char * s)
227 if (strcmp(s,":") == 0) literal = "_colon";
228 else if (strcmp(s,"!") == 0) literal = "_bang";
229 else if (strcmp(s,"!=") == 0) literal = "_bang_equals";
230 else if (strcmp(s,"&&") == 0) literal = "_amperamper";
231 else if (strcmp(s,"&") == 0) literal = "_amper";
232 else if (strcmp(s,"+") == 0) literal = "_plus";
233 else if (strcmp(s,"+=") == 0) literal = "_plus_equals";
234 else if (strcmp(s,"||") == 0) literal = "_barbar";
235 else if (strcmp(s,"|") == 0) literal = "_bar";
236 else if (strcmp(s,";") == 0) literal = "_semic";
237 else if (strcmp(s,"-") == 0) literal = "_minus";
238 else if (strcmp(s,"<") == 0) literal = "_langle";
239 else if (strcmp(s,"<=") == 0) literal = "_langle_equals";
240 else if (strcmp(s,">") == 0) literal = "_rangle";
241 else if (strcmp(s,">=") == 0) literal = "_rangle_equals";
242 else if (strcmp(s,".") == 0) literal = "_period";
243 else if (strcmp(s,"?") == 0) literal = "_question";
244 else if (strcmp(s,"?=") == 0) literal = "_question_equals";
245 else if (strcmp(s,"=") == 0) literal = "_equals";
246 else if (strcmp(s,",") == 0) literal = "_comma";
247 else if (strcmp(s,"[") == 0) literal = "_lbracket";
248 else if (strcmp(s,"]") == 0) literal = "_rbracket";
249 else if (strcmp(s,"{") == 0) literal = "_lbrace";
250 else if (strcmp(s,"}") == 0) literal = "_rbrace";
251 else if (strcmp(s,"(") == 0) literal = "_lparen";
252 else if (strcmp(s,")") == 0) literal = "_rparen";
253 l = strlen(literal)+2;
254 result = (char*)malloc(l+1);
255 for (c = 0; literal[c] != 0; ++c)
257 result[c] = toupper(literal[c]);
265 int cmp_literal(const void * a, const void * b)
267 return strcmp(((const literal *)a)->string,((const literal *)b)->string);