Skip to content

Instantly share code, notes, and snippets.

@pgoodman
Last active October 6, 2020 03:26
Show Gist options
  • Save pgoodman/1492b0308821b6fccd1b27bb0b90c8f3 to your computer and use it in GitHub Desktop.
Save pgoodman/1492b0308821b6fccd1b27bb0b90c8f3 to your computer and use it in GitHub Desktop.
Pretty print tables.
+- 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 | | | | | | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
# 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