diff options
author | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
---|---|---|
committer | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
commit | d94373453c69c6cfec952a0f7b427cacc78654d8 (patch) | |
tree | 43febdf719c103d19bd5d22d0be734e1574bc1e9 /jam-files/engine/yyacc.c | |
parent | cc9650b8b664d1f6836a0fa86a012401b51aafa0 (diff) | |
parent | a65a80c5d5b6fc4cbd32280f07cae9be71551b70 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'jam-files/engine/yyacc.c')
-rw-r--r-- | jam-files/engine/yyacc.c | 268 |
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); +} |