summaryrefslogtreecommitdiff
path: root/jam-files/engine/yyacc.c
diff options
context:
space:
mode:
Diffstat (limited to 'jam-files/engine/yyacc.c')
-rw-r--r--jam-files/engine/yyacc.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/jam-files/engine/yyacc.c b/jam-files/engine/yyacc.c
new file mode 100644
index 00000000..b5efc96b
--- /dev/null
+++ b/jam-files/engine/yyacc.c
@@ -0,0 +1,268 @@
+/* Copyright 2002 Rene Rivera.
+** Distributed under the Boost Software License, Version 1.0.
+** (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+# yyacc - yacc wrapper
+#
+# Allows tokens to be written as `literal` and then automatically
+# substituted with #defined tokens.
+#
+# Usage:
+# yyacc file.y filetab.h file.yy
+#
+# inputs:
+# file.yy yacc grammar with ` literals
+#
+# outputs:
+# file.y yacc grammar
+# filetab.h array of string <-> token mappings
+#
+# 3-13-93
+# Documented and p moved in sed command (for some reason,
+# s/x/y/p doesn't work).
+# 10-12-93
+# Take basename as second argument.
+# 12-31-96
+# reversed order of args to be compatible with GenFile rule
+# 11-20-2002
+# Reimplemented as a C program for portability. (Rene Rivera)
+*/
+
+void print_usage();
+char * copy_string(char * s, int l);
+char * tokenize_string(char * s);
+int cmp_literal(const void * a, const void * b);
+
+typedef struct
+{
+ char * string;
+ char * token;
+} literal;
+
+int main(int argc, char ** argv)
+{
+ int result = 0;
+ if (argc != 4)
+ {
+ print_usage();
+ result = 1;
+ }
+ else
+ {
+ FILE * token_output_f = 0;
+ FILE * grammar_output_f = 0;
+ FILE * grammar_source_f = 0;
+
+ grammar_source_f = fopen(argv[3],"r");
+ if (grammar_source_f == 0) { result = 1; }
+ if (result == 0)
+ {
+ literal literals[1024];
+ int t = 0;
+ char l[2048];
+ while (1)
+ {
+ if (fgets(l,2048,grammar_source_f) != 0)
+ {
+ char * c = l;
+ while (1)
+ {
+ char * c1 = strchr(c,'`');
+ if (c1 != 0)
+ {
+ char * c2 = strchr(c1+1,'`');
+ if (c2 != 0)
+ {
+ literals[t].string = copy_string(c1+1,c2-c1-1);
+ literals[t].token = tokenize_string(literals[t].string);
+ t += 1;
+ c = c2+1;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ literals[t].string = 0;
+ literals[t].token = 0;
+ qsort(literals,t,sizeof(literal),cmp_literal);
+ {
+ int p = 1;
+ int i = 1;
+ while (literals[i].string != 0)
+ {
+ if (strcmp(literals[p-1].string,literals[i].string) != 0)
+ {
+ literals[p] = literals[i];
+ p += 1;
+ }
+ i += 1;
+ }
+ literals[p].string = 0;
+ literals[p].token = 0;
+ t = p;
+ }
+ token_output_f = fopen(argv[2],"w");
+ if (token_output_f != 0)
+ {
+ int i = 0;
+ while (literals[i].string != 0)
+ {
+ fprintf(token_output_f," { \"%s\", %s },\n",literals[i].string,literals[i].token);
+ i += 1;
+ }
+ fclose(token_output_f);
+ }
+ else
+ result = 1;
+ if (result == 0)
+ {
+ grammar_output_f = fopen(argv[1],"w");
+ if (grammar_output_f != 0)
+ {
+ int i = 0;
+ while (literals[i].string != 0)
+ {
+ fprintf(grammar_output_f,"%%token %s\n",literals[i].token);
+ i += 1;
+ }
+ rewind(grammar_source_f);
+ while (1)
+ {
+ if (fgets(l,2048,grammar_source_f) != 0)
+ {
+ char * c = l;
+ while (1)
+ {
+ char * c1 = strchr(c,'`');
+ if (c1 != 0)
+ {
+ char * c2 = strchr(c1+1,'`');
+ if (c2 != 0)
+ {
+ literal key;
+ literal * replacement = 0;
+ key.string = copy_string(c1+1,c2-c1-1);
+ key.token = 0;
+ replacement = (literal*)bsearch(
+ &key,literals,t,sizeof(literal),cmp_literal);
+ *c1 = 0;
+ fprintf(grammar_output_f,"%s%s",c,replacement->token);
+ c = c2+1;
+ }
+ else
+ {
+ fprintf(grammar_output_f,"%s",c);
+ break;
+ }
+ }
+ else
+ {
+ fprintf(grammar_output_f,"%s",c);
+ break;
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ fclose(grammar_output_f);
+ }
+ else
+ result = 1;
+ }
+ }
+ if (result != 0)
+ {
+ perror("yyacc");
+ }
+ }
+ return result;
+}
+
+static char * usage[] = {
+ "yyacc <grammar output.y> <token table output.h> <grammar source.yy>",
+ 0 };
+
+void print_usage()
+{
+ char ** u;
+ for (u = usage; *u != 0; ++u)
+ {
+ fputs(*u,stderr); putc('\n',stderr);
+ }
+}
+
+char * copy_string(char * s, int l)
+{
+ char * result = (char*)malloc(l+1);
+ strncpy(result,s,l);
+ result[l] = 0;
+ return result;
+}
+
+char * tokenize_string(char * s)
+{
+ char * result;
+ char * literal = s;
+ int l;
+ int c;
+
+ if (strcmp(s,":") == 0) literal = "_colon";
+ else if (strcmp(s,"!") == 0) literal = "_bang";
+ else if (strcmp(s,"!=") == 0) literal = "_bang_equals";
+ else if (strcmp(s,"&&") == 0) literal = "_amperamper";
+ else if (strcmp(s,"&") == 0) literal = "_amper";
+ else if (strcmp(s,"+") == 0) literal = "_plus";
+ else if (strcmp(s,"+=") == 0) literal = "_plus_equals";
+ else if (strcmp(s,"||") == 0) literal = "_barbar";
+ else if (strcmp(s,"|") == 0) literal = "_bar";
+ else if (strcmp(s,";") == 0) literal = "_semic";
+ else if (strcmp(s,"-") == 0) literal = "_minus";
+ else if (strcmp(s,"<") == 0) literal = "_langle";
+ else if (strcmp(s,"<=") == 0) literal = "_langle_equals";
+ else if (strcmp(s,">") == 0) literal = "_rangle";
+ else if (strcmp(s,">=") == 0) literal = "_rangle_equals";
+ else if (strcmp(s,".") == 0) literal = "_period";
+ else if (strcmp(s,"?") == 0) literal = "_question";
+ else if (strcmp(s,"?=") == 0) literal = "_question_equals";
+ else if (strcmp(s,"=") == 0) literal = "_equals";
+ else if (strcmp(s,",") == 0) literal = "_comma";
+ else if (strcmp(s,"[") == 0) literal = "_lbracket";
+ else if (strcmp(s,"]") == 0) literal = "_rbracket";
+ else if (strcmp(s,"{") == 0) literal = "_lbrace";
+ else if (strcmp(s,"}") == 0) literal = "_rbrace";
+ else if (strcmp(s,"(") == 0) literal = "_lparen";
+ else if (strcmp(s,")") == 0) literal = "_rparen";
+ l = strlen(literal)+2;
+ result = (char*)malloc(l+1);
+ for (c = 0; literal[c] != 0; ++c)
+ {
+ result[c] = toupper(literal[c]);
+ }
+ result[l-2] = '_';
+ result[l-1] = 't';
+ result[l] = 0;
+ return result;
+}
+
+int cmp_literal(const void * a, const void * b)
+{
+ return strcmp(((const literal *)a)->string,((const literal *)b)->string);
+}