# Clarify the flex debug trace by substituting first line of each rule. # Francois Pinard <pinard@iro.umontreal.ca>, July 1990. # # Rewritten to process correctly \n's in scanner input. # BEGIN section modified to correct a collection of rules. # Michal Jaegermann <michal@phys.ualberta.ca>, December 1993 # # Sample usage: # flex -d PROGRAM.l # gcc -o PROGRAM PROGRAM.c -lfl # PROGRAM 2>&1 | gawk -f debflex.awk PROGRAM.l # # (VP's note: this script presently does not work with either "old" or # "new" awk; fixes so it does will be welcome) BEGIN { # Insure proper usage. if (ARGC != 2) { print "usage: gawk -f debflex.awk FLEX_SOURCE <DEBUG_OUTPUT"; exit (1); } # Remove and save the name of flex source. source = ARGV[1]; ARGC--; # Swallow the flex source file. line = 0; section = 1; while (getline <source) { # Count the lines. line++; # Count the sections. When encountering section 3, # break out of the awk BEGIN block. if (match ($0, /^%%/)) { section++; if (section == 3) { break; } } else { # Only the lines in section 2 which do not begin in a # tab or space might be referred to by the flex debug # trace. Save only those lines. if (section == 2 && match ($0, /^[^ \t]/)) { rules[line] = $0; } } } dashes = "-----------------------------------------------------------"; collect = ""; line = 0; } # collect complete rule output from a scanner $0 !~ /^--/ { collect = collect "\n" $0; next; } # otherwise we have a new rule - process what we got so far { process(); } # and the same thing if we hit EOF END { process(); } function process() { # splitting this way we loose some double dashes and # left parentheses from echoed input - a small price to pay n = split(collect, field, "\n--|[(]"); # this loop kicks in only when we already collected something for (i = 1; i <= n; i++) { if (0 != line) { # we do not care for traces of newlines. if (0 == match(field[i], /\"\n+\"[)]/)) { if (rules[line]) { text = field[i]; while ( ++i <= n) { text = text field[i]; } printf("%s:%d: %-8s -- %s\n", source, line, text, rules[line]); } else { print; printf "%s:%d: *** No such rule.\n", source, line; } } line = 0; break; } if ("" != field[i]) { if ("end of buffer or a NUL)" == field[i]) { print dashes; # Simplify trace of buffer reloads continue; } if (match(field[i], /accepting rule at line /)) { # force interpretation of line as a number line = 0 + substr(field[i], RLENGTH); continue; } # echo everything else printf("--%s\n", field[i]); } } collect = "\n" $0; # ... and start next trace }