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