#! `which awk` -f
# "common-output-to-C.awk"
# by Fang
#	$Id: common-output-to-C.awk,v 1.4 2006/11/04 03:21:43 fang Exp $
# TODO: take advantage of string tables already present in bison parser.
#	will save a ton of string memory.  

# takes the y.output file from yacc -v and converts it into C strings
# for use in error reporting

# CO-DEPENDENT ON:
# parser/yacc-output-to-C.awk OR parser/bison-output-to-C.awk

# chicken-before-the-egg

BEGIN {
	state_count = 0;
	print "/***";
	# FILENAME isn't available yet
	print "\t\"y.output.h\"";
	print "\tautomatically generated by: awk -f " main_program_name() " <y.output>";
	print "\tInclude this file in the declaration section of a yacc file.";
	print " **/";
	print "";
	print "#ifndef\t__Y_OUTPUT_H__";
	print "#define\t__Y_OUTPUT_H__";
	print "";
	print "typedef struct _yy_output_state_string_ {";
	print "\tconst int n;";
	print "\tconst char* const* rule;";

# NOTE: a constructor was added because gcc-3.2 requires a constructor
#	for structs with non-static const members.
#	gcc-3.3 and up don't require it.  
	print "\t_yy_output_state_string_(const int k, const char* const* r) :";
	print "\t\tn(k), rule(r) { }";

	print "} yy_output_state_string;\t\t/* end struct */"
	print "";
#	print "typedef const char* const*\t\tconst_string_array;";


# NOTE:
#	can't use const char* const rule[] because compilers complain
#	about "excess elements in aggregate initializers" in structs.
#	The solution presented here is a workaround.  

#	print "typedef struct {";
#	print "\tconst yy_output_state_string* sstrs;";
#	print "\tconst int n;";
#	print "} yy_output_state_string_set;"
#	print "";
#	print "const yy_output_state_string_set yysss = {";
#	print "  {";

}

function string_to_Cstring(str) {
	gsub("\t","\\t",str);
	gsub("\n","\\n",str);
	gsub("'","\\'",str);
	gsub("\"","\\\"",str);
#	gsub("\\","\\\\",str);		# buggy version of awk gets this wrong!
	# so we drop it for now, until we actually expect '\' in grammar
	return "\"" str "\"";
}

END {
	print "const int yynss = " state_count ";\t\t/* number of states */";
	print "const yy_output_state_string yysss[] = {";
	for (i=0; i<state_count; i++) {
#		print "  { " rule_count[i] ", yy_rule_string_set_" i " },"
#		gcc-3.2 doesn't like struct-style initialization
#		and requires constructor-style initialization.  
		print "\tyy_output_state_string(" rule_count[i] \
			", yy_rule_string_set_" i "),";
		# trailing comma is ok
	}
	print "};\t\t/* end yysss */";
	print "";
	print "#endif // __Y_OUTPUT_H__";
	print "";
}

