diff --git a/Project-02/main.py b/Project-02/main.py index 317dc70..0729f00 100644 --- a/Project-02/main.py +++ b/Project-02/main.py @@ -1,18 +1,52 @@ -# This is a sample Python script for testing your TRIPLA parser. - -# In PyCharm press Umschalt+F10 to execute it. +# (c) Stephan Diehl / Updated for AST display by ChatGPT import triplayacc as yacc import triplalex as lex +import syntax +from graphviz import Source +import matplotlib.pyplot as plt +import matplotlib.image as mpimg -def test_parser(name): - source = "\n".join(open(name).readlines()) - ast = yacc.parser.parse(source) # ,debug=True) - print("AST:") + +def display_ast_graph(dotfile="ast.dot"): + """Render DOT → PNG and display via matplotlib (always).""" + + # Read DOT + with open(dotfile) as f: + dot_data = f.read() + + # Render using Graphviz + src = Source(dot_data) + src.render("ast", format="png", cleanup=True) + + # Load rendered PNG + img = mpimg.imread("ast.png") + + # Show in matplotlib window + plt.imshow(img) + plt.axis('off') + plt.show() + + +def test_parser(filepath): + # Load program + with open(filepath) as f: + source = f.read() + + # Parse input + ast = yacc.parser.parse(source) + + # Print plain-text version of the AST (optional) + print("AST object:") print(ast) -# Press the green button in the gutter to run the script. -if __name__ == '__main__': - test_parser('whileprograms/complex.while') + # Export DOT file + syntax.export_dot(ast, "ast.dot") -# See PyCharm help at https://www.jetbrains.com/help/pycharm/ + # Display AST diagram + print("Rendering AST diagram with matplotlib...") + display_ast_graph("ast.dot") + + +if __name__ == '__main__': + test_parser('triplaprograms/or.tripla') diff --git a/Project-02/parser.out b/Project-02/parser.out index 96dc6a4..2bbd535 100644 --- a/Project-02/parser.out +++ b/Project-02/parser.out @@ -1,135 +1,1133 @@ Created by PLY version 3.11 (http://www.dabeaz.com/ply) -Unused terminals: - - AOP - ASSIGN - COMMA - ELSE - FALSE - ID - IF - IN - LET - LOP - LPAREN - RELOP - RPAREN - SEMICOLON - THEN - TRUE - Grammar -Rule 0 S' -> expression -Rule 1 expression -> CONST -Rule 2 expression -> WHILE expression DO LBRACE expression RBRACE +Rule 0 S' -> E +Rule 1 E -> LET D IN E +Rule 2 E -> ID +Rule 3 E -> ID LPAREN A RPAREN +Rule 4 E -> E AOP E +Rule 5 E -> LPAREN E RPAREN +Rule 6 E -> CONST +Rule 7 E -> ID ASSIGN E +Rule 8 E -> E SEMICOLON E +Rule 9 E -> IF LPAREN B RPAREN THEN E ELSE E +Rule 10 E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE +Rule 11 A -> E +Rule 12 A -> A COMMA E +Rule 13 D -> ID LPAREN V RPAREN LBRACE E RBRACE +Rule 14 D -> D D +Rule 15 V -> ID +Rule 16 V -> V COMMA ID +Rule 17 B -> E EQOP E +Rule 18 B -> E COMP E +Rule 19 B -> B EQOP B +Rule 20 B -> B LOP B +Rule 21 B -> TRUE +Rule 22 B -> FALSE +Rule 23 B -> LPAREN B RPAREN Terminals, with rules where they appear -AOP : -ASSIGN : -COMMA : -CONST : 1 -DO : 2 -ELSE : -FALSE : -ID : -IF : -IN : -LBRACE : 2 -LET : -LOP : -LPAREN : -RBRACE : 2 -RELOP : -RPAREN : -SEMICOLON : -THEN : -TRUE : -WHILE : 2 +AOP : 4 +ASSIGN : 7 +COMMA : 12 16 +COMP : 18 +CONST : 6 +DO : 10 +ELSE : 9 +EQOP : 17 19 +FALSE : 22 +ID : 2 3 7 13 15 16 +IF : 9 +IN : 1 +LBRACE : 10 13 +LET : 1 +LOP : 20 +LPAREN : 3 5 9 10 13 23 +RBRACE : 10 13 +RPAREN : 3 5 9 10 13 23 +SEMICOLON : 8 +THEN : 9 +TRUE : 21 +WHILE : 10 error : Nonterminals, with rules where they appear -expression : 2 2 0 +A : 3 12 +B : 9 10 19 19 20 20 23 +D : 1 14 14 +E : 1 4 4 5 7 8 8 9 9 10 11 12 13 17 17 18 18 0 +V : 13 16 Parsing method: LALR state 0 - (0) S' -> . expression - (1) expression -> . CONST - (2) expression -> . WHILE expression DO LBRACE expression RBRACE + (0) S' -> . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE - CONST shift and go to state 2 - WHILE shift and go to state 3 + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 - expression shift and go to state 1 + E shift and go to state 1 state 1 - (0) S' -> expression . + (0) S' -> E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 state 2 - (1) expression -> CONST . + (1) E -> LET . D IN E + (13) D -> . ID LPAREN V RPAREN LBRACE E RBRACE + (14) D -> . D D - $end reduce using rule 1 (expression -> CONST .) - DO reduce using rule 1 (expression -> CONST .) - RBRACE reduce using rule 1 (expression -> CONST .) + ID shift and go to state 11 + D shift and go to state 10 state 3 - (2) expression -> WHILE . expression DO LBRACE expression RBRACE - (1) expression -> . CONST - (2) expression -> . WHILE expression DO LBRACE expression RBRACE + (2) E -> ID . + (3) E -> ID . LPAREN A RPAREN + (7) E -> ID . ASSIGN E - CONST shift and go to state 2 - WHILE shift and go to state 3 + AOP reduce using rule 2 (E -> ID .) + SEMICOLON reduce using rule 2 (E -> ID .) + $end reduce using rule 2 (E -> ID .) + RPAREN reduce using rule 2 (E -> ID .) + COMMA reduce using rule 2 (E -> ID .) + EQOP reduce using rule 2 (E -> ID .) + COMP reduce using rule 2 (E -> ID .) + LOP reduce using rule 2 (E -> ID .) + ELSE reduce using rule 2 (E -> ID .) + RBRACE reduce using rule 2 (E -> ID .) + LPAREN shift and go to state 12 + ASSIGN shift and go to state 13 - expression shift and go to state 4 state 4 - (2) expression -> WHILE expression . DO LBRACE expression RBRACE + (5) E -> LPAREN . E RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE - DO shift and go to state 5 + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + E shift and go to state 14 state 5 - (2) expression -> WHILE expression DO . LBRACE expression RBRACE + (6) E -> CONST . - LBRACE shift and go to state 6 + AOP reduce using rule 6 (E -> CONST .) + SEMICOLON reduce using rule 6 (E -> CONST .) + $end reduce using rule 6 (E -> CONST .) + RPAREN reduce using rule 6 (E -> CONST .) + COMMA reduce using rule 6 (E -> CONST .) + EQOP reduce using rule 6 (E -> CONST .) + COMP reduce using rule 6 (E -> CONST .) + LOP reduce using rule 6 (E -> CONST .) + ELSE reduce using rule 6 (E -> CONST .) + RBRACE reduce using rule 6 (E -> CONST .) state 6 - (2) expression -> WHILE expression DO LBRACE . expression RBRACE - (1) expression -> . CONST - (2) expression -> . WHILE expression DO LBRACE expression RBRACE + (9) E -> IF . LPAREN B RPAREN THEN E ELSE E - CONST shift and go to state 2 - WHILE shift and go to state 3 + LPAREN shift and go to state 15 - expression shift and go to state 7 state 7 - (2) expression -> WHILE expression DO LBRACE expression . RBRACE + (10) E -> WHILE . LPAREN B RPAREN DO LBRACE E RBRACE - RBRACE shift and go to state 8 + LPAREN shift and go to state 16 state 8 - (2) expression -> WHILE expression DO LBRACE expression RBRACE . + (4) E -> E AOP . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE - $end reduce using rule 2 (expression -> WHILE expression DO LBRACE expression RBRACE .) - DO reduce using rule 2 (expression -> WHILE expression DO LBRACE expression RBRACE .) - RBRACE reduce using rule 2 (expression -> WHILE expression DO LBRACE expression RBRACE .) + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + E shift and go to state 17 + +state 9 + + (8) E -> E SEMICOLON . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 18 + +state 10 + + (1) E -> LET D . IN E + (14) D -> D . D + (13) D -> . ID LPAREN V RPAREN LBRACE E RBRACE + (14) D -> . D D + + IN shift and go to state 20 + ID shift and go to state 11 + + D shift and go to state 19 + +state 11 + + (13) D -> ID . LPAREN V RPAREN LBRACE E RBRACE + + LPAREN shift and go to state 21 + + +state 12 + + (3) E -> ID LPAREN . A RPAREN + (11) A -> . E + (12) A -> . A COMMA E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + A shift and go to state 22 + E shift and go to state 23 + +state 13 + + (7) E -> ID ASSIGN . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 24 + +state 14 + + (5) E -> LPAREN E . RPAREN + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN shift and go to state 25 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 15 + + (9) E -> IF LPAREN . B RPAREN THEN E ELSE E + (17) B -> . E EQOP E + (18) B -> . E COMP E + (19) B -> . B EQOP B + (20) B -> . B LOP B + (21) B -> . TRUE + (22) B -> . FALSE + (23) B -> . LPAREN B RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + TRUE shift and go to state 29 + FALSE shift and go to state 30 + LPAREN shift and go to state 26 + LET shift and go to state 2 + ID shift and go to state 3 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + B shift and go to state 27 + E shift and go to state 28 + +state 16 + + (10) E -> WHILE LPAREN . B RPAREN DO LBRACE E RBRACE + (17) B -> . E EQOP E + (18) B -> . E COMP E + (19) B -> . B EQOP B + (20) B -> . B LOP B + (21) B -> . TRUE + (22) B -> . FALSE + (23) B -> . LPAREN B RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + TRUE shift and go to state 29 + FALSE shift and go to state 30 + LPAREN shift and go to state 26 + LET shift and go to state 2 + ID shift and go to state 3 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + B shift and go to state 31 + E shift and go to state 28 + +state 17 + + (4) E -> E AOP E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + AOP reduce using rule 4 (E -> E AOP E .) + SEMICOLON reduce using rule 4 (E -> E AOP E .) + $end reduce using rule 4 (E -> E AOP E .) + RPAREN reduce using rule 4 (E -> E AOP E .) + COMMA reduce using rule 4 (E -> E AOP E .) + EQOP reduce using rule 4 (E -> E AOP E .) + COMP reduce using rule 4 (E -> E AOP E .) + LOP reduce using rule 4 (E -> E AOP E .) + ELSE reduce using rule 4 (E -> E AOP E .) + RBRACE reduce using rule 4 (E -> E AOP E .) + + ! AOP [ shift and go to state 8 ] + ! SEMICOLON [ shift and go to state 9 ] + + +state 18 + + (8) E -> E SEMICOLON E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + ! shift/reduce conflict for AOP resolved as shift + ! shift/reduce conflict for SEMICOLON resolved as shift + $end reduce using rule 8 (E -> E SEMICOLON E .) + RPAREN reduce using rule 8 (E -> E SEMICOLON E .) + COMMA reduce using rule 8 (E -> E SEMICOLON E .) + EQOP reduce using rule 8 (E -> E SEMICOLON E .) + COMP reduce using rule 8 (E -> E SEMICOLON E .) + LOP reduce using rule 8 (E -> E SEMICOLON E .) + ELSE reduce using rule 8 (E -> E SEMICOLON E .) + RBRACE reduce using rule 8 (E -> E SEMICOLON E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + ! AOP [ reduce using rule 8 (E -> E SEMICOLON E .) ] + ! SEMICOLON [ reduce using rule 8 (E -> E SEMICOLON E .) ] + + +state 19 + + (14) D -> D D . + (14) D -> D . D + (13) D -> . ID LPAREN V RPAREN LBRACE E RBRACE + (14) D -> . D D + + ! shift/reduce conflict for ID resolved as shift + IN reduce using rule 14 (D -> D D .) + ID shift and go to state 11 + + ! ID [ reduce using rule 14 (D -> D D .) ] + + D shift and go to state 19 + +state 20 + + (1) E -> LET D IN . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 32 + +state 21 + + (13) D -> ID LPAREN . V RPAREN LBRACE E RBRACE + (15) V -> . ID + (16) V -> . V COMMA ID + + ID shift and go to state 33 + + V shift and go to state 34 + +state 22 + + (3) E -> ID LPAREN A . RPAREN + (12) A -> A . COMMA E + + RPAREN shift and go to state 35 + COMMA shift and go to state 36 + + +state 23 + + (11) A -> E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN reduce using rule 11 (A -> E .) + COMMA reduce using rule 11 (A -> E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 24 + + (7) E -> ID ASSIGN E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + ! shift/reduce conflict for AOP resolved as shift + ! shift/reduce conflict for SEMICOLON resolved as shift + $end reduce using rule 7 (E -> ID ASSIGN E .) + RPAREN reduce using rule 7 (E -> ID ASSIGN E .) + COMMA reduce using rule 7 (E -> ID ASSIGN E .) + EQOP reduce using rule 7 (E -> ID ASSIGN E .) + COMP reduce using rule 7 (E -> ID ASSIGN E .) + LOP reduce using rule 7 (E -> ID ASSIGN E .) + ELSE reduce using rule 7 (E -> ID ASSIGN E .) + RBRACE reduce using rule 7 (E -> ID ASSIGN E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + ! AOP [ reduce using rule 7 (E -> ID ASSIGN E .) ] + ! SEMICOLON [ reduce using rule 7 (E -> ID ASSIGN E .) ] + + +state 25 + + (5) E -> LPAREN E RPAREN . + + AOP reduce using rule 5 (E -> LPAREN E RPAREN .) + SEMICOLON reduce using rule 5 (E -> LPAREN E RPAREN .) + $end reduce using rule 5 (E -> LPAREN E RPAREN .) + RPAREN reduce using rule 5 (E -> LPAREN E RPAREN .) + COMMA reduce using rule 5 (E -> LPAREN E RPAREN .) + EQOP reduce using rule 5 (E -> LPAREN E RPAREN .) + COMP reduce using rule 5 (E -> LPAREN E RPAREN .) + LOP reduce using rule 5 (E -> LPAREN E RPAREN .) + ELSE reduce using rule 5 (E -> LPAREN E RPAREN .) + RBRACE reduce using rule 5 (E -> LPAREN E RPAREN .) + + +state 26 + + (23) B -> LPAREN . B RPAREN + (5) E -> LPAREN . E RPAREN + (17) B -> . E EQOP E + (18) B -> . E COMP E + (19) B -> . B EQOP B + (20) B -> . B LOP B + (21) B -> . TRUE + (22) B -> . FALSE + (23) B -> . LPAREN B RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + TRUE shift and go to state 29 + FALSE shift and go to state 30 + LPAREN shift and go to state 26 + LET shift and go to state 2 + ID shift and go to state 3 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + B shift and go to state 37 + E shift and go to state 38 + +state 27 + + (9) E -> IF LPAREN B . RPAREN THEN E ELSE E + (19) B -> B . EQOP B + (20) B -> B . LOP B + + RPAREN shift and go to state 39 + EQOP shift and go to state 40 + LOP shift and go to state 41 + + +state 28 + + (17) B -> E . EQOP E + (18) B -> E . COMP E + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + EQOP shift and go to state 42 + COMP shift and go to state 43 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 29 + + (21) B -> TRUE . + + RPAREN reduce using rule 21 (B -> TRUE .) + EQOP reduce using rule 21 (B -> TRUE .) + LOP reduce using rule 21 (B -> TRUE .) + + +state 30 + + (22) B -> FALSE . + + RPAREN reduce using rule 22 (B -> FALSE .) + EQOP reduce using rule 22 (B -> FALSE .) + LOP reduce using rule 22 (B -> FALSE .) + + +state 31 + + (10) E -> WHILE LPAREN B . RPAREN DO LBRACE E RBRACE + (19) B -> B . EQOP B + (20) B -> B . LOP B + + RPAREN shift and go to state 44 + EQOP shift and go to state 40 + LOP shift and go to state 41 + + +state 32 + + (1) E -> LET D IN E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + ! shift/reduce conflict for AOP resolved as shift + ! shift/reduce conflict for SEMICOLON resolved as shift + $end reduce using rule 1 (E -> LET D IN E .) + RPAREN reduce using rule 1 (E -> LET D IN E .) + COMMA reduce using rule 1 (E -> LET D IN E .) + EQOP reduce using rule 1 (E -> LET D IN E .) + COMP reduce using rule 1 (E -> LET D IN E .) + LOP reduce using rule 1 (E -> LET D IN E .) + ELSE reduce using rule 1 (E -> LET D IN E .) + RBRACE reduce using rule 1 (E -> LET D IN E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + ! AOP [ reduce using rule 1 (E -> LET D IN E .) ] + ! SEMICOLON [ reduce using rule 1 (E -> LET D IN E .) ] + + +state 33 + + (15) V -> ID . + + RPAREN reduce using rule 15 (V -> ID .) + COMMA reduce using rule 15 (V -> ID .) + + +state 34 + + (13) D -> ID LPAREN V . RPAREN LBRACE E RBRACE + (16) V -> V . COMMA ID + + RPAREN shift and go to state 45 + COMMA shift and go to state 46 + + +state 35 + + (3) E -> ID LPAREN A RPAREN . + + AOP reduce using rule 3 (E -> ID LPAREN A RPAREN .) + SEMICOLON reduce using rule 3 (E -> ID LPAREN A RPAREN .) + $end reduce using rule 3 (E -> ID LPAREN A RPAREN .) + RPAREN reduce using rule 3 (E -> ID LPAREN A RPAREN .) + COMMA reduce using rule 3 (E -> ID LPAREN A RPAREN .) + EQOP reduce using rule 3 (E -> ID LPAREN A RPAREN .) + COMP reduce using rule 3 (E -> ID LPAREN A RPAREN .) + LOP reduce using rule 3 (E -> ID LPAREN A RPAREN .) + ELSE reduce using rule 3 (E -> ID LPAREN A RPAREN .) + RBRACE reduce using rule 3 (E -> ID LPAREN A RPAREN .) + + +state 36 + + (12) A -> A COMMA . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 47 + +state 37 + + (23) B -> LPAREN B . RPAREN + (19) B -> B . EQOP B + (20) B -> B . LOP B + + RPAREN shift and go to state 48 + EQOP shift and go to state 40 + LOP shift and go to state 41 + + +state 38 + + (5) E -> LPAREN E . RPAREN + (17) B -> E . EQOP E + (18) B -> E . COMP E + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN shift and go to state 25 + EQOP shift and go to state 42 + COMP shift and go to state 43 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 39 + + (9) E -> IF LPAREN B RPAREN . THEN E ELSE E + + THEN shift and go to state 49 + + +state 40 + + (19) B -> B EQOP . B + (17) B -> . E EQOP E + (18) B -> . E COMP E + (19) B -> . B EQOP B + (20) B -> . B LOP B + (21) B -> . TRUE + (22) B -> . FALSE + (23) B -> . LPAREN B RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + TRUE shift and go to state 29 + FALSE shift and go to state 30 + LPAREN shift and go to state 26 + LET shift and go to state 2 + ID shift and go to state 3 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + B shift and go to state 50 + E shift and go to state 28 + +state 41 + + (20) B -> B LOP . B + (17) B -> . E EQOP E + (18) B -> . E COMP E + (19) B -> . B EQOP B + (20) B -> . B LOP B + (21) B -> . TRUE + (22) B -> . FALSE + (23) B -> . LPAREN B RPAREN + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + TRUE shift and go to state 29 + FALSE shift and go to state 30 + LPAREN shift and go to state 26 + LET shift and go to state 2 + ID shift and go to state 3 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + B shift and go to state 51 + E shift and go to state 28 + +state 42 + + (17) B -> E EQOP . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 52 + +state 43 + + (18) B -> E COMP . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 53 + +state 44 + + (10) E -> WHILE LPAREN B RPAREN . DO LBRACE E RBRACE + + DO shift and go to state 54 + + +state 45 + + (13) D -> ID LPAREN V RPAREN . LBRACE E RBRACE + + LBRACE shift and go to state 55 + + +state 46 + + (16) V -> V COMMA . ID + + ID shift and go to state 56 + + +state 47 + + (12) A -> A COMMA E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN reduce using rule 12 (A -> A COMMA E .) + COMMA reduce using rule 12 (A -> A COMMA E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 48 + + (23) B -> LPAREN B RPAREN . + + RPAREN reduce using rule 23 (B -> LPAREN B RPAREN .) + EQOP reduce using rule 23 (B -> LPAREN B RPAREN .) + LOP reduce using rule 23 (B -> LPAREN B RPAREN .) + + +state 49 + + (9) E -> IF LPAREN B RPAREN THEN . E ELSE E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 57 + +state 50 + + (19) B -> B EQOP B . + (19) B -> B . EQOP B + (20) B -> B . LOP B + + RPAREN reduce using rule 19 (B -> B EQOP B .) + EQOP reduce using rule 19 (B -> B EQOP B .) + LOP reduce using rule 19 (B -> B EQOP B .) + + ! EQOP [ shift and go to state 40 ] + ! LOP [ shift and go to state 41 ] + + +state 51 + + (20) B -> B LOP B . + (19) B -> B . EQOP B + (20) B -> B . LOP B + + ! shift/reduce conflict for EQOP resolved as shift + ! shift/reduce conflict for LOP resolved as shift + RPAREN reduce using rule 20 (B -> B LOP B .) + EQOP shift and go to state 40 + LOP shift and go to state 41 + + ! EQOP [ reduce using rule 20 (B -> B LOP B .) ] + ! LOP [ reduce using rule 20 (B -> B LOP B .) ] + + +state 52 + + (17) B -> E EQOP E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN reduce using rule 17 (B -> E EQOP E .) + EQOP reduce using rule 17 (B -> E EQOP E .) + LOP reduce using rule 17 (B -> E EQOP E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 53 + + (18) B -> E COMP E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RPAREN reduce using rule 18 (B -> E COMP E .) + EQOP reduce using rule 18 (B -> E COMP E .) + LOP reduce using rule 18 (B -> E COMP E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 54 + + (10) E -> WHILE LPAREN B RPAREN DO . LBRACE E RBRACE + + LBRACE shift and go to state 58 + + +state 55 + + (13) D -> ID LPAREN V RPAREN LBRACE . E RBRACE + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 59 + +state 56 + + (16) V -> V COMMA ID . + + RPAREN reduce using rule 16 (V -> V COMMA ID .) + COMMA reduce using rule 16 (V -> V COMMA ID .) + + +state 57 + + (9) E -> IF LPAREN B RPAREN THEN E . ELSE E + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + ELSE shift and go to state 60 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 58 + + (10) E -> WHILE LPAREN B RPAREN DO LBRACE . E RBRACE + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 61 + +state 59 + + (13) D -> ID LPAREN V RPAREN LBRACE E . RBRACE + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RBRACE shift and go to state 62 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 60 + + (9) E -> IF LPAREN B RPAREN THEN E ELSE . E + (1) E -> . LET D IN E + (2) E -> . ID + (3) E -> . ID LPAREN A RPAREN + (4) E -> . E AOP E + (5) E -> . LPAREN E RPAREN + (6) E -> . CONST + (7) E -> . ID ASSIGN E + (8) E -> . E SEMICOLON E + (9) E -> . IF LPAREN B RPAREN THEN E ELSE E + (10) E -> . WHILE LPAREN B RPAREN DO LBRACE E RBRACE + + LET shift and go to state 2 + ID shift and go to state 3 + LPAREN shift and go to state 4 + CONST shift and go to state 5 + IF shift and go to state 6 + WHILE shift and go to state 7 + + E shift and go to state 63 + +state 61 + + (10) E -> WHILE LPAREN B RPAREN DO LBRACE E . RBRACE + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + RBRACE shift and go to state 64 + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + +state 62 + + (13) D -> ID LPAREN V RPAREN LBRACE E RBRACE . + + IN reduce using rule 13 (D -> ID LPAREN V RPAREN LBRACE E RBRACE .) + ID reduce using rule 13 (D -> ID LPAREN V RPAREN LBRACE E RBRACE .) + + +state 63 + + (9) E -> IF LPAREN B RPAREN THEN E ELSE E . + (4) E -> E . AOP E + (8) E -> E . SEMICOLON E + + ! shift/reduce conflict for AOP resolved as shift + ! shift/reduce conflict for SEMICOLON resolved as shift + $end reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + RPAREN reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + COMMA reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + EQOP reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + COMP reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + LOP reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + ELSE reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + RBRACE reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) + AOP shift and go to state 8 + SEMICOLON shift and go to state 9 + + ! AOP [ reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) ] + ! SEMICOLON [ reduce using rule 9 (E -> IF LPAREN B RPAREN THEN E ELSE E .) ] + + +state 64 + + (10) E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE . + + AOP reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + SEMICOLON reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + $end reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + RPAREN reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + COMMA reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + EQOP reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + COMP reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + LOP reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + ELSE reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + RBRACE reduce using rule 10 (E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE .) + +WARNING: +WARNING: Conflicts: +WARNING: +WARNING: shift/reduce conflict for AOP in state 18 resolved as shift +WARNING: shift/reduce conflict for SEMICOLON in state 18 resolved as shift +WARNING: shift/reduce conflict for ID in state 19 resolved as shift +WARNING: shift/reduce conflict for AOP in state 24 resolved as shift +WARNING: shift/reduce conflict for SEMICOLON in state 24 resolved as shift +WARNING: shift/reduce conflict for AOP in state 32 resolved as shift +WARNING: shift/reduce conflict for SEMICOLON in state 32 resolved as shift +WARNING: shift/reduce conflict for EQOP in state 51 resolved as shift +WARNING: shift/reduce conflict for LOP in state 51 resolved as shift +WARNING: shift/reduce conflict for AOP in state 63 resolved as shift +WARNING: shift/reduce conflict for SEMICOLON in state 63 resolved as shift diff --git a/Project-02/parsetab.py b/Project-02/parsetab.py index c9b6b04..5bd8b35 100644 --- a/Project-02/parsetab.py +++ b/Project-02/parsetab.py @@ -6,9 +6,9 @@ _tabversion = '3.10' _lr_method = 'LALR' -_lr_signature = 'AOP ASSIGN COMMA CONST DO ELSE FALSE ID IF IN LBRACE LET LOP LPAREN RBRACE RELOP RPAREN SEMICOLON THEN TRUE WHILEexpression : CONSTexpression : WHILE expression DO LBRACE expression RBRACE' +_lr_signature = 'EleftCOMPleftEQOPleftAOPAOP ASSIGN COMMA COMP CONST DO ELSE EQOP FALSE ID IF IN LBRACE LET LOP LPAREN RBRACE RPAREN SEMICOLON THEN TRUE WHILEE : LET D IN EE : IDE : ID LPAREN A RPARENE : E AOP EE : LPAREN E RPARENE : CONSTE : ID ASSIGN EE : E SEMICOLON EE : IF LPAREN B RPAREN THEN E ELSE EE : WHILE LPAREN B RPAREN DO LBRACE E RBRACEA : EA : A COMMA ED : ID LPAREN V RPAREN LBRACE E RBRACED : D DV : IDV : V COMMA IDB : E EQOP EB : E COMP EB : B EQOP BB : B LOP BB : TRUEB : FALSEB : LPAREN B RPAREN' -_lr_action_items = {'CONST':([0,3,6,],[2,2,2,]),'WHILE':([0,3,6,],[3,3,3,]),'$end':([1,2,8,],[0,-1,-2,]),'DO':([2,4,8,],[-1,5,-2,]),'RBRACE':([2,7,8,],[-1,8,-2,]),'LBRACE':([5,],[6,]),} +_lr_action_items = {'LET':([0,4,8,9,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,]),'ID':([0,2,4,8,9,10,12,13,15,16,19,20,21,26,36,40,41,42,43,46,49,55,58,60,62,],[3,11,3,3,3,11,3,3,3,3,11,3,33,3,3,3,3,3,3,56,3,3,3,3,-13,]),'LPAREN':([0,3,4,6,7,8,9,11,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[4,12,4,15,16,4,4,21,4,4,26,26,4,26,4,26,26,4,4,4,4,4,4,]),'CONST':([0,4,8,9,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'IF':([0,4,8,9,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'WHILE':([0,4,8,9,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'$end':([1,3,5,17,18,24,25,32,35,63,64,],[0,-2,-6,-4,-8,-7,-5,-1,-3,-9,-10,]),'AOP':([1,3,5,14,17,18,23,24,25,28,32,35,38,47,52,53,57,59,61,63,64,],[8,-2,-6,8,-4,8,8,8,-5,8,8,-3,8,8,8,8,8,8,8,8,-10,]),'SEMICOLON':([1,3,5,14,17,18,23,24,25,28,32,35,38,47,52,53,57,59,61,63,64,],[9,-2,-6,9,-4,9,9,9,-5,9,9,-3,9,9,9,9,9,9,9,9,-10,]),'RPAREN':([3,5,14,17,18,22,23,24,25,27,29,30,31,32,33,34,35,37,38,47,48,50,51,52,53,56,63,64,],[-2,-6,25,-4,-8,35,-11,-7,-5,39,-21,-22,44,-1,-15,45,-3,48,25,-12,-23,-19,-20,-17,-18,-16,-9,-10,]),'COMMA':([3,5,17,18,22,23,24,25,32,33,34,35,47,56,63,64,],[-2,-6,-4,-8,36,-11,-7,-5,-1,-15,46,-3,-12,-16,-9,-10,]),'EQOP':([3,5,17,18,24,25,27,28,29,30,31,32,35,37,38,48,50,51,52,53,63,64,],[-2,-6,-4,-8,-7,-5,40,42,-21,-22,40,-1,-3,40,42,-23,-19,40,-17,-18,-9,-10,]),'COMP':([3,5,17,18,24,25,28,32,35,38,63,64,],[-2,-6,-4,-8,-7,-5,43,-1,-3,43,-9,-10,]),'LOP':([3,5,17,18,24,25,27,29,30,31,32,35,37,48,50,51,52,53,63,64,],[-2,-6,-4,-8,-7,-5,41,-21,-22,41,-1,-3,41,-23,-19,41,-17,-18,-9,-10,]),'ELSE':([3,5,17,18,24,25,32,35,57,63,64,],[-2,-6,-4,-8,-7,-5,-1,-3,60,-9,-10,]),'RBRACE':([3,5,17,18,24,25,32,35,59,61,63,64,],[-2,-6,-4,-8,-7,-5,-1,-3,62,64,-9,-10,]),'ASSIGN':([3,],[13,]),'IN':([10,19,62,],[20,-14,-13,]),'TRUE':([15,16,26,40,41,],[29,29,29,29,29,]),'FALSE':([15,16,26,40,41,],[30,30,30,30,30,]),'THEN':([39,],[49,]),'DO':([44,],[54,]),'LBRACE':([45,54,],[55,58,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): @@ -17,7 +17,7 @@ for _k, _v in _lr_action_items.items(): _lr_action[_x][_k] = _y del _lr_action_items -_lr_goto_items = {'expression':([0,3,6,],[1,4,7,]),} +_lr_goto_items = {'E':([0,4,8,9,12,13,15,16,20,26,36,40,41,42,43,49,55,58,60,],[1,14,17,18,23,24,28,28,32,38,47,28,28,52,53,57,59,61,63,]),'D':([2,10,19,],[10,19,19,]),'A':([12,],[22,]),'B':([15,16,26,40,41,],[27,31,37,50,51,]),'V':([21,],[34,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): @@ -26,7 +26,28 @@ for _k, _v in _lr_goto_items.items(): _lr_goto[_x][_k] = _y del _lr_goto_items _lr_productions = [ - ("S' -> expression","S'",1,None,None,None), - ('expression -> CONST','expression',1,'p_expression_const','triplayacc.py',28), - ('expression -> WHILE expression DO LBRACE expression RBRACE','expression',6,'p_expression_while','triplayacc.py',33), + ("S' -> E","S'",1,None,None,None), + ('E -> LET D IN E','E',4,'p_E_let','triplayacc.py',23), + ('E -> ID','E',1,'p_E_id','triplayacc.py',27), + ('E -> ID LPAREN A RPAREN','E',4,'p_E_call','triplayacc.py',31), + ('E -> E AOP E','E',3,'p_E_aop','triplayacc.py',36), + ('E -> LPAREN E RPAREN','E',3,'p_E_paren','triplayacc.py',40), + ('E -> CONST','E',1,'p_E_const','triplayacc.py',45), + ('E -> ID ASSIGN E','E',3,'p_E_assign','triplayacc.py',49), + ('E -> E SEMICOLON E','E',3,'p_E_seq','triplayacc.py',53), + ('E -> IF LPAREN B RPAREN THEN E ELSE E','E',8,'p_E_if','triplayacc.py',57), + ('E -> WHILE LPAREN B RPAREN DO LBRACE E RBRACE','E',8,'p_E_while','triplayacc.py',61), + ('A -> E','A',1,'p_A_single','triplayacc.py',69), + ('A -> A COMMA E','A',3,'p_A_multiple','triplayacc.py',73), + ('D -> ID LPAREN V RPAREN LBRACE E RBRACE','D',7,'p_D_single','triplayacc.py',81), + ('D -> D D','D',2,'p_D_concat','triplayacc.py',85), + ('V -> ID','V',1,'p_V_single','triplayacc.py',93), + ('V -> V COMMA ID','V',3,'p_V_multiple','triplayacc.py',97), + ('B -> E EQOP E','B',3,'p_B_eqop_E','triplayacc.py',105), + ('B -> E COMP E','B',3,'p_B_comp','triplayacc.py',109), + ('B -> B EQOP B','B',3,'p_B_eqop_B','triplayacc.py',113), + ('B -> B LOP B','B',3,'p_B_lop','triplayacc.py',117), + ('B -> TRUE','B',1,'p_B_true','triplayacc.py',121), + ('B -> FALSE','B',1,'p_B_false','triplayacc.py',125), + ('B -> LPAREN B RPAREN','B',3,'p_B_paren','triplayacc.py',129), ] diff --git a/Project-02/syntax.py b/Project-02/syntax.py index 32097f6..6103b5b 100644 --- a/Project-02/syntax.py +++ b/Project-02/syntax.py @@ -1,132 +1,190 @@ - # (c) Stephan Diehl, University of Trier, Germany, 2025 class EXPRESSION: - ppcount=0 + pp_count = 0 def __init__(self): - self.pp=EXPRESSION.ppcount - EXPRESSION.ppcount=EXPRESSION.ppcount+1 + self.pp = EXPRESSION.pp_count + EXPRESSION.pp_count += 1 - def copy(self): + @staticmethod + def copy(): return EXPRESSION() def allNodes(self): ret = [self] for node in (self.__getattribute__(a) for a in self.__dict__.keys()): if isinstance(node, EXPRESSION): - ret = ret + node.allNodes() + ret += node.allNodes() if isinstance(node, list): for n in node: if isinstance(n, EXPRESSION): - ret = ret + n.allNodes() + ret += n.allNodes() return ret + def children(self): + """Return a list of (name, childNode).""" + out = [] + for key, value in self.__dict__.items(): + if key == "pp": + continue + if isinstance(value, EXPRESSION): + out.append((key, value)) + elif isinstance(value, list): + for i, elem in enumerate(value): + if isinstance(elem, EXPRESSION): + out.append((f"{key}[{i}]", elem)) + return out + + def to_dot(self, out): + # node label is class name or class name + value + label = type(self).__name__ + if hasattr(self, "operator"): # AOP/EQOP/COMP/LOP + label += f"({self.operator})" + if hasattr(self, "name"): # ID + label += f"({self.name})" + if hasattr(self, "value"): # CONST + label += f"({self.value})" + + out.write(f' node{self.pp} [label="{label}"];\n') + + for (edge_name, child) in self.children(): + out.write(f' node{self.pp} -> node{child.pp} [label="{edge_name}"];\n') + child.to_dot(out) + class LET(EXPRESSION): def __init__(self, declarations, body): super().__init__() - self.declarations=declarations - self.body=body + self.declarations = declarations + self.body = body - def __str__(self): return "let " \ - +','.join([ str(decl) for decl in self.declarations ]) \ - + " in " + str(self.body) + def __str__(self): + return "let " + ", ".join(str(d) for d in self.declarations) + " in " + str(self.body) class DECL(EXPRESSION): - def __init__(self, fname, params, body): - self.fname=fname - self.params=params - self.body=body + def __init__(self, f_name, params, body): + super().__init__() + self.f_name = f_name + self.params = params + self.body = body - def __str__(self): return self.fname+"(" \ - +','.join([ str(param) for param in self.params ]) \ - +"){ "+str(self.body)+" }" + def __str__(self): + return f"{self.f_name}(" + ",".join(str(p) for p in self.params) + ") { " + str(self.body) + " }" class CALL(EXPRESSION): - def __init__(self, fname, arguments): + def __init__(self, f_name, arguments): super().__init__() - self.fname=fname - self.arguments=arguments + self.f_name = f_name + self.arguments = arguments - def __str__(self): return self.fname+"(" \ - +','.join([ str(arg) for arg in self.arguments ]) +")" + def __str__(self): + return self.f_name + "(" + ",".join(str(a) for a in self.arguments) + ")" - -class VAR(EXPRESSION): - def __init__(self,name): +class ID(EXPRESSION): + def __init__(self, name): super().__init__() - self.name=name + self.name = name - def __str__(self): return self.name - -class BINOP(EXPRESSION): - def __init__(self,operator,arg1,arg2): - super().__init__() - self.operator=operator - self.arg1=arg1 - self.arg2=arg2 - - def __str__(self): return "("+str(self.arg1)+self.operator+str(self.arg2)+")" + def __str__(self): + return self.name class CONST(EXPRESSION): - def __init__(self,value): + def __init__(self, value): super().__init__() - self.value=value + self.value = value - def __str__(self): return str(self.value) + def __str__(self): + return str(self.value) + +class AOP(EXPRESSION): + def __init__(self, operator, arg1, arg2): + super().__init__() + self.operator = operator + self.arg1 = arg1 + self.arg2 = arg2 + + def __str__(self): + return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" + +class EQOP(EXPRESSION): + def __init__(self, operator, arg1, arg2): + super().__init__() + self.operator = operator + self.arg1 = arg1 + self.arg2 = arg2 + + def __str__(self): + return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" + +class COMP(EXPRESSION): + def __init__(self, operator, arg1, arg2): + super().__init__() + self.operator = operator + self.arg1 = arg1 + self.arg2 = arg2 + + def __str__(self): + return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" + +class LOP(EXPRESSION): + def __init__(self, operator, arg1, arg2): + super().__init__() + self.operator = operator + self.arg1 = arg1 + self.arg2 = arg2 + + def __str__(self): + return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")" class ASSIGN(EXPRESSION): def __init__(self, variable, expression): super().__init__() - self.variable=variable - self.expression=expression + self.variable = variable + self.expression = expression - def __str__(self): return self.variable.name+"="+str(self.expression) + def __str__(self): + return self.variable.name + " = " + str(self.expression) class SEQ(EXPRESSION): def __init__(self, exp1, exp2): super().__init__() - self.exp1=exp1 - self.exp2=exp2 + self.exp1 = exp1 + self.exp2 = exp2 - def __str__(self): return str(self.exp1)+";"+str(self.exp2) + def __str__(self): + return str(self.exp1) + "; " + str(self.exp2) class IF(EXPRESSION): - def __init__(self,condition,exp1,exp2): + def __init__(self, condition, exp1, exp2): super().__init__() - self.condition=condition - self.exp1=exp1 - self.exp2=exp2 + self.condition = condition + self.exp1 = exp1 + self.exp2 = exp2 - def __str__(self): return "if "+str(self.condition)+" then { " \ - + str(self.exp1)+" } else { "+str(self.exp2)+" } " - -class DO(EXPRESSION): - def __init__(self,body,condition): - super().__init__() - self.body=body - self.condition=condition - - def __str__(self): return "do { "+str(self.body)+" } while "+str(self.condition) + def __str__(self): + return "if (" + str(self.condition) + ") then { " + str(self.exp1) + " } else { " + str(self.exp2) + " }" class WHILE(EXPRESSION): - def __init__(self,condition,body): + def __init__(self, condition, body): super().__init__() - self.condition=condition - self.body=body + self.condition = condition + self.body = body - def __str__(self): return "while "+str(self.condition)+" do { "+str(self.body)+" }" - -# see https://stackoverflow.com/questions/51753937/python-pretty-print-nested-objects + def __str__(self): + return "while (" + str(self.condition) + ") do { " + str(self.body) + " }" def pretty_print(clas, indent=0): - print(' ' * indent + type(clas).__name__ + ':') + print(' ' * indent + type(clas).__name__ + ':') indent += 4 - for k,v in clas.__dict__.items(): - if '__dict__' in dir(v): - pretty_print(v,indent) + for k, v in clas.__dict__.items(): + if isinstance(v, EXPRESSION): + pretty_print(v, indent) else: - print(' ' * indent + k + ': ' + str(v)) - - + print(' ' * indent + f"{k}: {v}") +def export_dot(ast, filename="ast.dot"): + with open(filename, "w") as f: + f.write("digraph AST {\n") + f.write(" node [shape=box];\n") + ast.to_dot(f) + f.write("}\n") diff --git a/Project-02/triplalex.py b/Project-02/triplalex.py index 7b44f04..c581772 100644 --- a/Project-02/triplalex.py +++ b/Project-02/triplalex.py @@ -16,12 +16,13 @@ reserved = { 'false': 'FALSE' } -# List of token names. This is always required +# List of token names. This is always requiredy tokens = [ 'ID', 'CONST', 'AOP', - 'RELOP', + 'COMP', + 'EQOP', 'LOP', 'ASSIGN', 'LPAREN', 'RPAREN', @@ -31,11 +32,11 @@ tokens = [ ] + list(reserved.values()) # Simple tokens -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_LBRACE = r'\{' -t_RBRACE = r'\}' -t_COMMA = r',' +t_LPAREN = r'\(' +t_RPAREN = r'\)' +t_LBRACE = r'\{' +t_RBRACE = r'\}' +t_COMMA = r',' t_SEMICOLON = r';' t_ASSIGN = r'=' @@ -43,10 +44,13 @@ t_ASSIGN = r'=' t_AOP = r'\+|\-|\*|/' # Comparison operators -t_RELOP = r'<=|>=|==|!=|<|>' +t_COMP = r'<=|>=|<|>' + +# Equality operators +t_EQOP = r'\|\||&&|==|!=' # Logical operators -t_LOP = r'\|\||&&|==|!=' +t_LOP = r'\|\||&&' # IDs def t_ID(t): diff --git a/Project-02/triplayacc.py b/Project-02/triplayacc.py index 1492bc3..afbd06e 100644 --- a/Project-02/triplayacc.py +++ b/Project-02/triplayacc.py @@ -1,45 +1,140 @@ - # ------------------------------------------------------------ -# triplayacc.py -# -# Yacc grammar of the TRIPLA language -''' Here an initial grammar - E -> while E do { E } - | CONST - - CONST: Positive, integer numbers = 0 | [1-9][0-9]* - -''' - -# Note: For LALR(1) left recursion is preferred +# Grammar of the TRIPLA language # ------------------------------------------------------------ import ply.yacc as yacc import syntax as ast - -# Get the token map from the lexer. This is required. from triplalex import tokens +# Operator precedence precedence = ( - + ('left', 'COMP'), + ('left', 'EQOP'), + ('left', 'AOP'), ) -def p_expression_const(p): - 'expression : CONST' +start = 'E' + +# ------------------------------------------------------------ +# Rules for E +# ------------------------------------------------------------ + +def p_E_let(p): + 'E : LET D IN E' + p[0] = ast.LET(p[2], p[4]) + +def p_E_id(p): + 'E : ID' + p[0] = ast.ID(p[1]) + +def p_E_call(p): + 'E : ID LPAREN A RPAREN' + # E : ID(A) + p[0] = ast.CALL(p[1], p[3]) + +def p_E_aop(p): + 'E : E AOP E' + p[0] = ast.AOP(p[2], p[1], p[3]) + +def p_E_paren(p): + 'E : LPAREN E RPAREN' + # E : (E) + p[0] = p[2] + +def p_E_const(p): + 'E : CONST' p[0] = ast.CONST(p[1]) +def p_E_assign(p): + 'E : ID ASSIGN E' + p[0] = ast.ASSIGN(ast.ID(p[1]), p[3]) -def p_expression_while(p): - 'expression : WHILE expression DO LBRACE expression RBRACE' - p[0] = ast.WHILE(p[2],p[5]) +def p_E_seq(p): + 'E : E SEMICOLON E' + p[0] = ast.SEQ(p[1], p[3]) -#def p_empty(p): -# 'empty :' -# pass +def p_E_if(p): + 'E : IF LPAREN B RPAREN THEN E ELSE E' + p[0] = ast.IF(p[3], p[6], p[8]) -# Error rule for syntax errors +def p_E_while(p): + 'E : WHILE LPAREN B RPAREN DO LBRACE E RBRACE' + p[0] = ast.WHILE(p[3], p[7]) + +# ------------------------------------------------------------ +# Rules for A +# ------------------------------------------------------------ + +def p_A_single(p): + 'A : E' + p[0] = [p[1]] + +def p_A_multiple(p): + 'A : A COMMA E' + p[0] = p[1] + [p[3]] + +# ------------------------------------------------------------ +# Rules for D +# ------------------------------------------------------------ + +def p_D_single(p): + 'D : ID LPAREN V RPAREN LBRACE E RBRACE' + p[0] = ast.DECL(p[1], p[3], p[6]) + +def p_D_concat(p): + 'D : D D' + p[0] = p[1] + [p[2]] if isinstance(p[1], list) else [p[1], p[2]] + +# ------------------------------------------------------------ +# Rules for V +# ------------------------------------------------------------ + +def p_V_single(p): + 'V : ID' + p[0] = [p[1]] + +def p_V_multiple(p): + 'V : V COMMA ID' + p[0] = p[1] + [p[3]] + +# ------------------------------------------------------------ +# Rules for B +# ------------------------------------------------------------ + +def p_B_eqop_E(p): + 'B : E EQOP E' + p[0] = ast.EQOP(p[2], p[1], p[3]) + +def p_B_comp(p): + 'B : E COMP E' + p[0] = ast.COMP(p[2], p[1], p[3]) + +def p_B_eqop_B(p): + 'B : B EQOP B' + p[0] = ast.EQOP(p[2], p[1], p[3]) + +def p_B_lop(p): + 'B : B LOP B' + p[0] = ast.LOP(p[2], p[1], p[3]) + +def p_B_true(p): + 'B : TRUE' + p[0] = ast.CONST(True) + +def p_B_false(p): + 'B : FALSE' + p[0] = ast.CONST(False) + +def p_B_paren(p): + 'B : LPAREN B RPAREN' + # B : (B) + p[0] = p[2] + +# Error handling def p_error(p): - print("Syntax error in input!") + if p: + print("Syntax error at token:", p.type, "value:", p.value) + else: + print("Syntax error at EOF") -# Build the parser -parser = yacc.yacc() # debug=True +parser = yacc.yacc() \ No newline at end of file diff --git a/Project-02/whileprograms/complex.while b/Project-02/whileprograms/complex.while deleted file mode 100644 index 1c09d16..0000000 --- a/Project-02/whileprograms/complex.while +++ /dev/null @@ -1,2 +0,0 @@ -while while 1 do { 2 } - do { while 3 do { 4 } } diff --git a/Project-02/whileprograms/simple.while b/Project-02/whileprograms/simple.while deleted file mode 100644 index a019d6d..0000000 --- a/Project-02/whileprograms/simple.while +++ /dev/null @@ -1 +0,0 @@ -while 1 do { 2 } \ No newline at end of file