1*357f1050SThomas Veerman# Clarify the flex debug trace by substituting first line of each rule.
2*357f1050SThomas Veerman# Francois Pinard <pinard@iro.umontreal.ca>, July 1990.
3*357f1050SThomas Veerman#
4*357f1050SThomas Veerman# Rewritten to process correctly \n's in scanner input.
5*357f1050SThomas Veerman# BEGIN section modified to correct a collection of rules.
6*357f1050SThomas Veerman# Michal Jaegermann <michal@phys.ualberta.ca>, December 1993
7*357f1050SThomas Veerman#
8*357f1050SThomas Veerman# Sample usage:
9*357f1050SThomas Veerman#	flex -d PROGRAM.l
10*357f1050SThomas Veerman#	gcc -o PROGRAM PROGRAM.c -lfl
11*357f1050SThomas Veerman#	PROGRAM 2>&1 | gawk -f debflex.awk PROGRAM.l
12*357f1050SThomas Veerman#
13*357f1050SThomas Veerman# (VP's note: this script presently does not work with either "old" or
14*357f1050SThomas Veerman#  "new" awk; fixes so it does will be welcome)
15*357f1050SThomas Veerman
16*357f1050SThomas VeermanBEGIN {
17*357f1050SThomas Veerman    # Insure proper usage.
18*357f1050SThomas Veerman
19*357f1050SThomas Veerman    if (ARGC != 2) {
20*357f1050SThomas Veerman	print "usage: gawk -f debflex.awk FLEX_SOURCE <DEBUG_OUTPUT";
21*357f1050SThomas Veerman	exit (1);
22*357f1050SThomas Veerman    }
23*357f1050SThomas Veerman
24*357f1050SThomas Veerman    # Remove and save the name of flex source.
25*357f1050SThomas Veerman
26*357f1050SThomas Veerman    source = ARGV[1];
27*357f1050SThomas Veerman    ARGC--;
28*357f1050SThomas Veerman
29*357f1050SThomas Veerman    # Swallow the flex source file.
30*357f1050SThomas Veerman
31*357f1050SThomas Veerman    line = 0;
32*357f1050SThomas Veerman    section = 1;
33*357f1050SThomas Veerman    while (getline <source) {
34*357f1050SThomas Veerman
35*357f1050SThomas Veerman	# Count the lines.
36*357f1050SThomas Veerman
37*357f1050SThomas Veerman	line++;
38*357f1050SThomas Veerman
39*357f1050SThomas Veerman	# Count the sections.  When encountering section 3,
40*357f1050SThomas Veerman	# break out of the awk BEGIN block.
41*357f1050SThomas Veerman
42*357f1050SThomas Veerman	if (match ($0, /^%%/)) {
43*357f1050SThomas Veerman	    section++;
44*357f1050SThomas Veerman	    if (section == 3) {
45*357f1050SThomas Veerman		break;
46*357f1050SThomas Veerman	    }
47*357f1050SThomas Veerman	}
48*357f1050SThomas Veerman	else {
49*357f1050SThomas Veerman	    # Only the lines in section 2 which do not begin in a
50*357f1050SThomas Veerman	    # tab or space might be referred to by the flex debug
51*357f1050SThomas Veerman	    # trace.  Save only those lines.
52*357f1050SThomas Veerman
53*357f1050SThomas Veerman	    if (section == 2 && match ($0, /^[^ \t]/)) {
54*357f1050SThomas Veerman		rules[line] = $0;
55*357f1050SThomas Veerman	    }
56*357f1050SThomas Veerman	}
57*357f1050SThomas Veerman    }
58*357f1050SThomas Veerman    dashes = "-----------------------------------------------------------";
59*357f1050SThomas Veerman    collect = "";
60*357f1050SThomas Veerman    line = 0;
61*357f1050SThomas Veerman}
62*357f1050SThomas Veerman
63*357f1050SThomas Veerman# collect complete rule output from a scanner
64*357f1050SThomas Veerman$0 !~ /^--/ {
65*357f1050SThomas Veerman    collect = collect "\n" $0;
66*357f1050SThomas Veerman    next;
67*357f1050SThomas Veerman}
68*357f1050SThomas Veerman# otherwise we have a new rule - process what we got so far
69*357f1050SThomas Veerman{
70*357f1050SThomas Veerman    process();
71*357f1050SThomas Veerman}
72*357f1050SThomas Veerman# and the same thing if we hit EOF
73*357f1050SThomas VeermanEND {
74*357f1050SThomas Veerman    process();
75*357f1050SThomas Veerman}
76*357f1050SThomas Veerman
77*357f1050SThomas Veermanfunction process() {
78*357f1050SThomas Veerman
79*357f1050SThomas Veerman    # splitting this way we loose some double dashes and
80*357f1050SThomas Veerman    # left parentheses from echoed input - a small price to pay
81*357f1050SThomas Veerman    n = split(collect, field, "\n--|[(]");
82*357f1050SThomas Veerman
83*357f1050SThomas Veerman    # this loop kicks in only when we already collected something
84*357f1050SThomas Veerman    for (i = 1; i <= n; i++) {
85*357f1050SThomas Veerman	if (0 != line) {
86*357f1050SThomas Veerman	    # we do not care for traces of newlines.
87*357f1050SThomas Veerman	    if (0 == match(field[i], /\"\n+\"[)]/)) {
88*357f1050SThomas Veerman		if (rules[line]) {
89*357f1050SThomas Veerman		    text = field[i];
90*357f1050SThomas Veerman		    while ( ++i <= n) {
91*357f1050SThomas Veerman			text = text field[i];
92*357f1050SThomas Veerman		    }
93*357f1050SThomas Veerman		    printf("%s:%d: %-8s -- %s\n",
94*357f1050SThomas Veerman			   source, line, text, rules[line]);
95*357f1050SThomas Veerman		}
96*357f1050SThomas Veerman		else {
97*357f1050SThomas Veerman		    print;
98*357f1050SThomas Veerman		    printf "%s:%d: *** No such rule.\n", source, line;
99*357f1050SThomas Veerman		}
100*357f1050SThomas Veerman	    }
101*357f1050SThomas Veerman	    line = 0;
102*357f1050SThomas Veerman	    break;
103*357f1050SThomas Veerman	}
104*357f1050SThomas Veerman	if ("" != field[i]) {
105*357f1050SThomas Veerman	    if ("end of buffer or a NUL)" == field[i]) {
106*357f1050SThomas Veerman		print dashes;  # Simplify trace of buffer reloads
107*357f1050SThomas Veerman		continue;
108*357f1050SThomas Veerman	    }
109*357f1050SThomas Veerman	    if (match(field[i], /accepting rule at line /)) {
110*357f1050SThomas Veerman		# force interpretation of line as a number
111*357f1050SThomas Veerman		line = 0 + substr(field[i], RLENGTH);
112*357f1050SThomas Veerman		continue;
113*357f1050SThomas Veerman	    }
114*357f1050SThomas Veerman	    # echo everything else
115*357f1050SThomas Veerman	    printf("--%s\n", field[i]);
116*357f1050SThomas Veerman	}
117*357f1050SThomas Veerman    }
118*357f1050SThomas Veerman    collect = "\n" $0;  # ... and start next trace
119*357f1050SThomas Veerman}
120