Last active
October 6, 2020 03:26
-
-
Save pgoodman/1492b0308821b6fccd1b27bb0b90c8f3 to your computer and use it in GitHub Desktop.
Pretty print tables.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| +- Grammar ---------------+ +-----------------------------------------------------+ | |
| | | | Production | Nullable | FIRST | FOLLOW | | |
| | S -> S S | |-------------------------+----------+-------+--------| | |
| | S -> if E then S else S | | S' -> S $ | False | exit | | | |
| | S -> if E then S | | | | if | | | |
| | S -> exit when E | |-------------------------+----------+-------+--------| | |
| +-------------------------+ | S -> S S | False | exit | $ | | |
| | S -> if E then S else S | | if | exit | | |
| | S -> if E then S | | | if | | |
| | S -> exit when E | | | else | | |
| +-----------------------------------------------------+ | |
| +- Item Closure --------------------------------------------+ +- States -------------------------------+ | |
| | | | | | |
| | Item | Closure(Item) | | State ID | Item Set | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> if E then S @ else S] | [S -> if E then S @ else S] | | 12 | [S -> if @ E then S else S] | | |
| |-----------------------------+-----------------------------| | | [S -> if @ E then S] | | |
| | [S' -> S $ @] | [S' -> S $ @] | |----------+-----------------------------| | |
| |-----------------------------+-----------------------------| | 0 | [S -> if E @ then S else S] | | |
| | [S -> if E @ then S else S] | [S -> if E @ then S else S] | | | [S -> if E @ then S] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> @ if E then S] | [S -> @ if E then S] | | 10 | [S -> exit when @ E] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> exit when @ E] | [S -> exit when @ E] | | 2 | [S -> exit @ when E] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> S @ S] | [S -> @ exit when E] | | 3 | [S -> @ S S] | | |
| | | [S -> @ if E then S] | | | [S -> if E then S else @ S] | | |
| | | [S -> @ if E then S else S] | | | [S -> @ if E then S else S] | | |
| | | [S -> @ S S] | | | [S -> @ if E then S] | | |
| | | [S -> S @ S] | | | [S -> @ exit when E] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> if E then @ S else S] | [S -> if E then @ S else S] | | 5 | [S' -> @ S $] | | |
| | | [S -> @ exit when E] | | | [S -> @ exit when E] | | |
| | | [S -> @ if E then S] | | | [S -> @ if E then S] | | |
| | | [S -> @ if E then S else S] | | | [S -> @ if E then S else S] | | |
| | | [S -> @ S S] | | | [S -> @ S S] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> @ exit when E] | [S -> @ exit when E] | | 6 | [S -> @ S S] | | |
| |-----------------------------+-----------------------------| | | [S -> @ if E then S else S] | | |
| | [S -> if E @ then S] | [S -> if E @ then S] | | | [S -> @ if E then S] | | |
| |-----------------------------+-----------------------------| | | [S -> @ exit when E] | | |
| | [S -> if @ E then S else S] | [S -> if @ E then S else S] | | | [S' -> S @ $] | | |
| |-----------------------------+-----------------------------| | | [S -> S @ S] | | |
| | [S -> S S @] | [S -> S S @] | |----------+-----------------------------| | |
| |-----------------------------+-----------------------------| | 7 | [S' -> S $ @] | | |
| | [S' -> S @ $] | [S' -> S @ $] | |----------+-----------------------------| | |
| |-----------------------------+-----------------------------| | 8 | [S -> @ if E then S] | | |
| | [S -> if E then S @] | [S -> if E then S @] | | | [S -> @ if E then S else S] | | |
| |-----------------------------+-----------------------------| | | [S -> @ S S] | | |
| | [S -> @ S S] | [S -> @ exit when E] | | | [S -> S S @] | | |
| | | [S -> @ if E then S] | | | [S -> @ exit when E] | | |
| | | [S -> @ if E then S else S] | | | [S -> S @ S] | | |
| | | [S -> @ S S] | |----------+-----------------------------| | |
| |-----------------------------+-----------------------------| | 11 | [S -> exit when E @] | | |
| | [S -> if E then @ S] | [S -> if E then @ S] | |----------+-----------------------------| | |
| | | [S -> @ exit when E] | | 1 | [S -> @ if E then S else S] | | |
| | | [S -> @ if E then S] | | | [S -> @ if E then S] | | |
| | | [S -> @ if E then S else S] | | | [S -> @ exit when E] | | |
| | | [S -> @ S S] | | | [S -> if E then S @ else S] | | |
| |-----------------------------+-----------------------------| | | [S -> @ S S] | | |
| | [S -> if @ E then S] | [S -> if @ E then S] | | | [S -> if E then S @] | | |
| |-----------------------------+-----------------------------| | | [S -> S @ S] | | |
| | [S -> exit @ when E] | [S -> exit @ when E] | |----------+-----------------------------| | |
| |-----------------------------+-----------------------------| | 4 | [S -> @ if E then S] | | |
| | [S' -> @ S $] | [S' -> @ S $] | | | [S -> @ if E then S else S] | | |
| | | [S -> @ exit when E] | | | [S -> @ S S] | | |
| | | [S -> @ if E then S] | | | [S -> @ exit when E] | | |
| | | [S -> @ if E then S else S] | | | [S -> if E then S else S @] | | |
| | | [S -> @ S S] | | | [S -> S @ S] | | |
| |-----------------------------+-----------------------------| |----------+-----------------------------| | |
| | [S -> if E then S else S @] | [S -> if E then S else S @] | | 9 | [S -> if E then @ S else S] | | |
| |-----------------------------+-----------------------------| | | [S -> @ if E then S else S] | | |
| | [S -> exit when E @] | [S -> exit when E @] | | | [S -> @ S S] | | |
| |-----------------------------+-----------------------------| | | [S -> if E then @ S] | | |
| | [S -> if E then S else @ S] | [S -> @ exit when E] | | | [S -> @ if E then S] | | |
| | | [S -> if E then S else @ S] | | | [S -> @ exit when E] | | |
| | | [S -> @ if E then S] | +----------------------------------------+ | |
| | | [S -> @ if E then S else S] | | |
| | | [S -> @ S S] | | |
| |-----------------------------+-----------------------------| | |
| | [S -> @ if E then S else S] | [S -> @ if E then S else S] | | |
| +-----------------------------------------------------------+ | |
| +- Transition Table -------------------------------------------------------------------------+ | |
| | | | |
| | Source ID | | Transitions | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 0 | [S -> if E @ then S else S] | Symbol | Dest ID | | | |
| | | [S -> if E @ then S] | --------+---------+----------------------------- | | |
| | | | then | 9 | [S -> if E then @ S else S] | | |
| | | | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> if E then @ S] | | |
| | | | | | [S -> @ if E then S] | | |
| | | | | | [S -> @ exit when E] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 1 | [S -> @ if E then S else S] | Symbol | Dest ID | | | |
| | | [S -> @ if E then S] | --------+---------+----------------------------- | | |
| | | [S -> @ exit when E] | else | 3 | [S -> @ S S] | | |
| | | [S -> if E then S @ else S] | | | [S -> if E then S else @ S] | | |
| | | [S -> @ S S] | | | [S -> @ if E then S else S] | | |
| | | [S -> if E then S @] | | | [S -> @ if E then S] | | |
| | | [S -> S @ S] | | | [S -> @ exit when E] | | |
| | | | --------+---------+----------------------------- | | |
| | | | exit | 2 | [S -> exit @ when E] | | |
| | | | --------+---------+----------------------------- | | |
| | | | S | 8 | [S -> @ if E then S] | | |
| | | | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> S S @] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S] | | |
| | | | | | [S -> if @ E then S else S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 2 | [S -> exit @ when E] | Symbol | Dest ID | | | |
| | | | --------+---------+---------------------- | | |
| | | | when | 10 | [S -> exit when @ E] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 3 | [S -> @ S S] | Symbol | Dest ID | | | |
| | | [S -> if E then S else @ S] | --------+---------+----------------------------- | | |
| | | [S -> @ if E then S else S] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> @ if E then S] | --------+---------+----------------------------- | | |
| | | [S -> @ exit when E] | S | 4 | [S -> @ if E then S] | | |
| | | | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> if E then S else S @] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S] | | |
| | | | | | [S -> if @ E then S else S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 4 | [S -> @ if E then S] | Symbol | Dest ID | | | |
| | | [S -> @ if E then S else S] | --------+---------+----------------------------- | | |
| | | [S -> @ S S] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> @ exit when E] | --------+---------+----------------------------- | | |
| | | [S -> if E then S else S @] | S | 8 | [S -> @ if E then S] | | |
| | | [S -> S @ S] | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> S S @] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S else S] | | |
| | | | | | [S -> if @ E then S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 5 | [S' -> @ S $] | Symbol | Dest ID | | | |
| | | [S -> @ exit when E] | --------+---------+----------------------------- | | |
| | | [S -> @ if E then S] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> @ if E then S else S] | --------+---------+----------------------------- | | |
| | | [S -> @ S S] | S | 6 | [S -> @ S S] | | |
| | | | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ if E then S] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S' -> S @ $] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S else S] | | |
| | | | | | [S -> if @ E then S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 6 | [S -> @ S S] | Symbol | Dest ID | | | |
| | | [S -> @ if E then S else S] | --------+---------+----------------------------- | | |
| | | [S -> @ if E then S] | $ | 7 | [S' -> S $ @] | | |
| | | [S -> @ exit when E] | --------+---------+----------------------------- | | |
| | | [S' -> S @ $] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> S @ S] | --------+---------+----------------------------- | | |
| | | | S | 8 | [S -> @ if E then S] | | |
| | | | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> S S @] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S] | | |
| | | | | | [S -> if @ E then S else S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 7 | [S' -> S $ @] | | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 8 | [S -> @ if E then S] | Symbol | Dest ID | | | |
| | | [S -> @ if E then S else S] | --------+---------+----------------------------- | | |
| | | [S -> @ S S] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> S S @] | --------+---------+----------------------------- | | |
| | | [S -> @ exit when E] | S | 8 | [S -> @ if E then S] | | |
| | | [S -> S @ S] | | | [S -> @ if E then S else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> S S @] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S else S] | | |
| | | | | | [S -> if @ E then S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 9 | [S -> if E then @ S else S] | Symbol | Dest ID | | | |
| | | [S -> @ if E then S else S] | --------+---------+----------------------------- | | |
| | | [S -> @ S S] | exit | 2 | [S -> exit @ when E] | | |
| | | [S -> if E then @ S] | --------+---------+----------------------------- | | |
| | | [S -> @ if E then S] | S | 1 | [S -> @ if E then S else S] | | |
| | | [S -> @ exit when E] | | | [S -> @ if E then S] | | |
| | | | | | [S -> @ exit when E] | | |
| | | | | | [S -> if E then S @ else S] | | |
| | | | | | [S -> @ S S] | | |
| | | | | | [S -> if E then S @] | | |
| | | | | | [S -> S @ S] | | |
| | | | --------+---------+----------------------------- | | |
| | | | if | 12 | [S -> if @ E then S] | | |
| | | | | | [S -> if @ E then S else S] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 10 | [S -> exit when @ E] | Symbol | Dest ID | | | |
| | | | --------+---------+---------------------- | | |
| | | | E | 11 | [S -> exit when E @] | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 11 | [S -> exit when E @] | | | |
| |-----------+-----------------------------+--------------------------------------------------| | |
| | 12 | [S -> if @ E then S else S] | Symbol | Dest ID | | | |
| | | [S -> if @ E then S] | --------+---------+----------------------------- | | |
| | | | E | 0 | [S -> if E @ then S else S] | | |
| | | | | | [S -> if E @ then S] | | |
| +--------------------------------------------------------------------------------------------+ | |
| +- SLR Parsing Table -------------------------------------------------------------------------------------------------------------------------------------------------------+ | |
| | | | |
| | \ Input | then | S | E | S' | $ | exit | else | when | if | | |
| | \ | | | | | | | | | | | |
| | ID \ | | | | | | | | | | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 0 | shift: 9 | | | | | | | | | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 1 | | goto: 8 | | | reduce: | reduce: | reduce: | | reduce: | | |
| | | | | | | S -> if E then S | S -> if E then S | S -> if E then S | | S -> if E then S | | |
| | | | | | | | shift: 2 | shift: 3 | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 2 | | | | | | | | shift: 10 | | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 3 | | goto: 4 | | | | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 4 | | goto: 8 | | | reduce: | reduce: | reduce: | | reduce: | | |
| | | | | | | S -> if E then S else S | S -> if E then S else S | S -> if E then S else S | | S -> if E then S else S | | |
| | | | | | | | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 5 | | goto: 6 | | | | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 6 | | goto: 8 | | | shift: 7 | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 7 | | | | | accept | | | | | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 8 | | goto: 8 | | | reduce: | reduce: | reduce: | | reduce: | | |
| | | | | | | S -> S S | S -> S S | S -> S S | | S -> S S | | |
| | | | | | | | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 9 | | goto: 1 | | | | shift: 2 | | | shift: 12 | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 10 | | | shift: 11 | | | | | | | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 11 | | | | | reduce: | reduce: | reduce: | | reduce: | | |
| | | | | | | S -> exit when E | S -> exit when E | S -> exit when E | | S -> exit when E | | |
| |---------+----------+---------+-----------+----+---------------------------+---------------------------+---------------------------+-----------+---------------------------| | |
| | 12 | | | shift: 0 | | | | | | | | |
| +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # convert a list into an ASCII table | |
| # (c) 2010 Peter Goodman, all rights reserved. | |
| DEFAULT_TABLE_STYLES = ("|","-","|","-","+"," ") | |
| DEFAULT_TABLE_JUSTIFY = str.ljust | |
| DEFAULT_TABLE_CELL_TO_STR = str | |
| def list_to_table(table, title="", | |
| cell_to_str=DEFAULT_TABLE_CELL_TO_STR, | |
| justify=DEFAULT_TABLE_JUSTIFY, | |
| styles=DEFAULT_TABLE_STYLES): | |
| """Convert a list into a string that is formatableed to look like a table.""" | |
| def make_row_list(row): | |
| if not isinstance(row, list): | |
| return [row] | |
| return row | |
| COL_SEP, ROW_SEP, VERT_BORDER, HOR_BORDER, INTERSECT, PADDING = styles | |
| table = map(make_row_list, table) | |
| col_range, row_range = xrange(len(zip(*table))), xrange(len(table)) | |
| col_max_widths = dict.fromkeys(col_range, 0) | |
| row_max_heights = dict.fromkeys(row_range, 1) | |
| cells = { } | |
| # get string representations for each cell | |
| for r in row_range: | |
| for c in col_range: | |
| cells[r, c] = cell_to_str(table[r][c]).splitlines() | |
| # get max row heights and col lengths | |
| for ((r, c), lines) in cells.items(): | |
| row_max_heights[r] = max(row_max_heights[r], len(lines)) | |
| for line in lines: | |
| col_max_widths[c] = max(col_max_widths[c], len(line)) | |
| # add in extra lines to the cells and justify the cells | |
| for ((r, c), lines) in cells.items(): | |
| empty = " " * col_max_widths[c] | |
| for i in xrange(len(lines)): | |
| lines[i] = justify(lines[i], col_max_widths[c]) | |
| for _ in xrange(len(lines), row_max_heights[r]): | |
| lines.append(empty) | |
| # make the horizontal line separator | |
| line_sep = "" | |
| if len(ROW_SEP) or len(INTERSECT): | |
| line_sep += VERT_BORDER + ROW_SEP | |
| for c in col_range: | |
| if c > 0: | |
| line_sep += (INTERSECT * len(COL_SEP)) + ROW_SEP | |
| line_sep += ROW_SEP + (col_max_widths[c] * ROW_SEP) | |
| line_sep += VERT_BORDER | |
| line_sep += "\n" | |
| ret = "" | |
| # construct the table | |
| for r in row_range: | |
| if r > 0: | |
| ret += "\n" + line_sep | |
| for l in xrange(row_max_heights[r]): | |
| if l > 0: | |
| ret += PADDING + VERT_BORDER + "\n" | |
| for c in col_range: | |
| if c > 0: | |
| ret += PADDING + COL_SEP + PADDING | |
| else: | |
| ret += VERT_BORDER + PADDING | |
| ret += cells[r, c][l] | |
| ret += " " + VERT_BORDER | |
| header, footer, sep_len = "", "", len(line_sep) - 1 | |
| # make the table header and footer | |
| if len(HOR_BORDER): | |
| footer = INTERSECT + (HOR_BORDER * (sep_len - 2 * len(INTERSECT))) + INTERSECT | |
| if len(title): | |
| header += INTERSECT + (HOR_BORDER * (2 - len(INTERSECT))) | |
| header += " " + title + " " | |
| header += HOR_BORDER * (sep_len - len(header) - len(INTERSECT)) | |
| header += INTERSECT + "\n" | |
| header += VERT_BORDER + ((sep_len - 2 * len(VERT_BORDER)) * " ") | |
| header += VERT_BORDER | |
| else: | |
| header = footer | |
| header += "\n" | |
| footer += "\n" | |
| return header + ret + "\n" + footer | |
| def cell_to_str_with_subtables( | |
| cell_to_str=DEFAULT_TABLE_CELL_TO_STR, | |
| justify=DEFAULT_TABLE_JUSTIFY, | |
| styles=DEFAULT_TABLE_STYLES): | |
| """Returns a function to convert a cell to a string. If a cell is a list then it | |
| treats the cell as a table an prints it as such.""" | |
| def to_str(cell): | |
| if isinstance(cell, list): | |
| return list_to_table( | |
| cell, | |
| cell_to_str=cell_to_str_with_subtables(cell_to_str), | |
| justify=justify, | |
| styles=(styles[0], styles[1], "", "", styles[4], styles[5]) | |
| ) | |
| return cell_to_str(cell) | |
| return to_str |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment