First try
This commit is contained in:
BIN
Project-02-03-04/Source.gv.png
Normal file
BIN
Project-02-03-04/Source.gv.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
48
Project-02-03-04/cfg/CFG.py
Normal file
48
Project-02-03-04/cfg/CFG.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from .CFG_Node import *
|
||||||
|
|
||||||
|
|
||||||
|
class CFG:
|
||||||
|
def __init__(self, in_node: CFG_Node, out_node: CFG_Node):
|
||||||
|
self.in_node = in_node
|
||||||
|
self.out_node = out_node
|
||||||
|
|
||||||
|
def to_dot(self) -> str:
|
||||||
|
visited = set()
|
||||||
|
lines = ["digraph CFG {"]
|
||||||
|
|
||||||
|
# optionale Defaults
|
||||||
|
lines.append(' node [fontname="Helvetica"];')
|
||||||
|
|
||||||
|
def node_label(node: CFG_Node) -> str:
|
||||||
|
# Basislabel aus dem Knoten
|
||||||
|
base = node.dot_label() if hasattr(node, "dot_label") else ""
|
||||||
|
|
||||||
|
# semantisches Label aus AST
|
||||||
|
if node.ast_node is not None:
|
||||||
|
semantic = str(node.ast_node)
|
||||||
|
return f"{base}\\n{semantic}" if base else semantic
|
||||||
|
|
||||||
|
return base
|
||||||
|
|
||||||
|
def node_shape(node: CFG_Node) -> str:
|
||||||
|
return node.dot_shape() if hasattr(node, "dot_shape") else "box"
|
||||||
|
|
||||||
|
def visit(node: CFG_Node):
|
||||||
|
if node.id in visited:
|
||||||
|
return
|
||||||
|
visited.add(node.id)
|
||||||
|
|
||||||
|
label = node_label(node)
|
||||||
|
shape = node_shape(node)
|
||||||
|
|
||||||
|
lines.append(
|
||||||
|
f' n{node.id} [label="{label}", shape={shape}];'
|
||||||
|
)
|
||||||
|
|
||||||
|
for child in sorted(node.children, key=lambda n: n.id):
|
||||||
|
lines.append(f" n{node.id} -> n{child.id};")
|
||||||
|
visit(child)
|
||||||
|
|
||||||
|
visit(self.in_node)
|
||||||
|
lines.append("}")
|
||||||
|
return "\n".join(lines)
|
||||||
67
Project-02-03-04/cfg/CFG_Node.py
Normal file
67
Project-02-03-04/cfg/CFG_Node.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
class CFG_Node:
|
||||||
|
__counter = 1
|
||||||
|
|
||||||
|
def __init__(self, ast_node = None):
|
||||||
|
self.ast_node = ast_node
|
||||||
|
self.children = set()
|
||||||
|
self.parents = set()
|
||||||
|
|
||||||
|
self.id = CFG_Node.__counter
|
||||||
|
CFG_Node.__counter += 1
|
||||||
|
|
||||||
|
def get_children(self):
|
||||||
|
return self.children
|
||||||
|
|
||||||
|
def get_parents(self):
|
||||||
|
return self.parents
|
||||||
|
|
||||||
|
def add_child(self, child: CFG_Node, propagate = True):
|
||||||
|
if propagate:
|
||||||
|
child.parents.add(self)
|
||||||
|
self.children.add(child)
|
||||||
|
|
||||||
|
def add_parent(self, parent: CFG_Node, propagate = True):
|
||||||
|
if propagate:
|
||||||
|
parent.add_child(self)
|
||||||
|
self.parents.add(parent)
|
||||||
|
|
||||||
|
def remove_child(self, child: CFG_Node, propagate = True):
|
||||||
|
if propagate:
|
||||||
|
child.parents.remove(self)
|
||||||
|
self.children.remove(child)
|
||||||
|
|
||||||
|
def remove_parent(self, parent: CFG_Node, propagate = True):
|
||||||
|
if propagate:
|
||||||
|
parent.children.remove(self)
|
||||||
|
self.parents.remove(parent)
|
||||||
|
|
||||||
|
|
||||||
|
class CFG_START(CFG_Node):
|
||||||
|
def dot_shape(self):
|
||||||
|
return "circle"
|
||||||
|
|
||||||
|
def dot_label(self):
|
||||||
|
return "START"
|
||||||
|
|
||||||
|
|
||||||
|
class CFG_END(CFG_Node):
|
||||||
|
def dot_shape(self):
|
||||||
|
return "doublecircle"
|
||||||
|
|
||||||
|
def dot_label(self):
|
||||||
|
return "END"
|
||||||
|
|
||||||
|
|
||||||
|
class CFG_DIAMOND(CFG_Node):
|
||||||
|
def dot_shape(self):
|
||||||
|
return "diamond"
|
||||||
|
|
||||||
|
|
||||||
|
class CFG_CALL(CFG_Node):
|
||||||
|
def dot_shape(self):
|
||||||
|
return "box"
|
||||||
|
|
||||||
|
|
||||||
|
class CFG_RETURN(CFG_Node):
|
||||||
|
def dot_shape(self):
|
||||||
|
return "box"
|
||||||
134
Project-02-03-04/cfg_build.py
Normal file
134
Project-02-03-04/cfg_build.py
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
from cfg.CFG_Node import (
|
||||||
|
CFG_Node,
|
||||||
|
CFG_CALL,
|
||||||
|
CFG_RETURN,
|
||||||
|
CFG_DIAMOND,
|
||||||
|
)
|
||||||
|
|
||||||
|
import compiler
|
||||||
|
import syntax
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------
|
||||||
|
# Expressions — NO CFG NODES
|
||||||
|
# -------------------------------------------------
|
||||||
|
|
||||||
|
class CONST(compiler.CONST):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
class ID(compiler.ID):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
class AOP(compiler.AOP):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
class COMP(compiler.COMP):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
class EQOP(compiler.EQOP):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
class LOP(compiler.LOP):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------
|
||||||
|
# Statements
|
||||||
|
# -------------------------------------------------
|
||||||
|
|
||||||
|
class ASSIGN(compiler.ASSIGN):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
n = CFG_Node(self)
|
||||||
|
pred.add_child(n)
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
class SEQ(compiler.SEQ):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
mid = self.exp1.cfa(pred, end)
|
||||||
|
if mid is None:
|
||||||
|
return None
|
||||||
|
return self.exp2.cfa(mid, end)
|
||||||
|
|
||||||
|
|
||||||
|
class IF(compiler.IF):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
cond = CFG_DIAMOND(self)
|
||||||
|
pred.add_child(cond)
|
||||||
|
|
||||||
|
join = CFG_Node()
|
||||||
|
|
||||||
|
then_end = self.exp1.cfa(cond, end)
|
||||||
|
else_end = self.exp2.cfa(cond, end)
|
||||||
|
|
||||||
|
if then_end is not None:
|
||||||
|
then_end.add_child(join)
|
||||||
|
if else_end is not None:
|
||||||
|
else_end.add_child(join)
|
||||||
|
|
||||||
|
return join
|
||||||
|
|
||||||
|
|
||||||
|
class WHILE(compiler.WHILE):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
cond = CFG_DIAMOND(self)
|
||||||
|
pred.add_child(cond)
|
||||||
|
|
||||||
|
body_end = self.body.cfa(cond, end)
|
||||||
|
if body_end is not None:
|
||||||
|
body_end.add_child(cond)
|
||||||
|
|
||||||
|
after = CFG_Node()
|
||||||
|
cond.add_child(after)
|
||||||
|
|
||||||
|
return after
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------
|
||||||
|
# Functions / calls
|
||||||
|
# -------------------------------------------------
|
||||||
|
|
||||||
|
class CALL(compiler.CALL):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
n = CFG_CALL(self)
|
||||||
|
pred.add_child(n)
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
class DECL(compiler.DECL):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
entry = CFG_Node(self)
|
||||||
|
pred.add_child(entry)
|
||||||
|
return self.body.cfa(entry, end)
|
||||||
|
|
||||||
|
|
||||||
|
class LET(compiler.LET):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
current = pred
|
||||||
|
|
||||||
|
decls = self.decl if isinstance(self.decl, list) else [self.decl]
|
||||||
|
for d in decls:
|
||||||
|
current = d.cfa(current, end)
|
||||||
|
if current is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.body.cfa(current, end)
|
||||||
|
|
||||||
|
|
||||||
|
class RETURN(syntax.EXPRESSION):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
n = CFG_RETURN(self)
|
||||||
|
pred.add_child(n)
|
||||||
|
n.add_child(end) # direct jump to global END
|
||||||
|
return None # no fallthrough
|
||||||
0
Project-02-03-04/lib/__init__.py
Normal file
0
Project-02-03-04/lib/__init__.py
Normal file
@@ -1,4 +1,5 @@
|
|||||||
import triplayacc as yacc
|
import triplayacc as yacc
|
||||||
|
import cfg_build
|
||||||
import syntax
|
import syntax
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -10,9 +11,12 @@ from vistram.vistram import MachineUI
|
|||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import matplotlib.image as mpimg
|
import matplotlib.image as mpimg
|
||||||
import helpers.console as cnsl
|
import lib.console as cnsl
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
from cfg.CFG_Node import (CFG_START, CFG_END)
|
||||||
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
matplotlib.use("TkAgg")
|
matplotlib.use("TkAgg")
|
||||||
|
|
||||||
@@ -21,6 +25,17 @@ def assemble(ast):
|
|||||||
code = ast.code({}, 0)
|
code = ast.code({}, 0)
|
||||||
return code + [halt()]
|
return code + [halt()]
|
||||||
|
|
||||||
|
def make_cfg(ast):
|
||||||
|
start = CFG_START()
|
||||||
|
end = CFG_END()
|
||||||
|
|
||||||
|
last = ast.cfa(start, end)
|
||||||
|
if last is not None:
|
||||||
|
last.add_child(end)
|
||||||
|
|
||||||
|
return CFG(start, end)
|
||||||
|
|
||||||
|
|
||||||
# Renders a diagram of the AST
|
# Renders a diagram of the AST
|
||||||
def render_diagram(dot_string: str):
|
def render_diagram(dot_string: str):
|
||||||
# Set DPI for PNG
|
# Set DPI for PNG
|
||||||
@@ -64,9 +79,9 @@ if __name__ == "__main__":
|
|||||||
print("\nTRIPLA Parser and TRIPLA to TRAM Compiler")
|
print("\nTRIPLA Parser and TRIPLA to TRAM Compiler")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
mode = cnsl.prompt_choice("\nSelect action:", ["Parse .tripla", "Compile .tripla", "Exit"])
|
mode = cnsl.prompt_choice("\nSelect action:", ["Parse .tripla", "Compile .tripla", "CFG for .tripla", "Exit"])
|
||||||
|
|
||||||
if mode == 2:
|
if mode == 3:
|
||||||
print("\nBye Bye.")
|
print("\nBye Bye.")
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -143,4 +158,26 @@ if __name__ == "__main__":
|
|||||||
ui.machine.reset()
|
ui.machine.reset()
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
|
|
||||||
|
elif mode == 2:
|
||||||
|
cfg = make_cfg(ast)
|
||||||
|
|
||||||
|
dot_str = cfg.to_dot()
|
||||||
|
if cnsl.prompt_confirmation("\nExport CFG as .dot file?"):
|
||||||
|
default = f"{path.stem}_cfg.dot"
|
||||||
|
filename = input(f"Filename [{default}]: ").strip()
|
||||||
|
if not filename:
|
||||||
|
filename = default
|
||||||
|
|
||||||
|
out_path = Path(__file__).parent / filename
|
||||||
|
with open(out_path, "w") as f:
|
||||||
|
f.write(dot_str)
|
||||||
|
|
||||||
|
print(f"Saved CFG DOT file as: {out_path}")
|
||||||
|
|
||||||
|
if cnsl.prompt_confirmation("Display CFG diagram?"):
|
||||||
|
render_diagram(dot_str)
|
||||||
|
print("Rendered CFG diagram.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -781,6 +781,7 @@ state 38
|
|||||||
(4) E -> E . AOP E
|
(4) E -> E . AOP E
|
||||||
(8) E -> E . SEMICOLON E
|
(8) E -> E . SEMICOLON E
|
||||||
|
|
||||||
|
SEMICOLON reduce using rule 1 (E -> LET D IN E .)
|
||||||
$end reduce using rule 1 (E -> LET D IN E .)
|
$end reduce using rule 1 (E -> LET D IN E .)
|
||||||
RPAREN reduce using rule 1 (E -> LET D IN E .)
|
RPAREN reduce using rule 1 (E -> LET D IN E .)
|
||||||
EQOP reduce using rule 1 (E -> LET D IN E .)
|
EQOP reduce using rule 1 (E -> LET D IN E .)
|
||||||
@@ -792,10 +793,9 @@ state 38
|
|||||||
DO reduce using rule 1 (E -> LET D IN E .)
|
DO reduce using rule 1 (E -> LET D IN E .)
|
||||||
RBRACE 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
|
AOP shift and go to state 8
|
||||||
SEMICOLON shift and go to state 9
|
|
||||||
|
|
||||||
! AOP [ reduce using rule 1 (E -> LET D IN E .) ]
|
! AOP [ reduce using rule 1 (E -> LET D IN E .) ]
|
||||||
! SEMICOLON [ reduce using rule 1 (E -> LET D IN E .) ]
|
! SEMICOLON [ shift and go to state 9 ]
|
||||||
|
|
||||||
|
|
||||||
state 39
|
state 39
|
||||||
@@ -1056,11 +1056,10 @@ state 56
|
|||||||
(16) V -> V COMMA V .
|
(16) V -> V COMMA V .
|
||||||
(16) V -> V . COMMA V
|
(16) V -> V . COMMA V
|
||||||
|
|
||||||
! shift/reduce conflict for COMMA resolved as shift
|
|
||||||
RPAREN reduce using rule 16 (V -> V COMMA V .)
|
RPAREN reduce using rule 16 (V -> V COMMA V .)
|
||||||
COMMA shift and go to state 51
|
COMMA reduce using rule 16 (V -> V COMMA V .)
|
||||||
|
|
||||||
! COMMA [ reduce using rule 16 (V -> V COMMA V .) ]
|
! COMMA [ shift and go to state 51 ]
|
||||||
|
|
||||||
|
|
||||||
state 57
|
state 57
|
||||||
@@ -1069,8 +1068,7 @@ state 57
|
|||||||
(4) E -> E . AOP E
|
(4) E -> E . AOP E
|
||||||
(8) E -> E . SEMICOLON E
|
(8) E -> E . SEMICOLON E
|
||||||
|
|
||||||
! shift/reduce conflict for AOP resolved as shift
|
SEMICOLON reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
! shift/reduce conflict for SEMICOLON resolved as shift
|
|
||||||
$end reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
$end reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
RPAREN reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
RPAREN reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
EQOP reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
EQOP reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
@@ -1082,10 +1080,9 @@ state 57
|
|||||||
DO reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
DO reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
RBRACE reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
RBRACE reduce using rule 9 (E -> IF B THEN E ELSE E .)
|
||||||
AOP shift and go to state 8
|
AOP shift and go to state 8
|
||||||
SEMICOLON shift and go to state 9
|
|
||||||
|
|
||||||
! AOP [ reduce using rule 9 (E -> IF B THEN E ELSE E .) ]
|
! AOP [ reduce using rule 9 (E -> IF B THEN E ELSE E .) ]
|
||||||
! SEMICOLON [ reduce using rule 9 (E -> IF B THEN E ELSE E .) ]
|
! SEMICOLON [ shift and go to state 9 ]
|
||||||
|
|
||||||
|
|
||||||
state 58
|
state 58
|
||||||
@@ -1130,6 +1127,3 @@ WARNING:
|
|||||||
WARNING: shift/reduce conflict for ID in state 23 resolved as shift
|
WARNING: shift/reduce conflict for ID in state 23 resolved as shift
|
||||||
WARNING: shift/reduce conflict for EQOP in state 45 resolved as shift
|
WARNING: shift/reduce conflict for EQOP in state 45 resolved as shift
|
||||||
WARNING: shift/reduce conflict for LOP in state 45 resolved as shift
|
WARNING: shift/reduce conflict for LOP in state 45 resolved as shift
|
||||||
WARNING: shift/reduce conflict for COMMA in state 56 resolved as shift
|
|
||||||
WARNING: shift/reduce conflict for AOP in state 57 resolved as shift
|
|
||||||
WARNING: shift/reduce conflict for SEMICOLON in state 57 resolved as shift
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ _tabversion = '3.10'
|
|||||||
|
|
||||||
_lr_method = 'LALR'
|
_lr_method = 'LALR'
|
||||||
|
|
||||||
_lr_signature = 'ErightINleftSEMICOLONrightASSIGNleftCOMPleftEQOPleftAOPAOP 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 B THEN E ELSE EE : WHILE B DO LBRACE E RBRACEA : EA : A COMMA ED : ID LPAREN V RPAREN LBRACE E RBRACED : D DV : IDV : V COMMA VB : E EQOP EB : E COMP EB : B EQOP BB : B LOP BB : TRUEB : FALSEB : LPAREN B RPAREN'
|
_lr_signature = 'EleftSEMICOLONleftINleftELSEleftCOMMArightASSIGNleftCOMPleftEQOPleftAOPleftCOMPleftEQOPAOP 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 B THEN E ELSE EE : WHILE B DO LBRACE E RBRACEA : EA : A COMMA ED : ID LPAREN V RPAREN LBRACE E RBRACED : D DV : IDV : V COMMA VB : E EQOP EB : E COMP EB : B EQOP BB : B LOP BB : TRUEB : FALSEB : LPAREN B RPAREN'
|
||||||
|
|
||||||
_lr_action_items = {'LET':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,]),'ID':([0,2,4,6,7,8,9,10,12,13,19,23,24,25,30,31,32,33,34,42,49,51,53,55,60,],[3,11,3,3,3,3,3,11,3,3,3,11,3,39,3,3,3,3,3,3,3,39,3,3,-13,]),'LPAREN':([0,3,4,6,7,8,9,11,12,13,19,24,30,31,32,33,34,42,49,53,55,],[4,12,4,19,19,4,4,25,4,4,19,4,4,19,19,4,4,4,4,4,4,]),'CONST':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'IF':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'WHILE':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'$end':([1,3,5,21,22,28,29,38,41,57,58,],[0,-2,-6,-4,-8,-7,-5,-1,-3,-9,-10,]),'AOP':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[8,-2,-6,8,8,-4,8,8,8,-5,8,8,-3,8,8,8,8,8,8,-10,8,]),'SEMICOLON':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[9,-2,-6,9,9,-4,-8,9,-7,-5,9,9,-3,9,9,9,9,9,9,-10,9,]),'RPAREN':([3,5,14,17,18,21,22,26,27,28,29,35,36,38,39,40,41,44,45,46,47,48,52,56,57,58,],[-2,-6,29,-21,-22,-4,-8,41,-11,-7,-5,48,29,-1,-15,50,-3,-19,-20,-17,-18,-23,-12,-16,-9,-10,]),'EQOP':([3,5,15,16,17,18,20,21,22,28,29,35,36,38,41,44,45,46,47,48,57,58,],[-2,-6,31,33,-21,-22,31,-4,-8,-7,-5,31,33,-1,-3,-19,31,-17,-18,-23,-9,-10,]),'COMP':([3,5,16,21,22,28,29,36,38,41,57,58,],[-2,-6,34,-4,-8,-7,-5,34,-1,-3,-9,-10,]),'COMMA':([3,5,21,22,26,27,28,29,38,39,40,41,52,56,57,58,],[-2,-6,-4,-8,42,-11,-7,-5,-1,-15,51,-3,-12,51,-9,-10,]),'ELSE':([3,5,21,22,28,29,38,41,43,57,58,],[-2,-6,-4,-8,-7,-5,-1,-3,53,-9,-10,]),'THEN':([3,5,15,17,18,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,30,-21,-22,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'LOP':([3,5,15,17,18,20,21,22,28,29,35,38,41,44,45,46,47,48,57,58,],[-2,-6,32,-21,-22,32,-4,-8,-7,-5,32,-1,-3,-19,32,-17,-18,-23,-9,-10,]),'DO':([3,5,17,18,20,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,-21,-22,37,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'RBRACE':([3,5,21,22,28,29,38,41,54,57,58,59,],[-2,-6,-4,-8,-7,-5,-1,-3,58,-9,-10,60,]),'ASSIGN':([3,],[13,]),'TRUE':([6,7,19,31,32,],[17,17,17,17,17,]),'FALSE':([6,7,19,31,32,],[18,18,18,18,18,]),'IN':([10,23,60,],[24,-14,-13,]),'LBRACE':([37,50,],[49,55,]),}
|
_lr_action_items = {'LET':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,]),'ID':([0,2,4,6,7,8,9,10,12,13,19,23,24,25,30,31,32,33,34,42,49,51,53,55,60,],[3,11,3,3,3,3,3,11,3,3,3,11,3,39,3,3,3,3,3,3,3,39,3,3,-13,]),'LPAREN':([0,3,4,6,7,8,9,11,12,13,19,24,30,31,32,33,34,42,49,53,55,],[4,12,4,19,19,4,4,25,4,4,19,4,4,19,19,4,4,4,4,4,4,]),'CONST':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'IF':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'WHILE':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'$end':([1,3,5,21,22,28,29,38,41,57,58,],[0,-2,-6,-4,-8,-7,-5,-1,-3,-9,-10,]),'AOP':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[8,-2,-6,8,8,-4,8,8,8,-5,8,8,-3,8,8,8,8,8,8,-10,8,]),'SEMICOLON':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[9,-2,-6,9,9,-4,-8,9,-7,-5,9,-1,-3,9,9,9,9,9,-9,-10,9,]),'RPAREN':([3,5,14,17,18,21,22,26,27,28,29,35,36,38,39,40,41,44,45,46,47,48,52,56,57,58,],[-2,-6,29,-21,-22,-4,-8,41,-11,-7,-5,48,29,-1,-15,50,-3,-19,-20,-17,-18,-23,-12,-16,-9,-10,]),'EQOP':([3,5,15,16,17,18,20,21,22,28,29,35,36,38,41,44,45,46,47,48,57,58,],[-2,-6,31,33,-21,-22,31,-4,-8,-7,-5,31,33,-1,-3,-19,31,-17,-18,-23,-9,-10,]),'COMP':([3,5,16,21,22,28,29,36,38,41,57,58,],[-2,-6,34,-4,-8,-7,-5,34,-1,-3,-9,-10,]),'COMMA':([3,5,21,22,26,27,28,29,38,39,40,41,52,56,57,58,],[-2,-6,-4,-8,42,-11,-7,-5,-1,-15,51,-3,-12,-16,-9,-10,]),'ELSE':([3,5,21,22,28,29,38,41,43,57,58,],[-2,-6,-4,-8,-7,-5,-1,-3,53,-9,-10,]),'THEN':([3,5,15,17,18,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,30,-21,-22,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'LOP':([3,5,15,17,18,20,21,22,28,29,35,38,41,44,45,46,47,48,57,58,],[-2,-6,32,-21,-22,32,-4,-8,-7,-5,32,-1,-3,-19,32,-17,-18,-23,-9,-10,]),'DO':([3,5,17,18,20,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,-21,-22,37,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'RBRACE':([3,5,21,22,28,29,38,41,54,57,58,59,],[-2,-6,-4,-8,-7,-5,-1,-3,58,-9,-10,60,]),'ASSIGN':([3,],[13,]),'TRUE':([6,7,19,31,32,],[17,17,17,17,17,]),'FALSE':([6,7,19,31,32,],[18,18,18,18,18,]),'IN':([10,23,60,],[24,-14,-13,]),'LBRACE':([37,50,],[49,55,]),}
|
||||||
|
|
||||||
_lr_action = {}
|
_lr_action = {}
|
||||||
for _k, _v in _lr_action_items.items():
|
for _k, _v in _lr_action_items.items():
|
||||||
@@ -27,27 +27,27 @@ for _k, _v in _lr_goto_items.items():
|
|||||||
del _lr_goto_items
|
del _lr_goto_items
|
||||||
_lr_productions = [
|
_lr_productions = [
|
||||||
("S' -> E","S'",1,None,None,None),
|
("S' -> E","S'",1,None,None,None),
|
||||||
('E -> LET D IN E','E',4,'p_E_let','triplayacc.py',27),
|
('E -> LET D IN E','E',4,'p_E_let','triplayacc.py',30),
|
||||||
('E -> ID','E',1,'p_E_id','triplayacc.py',31),
|
('E -> ID','E',1,'p_E_id','triplayacc.py',34),
|
||||||
('E -> ID LPAREN A RPAREN','E',4,'p_E_call','triplayacc.py',35),
|
('E -> ID LPAREN A RPAREN','E',4,'p_E_call','triplayacc.py',38),
|
||||||
('E -> E AOP E','E',3,'p_E_aop','triplayacc.py',40),
|
('E -> E AOP E','E',3,'p_E_aop','triplayacc.py',43),
|
||||||
('E -> LPAREN E RPAREN','E',3,'p_E_paren','triplayacc.py',44),
|
('E -> LPAREN E RPAREN','E',3,'p_E_paren','triplayacc.py',47),
|
||||||
('E -> CONST','E',1,'p_E_const','triplayacc.py',49),
|
('E -> CONST','E',1,'p_E_const','triplayacc.py',52),
|
||||||
('E -> ID ASSIGN E','E',3,'p_E_assign','triplayacc.py',53),
|
('E -> ID ASSIGN E','E',3,'p_E_assign','triplayacc.py',56),
|
||||||
('E -> E SEMICOLON E','E',3,'p_E_seq','triplayacc.py',57),
|
('E -> E SEMICOLON E','E',3,'p_E_seq','triplayacc.py',60),
|
||||||
('E -> IF B THEN E ELSE E','E',6,'p_E_if','triplayacc.py',61),
|
('E -> IF B THEN E ELSE E','E',6,'p_E_if','triplayacc.py',64),
|
||||||
('E -> WHILE B DO LBRACE E RBRACE','E',6,'p_E_while','triplayacc.py',65),
|
('E -> WHILE B DO LBRACE E RBRACE','E',6,'p_E_while','triplayacc.py',68),
|
||||||
('A -> E','A',1,'p_A_single','triplayacc.py',74),
|
('A -> E','A',1,'p_A_single','triplayacc.py',77),
|
||||||
('A -> A COMMA E','A',3,'p_A_multiple','triplayacc.py',78),
|
('A -> A COMMA E','A',3,'p_A_multiple','triplayacc.py',81),
|
||||||
('D -> ID LPAREN V RPAREN LBRACE E RBRACE','D',7,'p_D_single','triplayacc.py',86),
|
('D -> ID LPAREN V RPAREN LBRACE E RBRACE','D',7,'p_D_single','triplayacc.py',89),
|
||||||
('D -> D D','D',2,'p_D_concat','triplayacc.py',90),
|
('D -> D D','D',2,'p_D_concat','triplayacc.py',93),
|
||||||
('V -> ID','V',1,'p_V_single','triplayacc.py',98),
|
('V -> ID','V',1,'p_V_single','triplayacc.py',101),
|
||||||
('V -> V COMMA V','V',3,'p_V_multiple','triplayacc.py',102),
|
('V -> V COMMA V','V',3,'p_V_multiple','triplayacc.py',105),
|
||||||
('B -> E EQOP E','B',3,'p_B_eqop_E','triplayacc.py',110),
|
('B -> E EQOP E','B',3,'p_B_eqop_E','triplayacc.py',113),
|
||||||
('B -> E COMP E','B',3,'p_B_comp','triplayacc.py',114),
|
('B -> E COMP E','B',3,'p_B_comp','triplayacc.py',117),
|
||||||
('B -> B EQOP B','B',3,'p_B_eqop_B','triplayacc.py',118),
|
('B -> B EQOP B','B',3,'p_B_eqop_B','triplayacc.py',121),
|
||||||
('B -> B LOP B','B',3,'p_B_lop','triplayacc.py',122),
|
('B -> B LOP B','B',3,'p_B_lop','triplayacc.py',125),
|
||||||
('B -> TRUE','B',1,'p_B_true','triplayacc.py',126),
|
('B -> TRUE','B',1,'p_B_true','triplayacc.py',129),
|
||||||
('B -> FALSE','B',1,'p_B_false','triplayacc.py',130),
|
('B -> FALSE','B',1,'p_B_false','triplayacc.py',133),
|
||||||
('B -> LPAREN B RPAREN','B',3,'p_B_paren','triplayacc.py',134),
|
('B -> LPAREN B RPAREN','B',3,'p_B_paren','triplayacc.py',137),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,16 +3,21 @@
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
import ply.yacc as yacc
|
import ply.yacc as yacc
|
||||||
import compiler as ast
|
import cfg_build as ast
|
||||||
from triplalex import tokens
|
from triplalex import tokens
|
||||||
|
|
||||||
precedence = (
|
precedence = (
|
||||||
('right', 'IN'),
|
|
||||||
('left', 'SEMICOLON'),
|
('left', 'SEMICOLON'),
|
||||||
|
('left', 'IN'),
|
||||||
|
('left', 'ELSE'),
|
||||||
|
('left', 'COMMA'),
|
||||||
('right', 'ASSIGN'),
|
('right', 'ASSIGN'),
|
||||||
('left', 'COMP'),
|
('left', 'COMP'),
|
||||||
('left', 'EQOP'),
|
('left', 'EQOP'),
|
||||||
('left', 'AOP'),
|
('left', 'AOP'),
|
||||||
|
('left', 'COMP'),
|
||||||
|
('left', 'EQOP'),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
start = 'E'
|
start = 'E'
|
||||||
|
|||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
matplotlib~=3.10.8
|
||||||
|
graphviz~=0.21
|
||||||
|
ply~=3.11
|
||||||
Reference in New Issue
Block a user