Mon commit avec mes modifs à moi ! Na
This commit is contained in:
parent
52ce1488c5
commit
62d045512a
@ -86,7 +86,9 @@ define CLEAN
|
|||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
for f in glob.glob("**/tests/**/*.c", recursive=True):
|
for f in glob.glob("**/tests/**/*.c", recursive=True):
|
||||||
for s in ("{}-{}.s".format(f[:-2], test) for test in ("naive", "smart", "gcc", "all-in-mem")):
|
files = ["{}-{}.{}".format(f[:-2], test,ext) for test in ("naive", "smart", "gcc", "all-in-mem") for ext in ("s","riscv","pdf")]
|
||||||
|
files += ["{}.{}.{}.{}".format(f[:-2], funct, test,ext for funct in ("main") for test in ("enterssa","exitssa") for ext in ("dot.pdf","dot")
|
||||||
|
for s in files:
|
||||||
try:
|
try:
|
||||||
os.remove(s)
|
os.remove(s)
|
||||||
print("Removed {}".format(s))
|
print("Removed {}".format(s))
|
||||||
|
|||||||
@ -52,7 +52,7 @@ print_stat
|
|||||||
expr
|
expr
|
||||||
: MINUS expr #unaryMinusExpr
|
: MINUS expr #unaryMinusExpr
|
||||||
| NOT expr #notExpr
|
| NOT expr #notExpr
|
||||||
| expr myop=(MULT|DIV|MOD) expr #multiplicativeExpr
|
| expr myop=(MULT|DIV|MOD) expr #multiplicativeExpr
|
||||||
| expr myop=(PLUS|MINUS) expr #additiveExpr
|
| expr myop=(PLUS|MINUS) expr #additiveExpr
|
||||||
| expr myop=(GT|LT|GTEQ|LTEQ) expr #relationalExpr
|
| expr myop=(GT|LT|GTEQ|LTEQ) expr #relationalExpr
|
||||||
| expr myop=(EQ|NEQ) expr #equalityExpr
|
| expr myop=(EQ|NEQ) expr #equalityExpr
|
||||||
|
|||||||
@ -3,23 +3,32 @@ LAB4 (simple code generation), MIF08 / CAP 2022-23
|
|||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
YOUR NAME HERE
|
Samy Avrillon
|
||||||
|
|
||||||
# Contents
|
# Contents
|
||||||
|
|
||||||
TODO for STUDENTS : Say a bit about the code infrastructure ...
|
Same as the first lab, you did the structure, so i have litle interest in commenting it.
|
||||||
|
|
||||||
# Test design
|
# Test design
|
||||||
|
|
||||||
TODO: explain your tests
|
- folder *operators* checks all operations on operators (additive, multiplicative, relations, unary minus, boolean)
|
||||||
|
- *nested{While,For,Ifs}* checks with structures of nested blocks.
|
||||||
|
- *forTests* and *whileClauseSyntax* tests for the well-execution of for and while loops.
|
||||||
|
- *testTooManyVariables* tries initializing many variables in order to make the naive allocator fail.
|
||||||
|
|
||||||
# Design choices
|
# Design choices
|
||||||
|
|
||||||
TODO: explain your choices. How did you implement boolean not? Did you implement an extension?
|
Boolean Not has been implemented using an immediate 1 and the opreator xor, even though such operator exists in riscV (see Known bugs).
|
||||||
|
|
||||||
|
I did implement C-like loops with the same system used in the interpreter.
|
||||||
|
|
||||||
# Known bugs
|
# Known bugs
|
||||||
|
|
||||||
TODO: Bugs and limitations.
|
There is a lot of RiscV instruction that are not implemented in Lib, and that makes bigger and less readable code (for exemple, slt would be better than blt for integer comparison).
|
||||||
|
|
||||||
|
By design, we always use a jump statement before a label. Otherwise, the CFG linearization fails. This is intended (the missing jump could be added in *prepare_chunk*).
|
||||||
|
|
||||||
|
So, there is one line in *BuildCFG.c* that sould never be executed (that's why the coverage is not 100% complete), when a label is detected as a leader, as the preceding jump will always have been detected as a leader before it.
|
||||||
|
|
||||||
# Checklists
|
# Checklists
|
||||||
|
|
||||||
@ -28,30 +37,30 @@ and *tested* with appropriate test cases.
|
|||||||
|
|
||||||
## Code generation
|
## Code generation
|
||||||
|
|
||||||
- [ ] Number Atom
|
- [X] Number Atom
|
||||||
- [ ] Boolean Atom
|
- [X] Boolean Atom
|
||||||
- [ ] Id Atom
|
- [X] Id Atom
|
||||||
- [ ] Additive expression
|
- [X] Additive expression
|
||||||
- [ ] Multiplicative expression
|
- [X] Multiplicative expression
|
||||||
- [ ] UnaryMinus expression
|
- [X] UnaryMinus expression
|
||||||
- [ ] Or expression
|
- [X] Or expression
|
||||||
- [ ] And expression
|
- [X] And expression
|
||||||
- [ ] Equality expression
|
- [X] Equality expression
|
||||||
- [ ] Relational expression (! many cases -> many tests)
|
- [X] Relational expression (! many cases -> many tests)
|
||||||
- [ ] Not expression
|
- [X] Not expression
|
||||||
|
|
||||||
## Statements
|
## Statements
|
||||||
|
|
||||||
- [ ] Prog, assignements
|
- [X] Prog, assignements
|
||||||
- [ ] While
|
- [X] While
|
||||||
- [ ] Cond Block
|
- [X] Cond Block
|
||||||
- [ ] If
|
- [X] If
|
||||||
- [ ] Nested ifs
|
- [X] Nested ifs
|
||||||
- [ ] Nested whiles
|
- [X] Nested whiles
|
||||||
|
|
||||||
## Allocation
|
## Allocation
|
||||||
|
|
||||||
- [ ] Naive allocation
|
- [X] Naive allocation
|
||||||
- [ ] All in memory allocation
|
- [X] All in memory allocation
|
||||||
- [ ] Massive tests of memory allocation
|
- [X] Massive tests of memory allocation
|
||||||
|
|
||||||
|
|||||||
@ -110,7 +110,7 @@ class MiniCTypingVisitor(MiniCVisitor):
|
|||||||
else:
|
else:
|
||||||
self._raise(ctx,"boolean operator", fstT)
|
self._raise(ctx,"boolean operator", fstT)
|
||||||
else:
|
else:
|
||||||
self._assertSameType(ctx,"boolean operator", fstT,sndT)
|
self._raise(ctx,"boolean operator", fstT,sndT)
|
||||||
|
|
||||||
def visitAndExpr(self, ctx):
|
def visitAndExpr(self, ctx):
|
||||||
fstT = self.visit(ctx.expr(0))
|
fstT = self.visit(ctx.expr(0))
|
||||||
@ -121,7 +121,7 @@ class MiniCTypingVisitor(MiniCVisitor):
|
|||||||
else:
|
else:
|
||||||
self._raise(ctx,"boolean operator", fstT)
|
self._raise(ctx,"boolean operator", fstT)
|
||||||
else:
|
else:
|
||||||
self._assertSameType(ctx,"boolean operator", fstT,sndT)
|
self._raise(ctx,"boolean operator", fstT,sndT)
|
||||||
|
|
||||||
def visitEqualityExpr(self, ctx):
|
def visitEqualityExpr(self, ctx):
|
||||||
fstT = self.visit(ctx.expr(0))
|
fstT = self.visit(ctx.expr(0))
|
||||||
@ -140,7 +140,7 @@ class MiniCTypingVisitor(MiniCVisitor):
|
|||||||
else:
|
else:
|
||||||
self._raise(ctx, "comparaison operator", fstT)
|
self._raise(ctx, "comparaison operator", fstT)
|
||||||
else:
|
else:
|
||||||
self._assertSameType(ctx,"comparaison operator", fstT,sndT)
|
self._raise(ctx,"comparaison operator", fstT,sndT)
|
||||||
|
|
||||||
def visitAdditiveExpr(self, ctx):
|
def visitAdditiveExpr(self, ctx):
|
||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
@ -152,9 +152,9 @@ class MiniCTypingVisitor(MiniCVisitor):
|
|||||||
elif (fstT == BaseType.String and ctx.myop.type == MiniCParser.PLUS):
|
elif (fstT == BaseType.String and ctx.myop.type == MiniCParser.PLUS):
|
||||||
return BaseType.String
|
return BaseType.String
|
||||||
else:
|
else:
|
||||||
self._raise(ctx, "additive operands", fstT)
|
self._raise(ctx, "additive operands", fstT,sndT)
|
||||||
else:
|
else:
|
||||||
self._assertSameType(ctx,"additive operator", fstT,sndT)
|
self._raise(ctx,"additive operator", fstT,sndT)
|
||||||
|
|
||||||
def visitMultiplicativeExpr(self, ctx):
|
def visitMultiplicativeExpr(self, ctx):
|
||||||
fstT = self.visit(ctx.expr(0))
|
fstT = self.visit(ctx.expr(0))
|
||||||
@ -165,7 +165,7 @@ class MiniCTypingVisitor(MiniCVisitor):
|
|||||||
else:
|
else:
|
||||||
return fstT
|
return fstT
|
||||||
else:
|
else:
|
||||||
self._assertSameType(ctx,"multiplicative operator", fstT,sndT)
|
self._raise(ctx,"multiplicative operands", fstT,sndT)
|
||||||
|
|
||||||
def visitNotExpr(self, ctx):
|
def visitNotExpr(self, ctx):
|
||||||
fstT = self.visit(ctx.expr())
|
fstT = self.visit(ctx.expr())
|
||||||
|
|||||||
@ -11,4 +11,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 8 col 6: type mismatch for multiplicative operator: integer and string
|
// In function main: Line 8 col 6: invalid type for multiplicative operands: integer and string
|
||||||
@ -6,4 +6,4 @@ int main(){
|
|||||||
}
|
}
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 4 col 14: invalid type for additive operands: boolean
|
// In function main: Line 4 col 14: invalid type for additive operands: boolean and boolean
|
||||||
@ -11,4 +11,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 6 col 12: type mismatch for additive operator: integer and boolean
|
// In function main: Line 6 col 12: invalid type for additive operator: integer and boolean
|
||||||
|
|||||||
@ -11,4 +11,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 8 col 8: invalid type for additive operands: boolean
|
// In function main: Line 8 col 8: invalid type for additive operands: boolean and boolean
|
||||||
|
|||||||
@ -13,4 +13,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 10 col 8: type mismatch for additive operator: integer and float
|
// In function main: Line 10 col 8: invalid type for additive operator: integer and float
|
||||||
|
|||||||
@ -11,4 +11,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean
|
// In function main: Line 8 col 8: invalid type for boolean operator: integer and boolean
|
||||||
|
|||||||
@ -19,4 +19,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 16 col 8: type mismatch for comparaison operator: integer and float
|
// In function main: Line 16 col 8: invalid type for comparaison operator: integer and float
|
||||||
|
|||||||
@ -13,4 +13,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 10 col 8: type mismatch for multiplicative operator: integer and float
|
// In function main: Line 10 col 8: invalid type for multiplicative operands: integer and float
|
||||||
|
|||||||
@ -11,4 +11,4 @@ int main(){
|
|||||||
|
|
||||||
// EXITCODE 2
|
// EXITCODE 2
|
||||||
// EXPECTED
|
// EXPECTED
|
||||||
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean
|
// In function main: Line 8 col 8: invalid type for boolean operator: integer and boolean
|
||||||
|
|||||||
@ -14,12 +14,32 @@ class AllInMemAllocator(Allocator):
|
|||||||
before: List[Instruction] = []
|
before: List[Instruction] = []
|
||||||
after: List[Instruction] = []
|
after: List[Instruction] = []
|
||||||
subst: Dict[Operand, Operand] = {}
|
subst: Dict[Operand, Operand] = {}
|
||||||
|
|
||||||
|
old_args = old_instr.args()
|
||||||
|
for arg in old_args:
|
||||||
|
# We substitute
|
||||||
|
subst[arg] = S[numreg]
|
||||||
|
numreg += 1
|
||||||
|
for arg in old_instr.used():
|
||||||
|
# We have to read them from memory
|
||||||
|
if(isinstance(arg, Temporary)):
|
||||||
|
before.append(RiscV.ld(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
|
||||||
|
for arg in old_instr.defined():
|
||||||
|
# We have to write them after to memory
|
||||||
|
if(isinstance(arg, Temporary)):
|
||||||
|
after.append(RiscV.sd(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
|
||||||
|
|
||||||
|
|
||||||
# TODO (Exercise 7): compute before,after,args.
|
# TODO (Exercise 7): compute before,after,args.
|
||||||
# TODO (Exercise 7): iterate over old_args, check which argument
|
# TODO (Exercise 7): iterate over old_args, check which argument
|
||||||
# TODO (Exercise 7): is a temporary (e.g. isinstance(..., Temporary)),
|
# TODO (Exercise 7): is a temporary (e.g. isinstance(..., Temporary)),
|
||||||
# TODO (Exercise 7): and if so, generate ld/sd accordingly. Replace the
|
# TODO (Exercise 7): and if so, generate ld/sd accordingly. Replace the
|
||||||
# TODO (Exercise 7): temporary with S[1], S[2] or S[3] physical registers.
|
# TODO (Exercise 7): temporary with S[1], S[2] or S[3] physical registers.
|
||||||
new_instr = old_instr.substitute(subst)
|
try:
|
||||||
|
new_instr = old_instr.substitute(subst)
|
||||||
|
except Exception:
|
||||||
|
# We have an instruction that doesn't need substitution
|
||||||
|
return [old_instr]
|
||||||
return before + [new_instr] + after
|
return before + [new_instr] + after
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
|
|||||||
@ -20,7 +20,14 @@ def find_leaders(instructions: List[CodeStatement]) -> List[int]:
|
|||||||
last is len(instructions)
|
last is len(instructions)
|
||||||
"""
|
"""
|
||||||
leaders: List[int] = [0]
|
leaders: List[int] = [0]
|
||||||
# TODO fill leaders (Lab4b, Exercise 3)
|
for i in range(1,len(instructions)):
|
||||||
|
if(isinstance(instructions[i],AbsoluteJump) or isinstance(instructions[i],ConditionalJump)):
|
||||||
|
# The block ends here and starts just after
|
||||||
|
leaders.append(i+1)
|
||||||
|
elif isinstance(instructions[i],Label) and leaders[-1] != i:
|
||||||
|
# The block starts here
|
||||||
|
leaders.append(i)
|
||||||
|
# Else, ignore
|
||||||
# The final "ret" is also a form of jump
|
# The final "ret" is also a form of jump
|
||||||
leaders.append(len(instructions))
|
leaders.append(len(instructions))
|
||||||
return leaders
|
return leaders
|
||||||
@ -64,9 +71,19 @@ def prepare_chunk(pre_chunk: List[CodeStatement], fdata: FunctionData) -> tuple[
|
|||||||
jump = None
|
jump = None
|
||||||
inner_statements: List[CodeStatement] = pre_chunk
|
inner_statements: List[CodeStatement] = pre_chunk
|
||||||
# Extract the first instruction from inner_statements if it is a label, or create a fresh one
|
# Extract the first instruction from inner_statements if it is a label, or create a fresh one
|
||||||
raise NotImplementedError() # TODO (Lab4b, Exercise 3)
|
firstStat = inner_statements.pop(0)
|
||||||
|
if(isinstance(firstStat, Label)):
|
||||||
|
label = firstStat
|
||||||
|
else:
|
||||||
|
inner_statements = [firstStat]+inner_statements
|
||||||
|
label = fdata.fresh_label(fdata._name)
|
||||||
# Extract the last instruction from inner_statements if it is a jump, or do nothing
|
# Extract the last instruction from inner_statements if it is a jump, or do nothing
|
||||||
raise NotImplementedError() # TODO (Lab4b, Exercise 3)
|
if(inner_statements != []):
|
||||||
|
lastStat = inner_statements.pop()
|
||||||
|
if(isinstance(lastStat, ConditionalJump) or isinstance(lastStat, AbsoluteJump)):
|
||||||
|
jump = lastStat
|
||||||
|
else:
|
||||||
|
inner_statements += [lastStat]
|
||||||
# Check that there is no other label or jump left in inner_statements
|
# Check that there is no other label or jump left in inner_statements
|
||||||
l: List[BlockInstr] = []
|
l: List[BlockInstr] = []
|
||||||
for i in inner_statements:
|
for i in inner_statements:
|
||||||
|
|||||||
@ -23,10 +23,32 @@ def linearize(cfg) -> List[Statement]:
|
|||||||
"""
|
"""
|
||||||
Linearize the given control flow graph as a list of instructions.
|
Linearize the given control flow graph as a list of instructions.
|
||||||
"""
|
"""
|
||||||
# TODO (Lab 4b, Exercise 5)
|
|
||||||
l: List[Statement] = [] # Linearized CFG
|
l: List[Statement] = [] # Linearized CFG
|
||||||
blocks: List[Block] = ordered_blocks_list(cfg)
|
blocks: List[Block] = ordered_blocks_list(cfg)
|
||||||
for j, block in enumerate(blocks):
|
|
||||||
|
labdict = {}
|
||||||
|
# We make the label dictionary
|
||||||
|
for j,block in enumerate(blocks):
|
||||||
|
labdict[block.get_label()] = block
|
||||||
|
|
||||||
|
while blocks != []:
|
||||||
|
block = blocks[0]
|
||||||
|
if(l != [] and isinstance(l[-1],AbsoluteJump)):
|
||||||
|
ll : AbsoluteJump = l[-1]
|
||||||
|
# We try to find the next jump according to that.
|
||||||
|
try:
|
||||||
|
# If we find the instruction
|
||||||
|
b = labdict[ll.label]
|
||||||
|
if b in blocks:
|
||||||
|
# We remove the jump instruction and we select the block to use
|
||||||
|
l.pop()
|
||||||
|
block = b
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# We remove the block we used
|
||||||
|
blocks.remove(block)
|
||||||
|
|
||||||
# 1. Add the label of the block to the linearization
|
# 1. Add the label of the block to the linearization
|
||||||
l.append(block.get_label())
|
l.append(block.get_label())
|
||||||
# 2. Add the body of the block to the linearization
|
# 2. Add the body of the block to the linearization
|
||||||
|
|||||||
@ -75,7 +75,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
|
|
||||||
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
||||||
# true is 1 false is 0
|
# true is 1 false is 0
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
if(ctx.getText() == "true"):
|
||||||
|
val = Operands.Immediate(1)
|
||||||
|
else:
|
||||||
|
val = Operands.Immediate(0)
|
||||||
|
self._current_function.add_instruction(RiscV.li(dtemp,val))
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
||||||
try:
|
try:
|
||||||
@ -97,13 +103,52 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
|
|
||||||
def visitAdditiveExpr(self, ctx) -> Operands.Temporary:
|
def visitAdditiveExpr(self, ctx) -> Operands.Temporary:
|
||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
raise NotImplementedError() # TODO (Exercise 2)
|
if self._debug:
|
||||||
|
print("additive expression, between:",
|
||||||
|
Trees.toStringTree(ctx.expr(0), None, self._parser),
|
||||||
|
"and",
|
||||||
|
Trees.toStringTree(ctx.expr(1), None, self._parser))
|
||||||
|
ltemp = self.visit(ctx.expr(0))
|
||||||
|
rtemp = self.visit(ctx.expr(1))
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
if(ctx.myop.type==MiniCParser.PLUS):
|
||||||
|
self._current_function.add_instruction(RiscV.add(dtemp,ltemp,rtemp))
|
||||||
|
elif(ctx.myop.type==MiniCParser.MINUS):
|
||||||
|
self._current_function.add_instruction(RiscV.sub(dtemp,ltemp,rtemp))
|
||||||
|
else:
|
||||||
|
raise MiniCInternalError("Unknown additive operator from the parser:",ctx.myop)
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitOrExpr(self, ctx) -> Operands.Temporary:
|
def visitOrExpr(self, ctx) -> Operands.Temporary:
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
if self._debug:
|
||||||
|
print("or expression, between:",
|
||||||
|
Trees.toStringTree(ctx.expr(0), None, self._parser),
|
||||||
|
"and",
|
||||||
|
Trees.toStringTree(ctx.expr(1), None, self._parser))
|
||||||
|
ltemp = self.visit(ctx.expr(0))
|
||||||
|
rtemp = self.visit(ctx.expr(1))
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
# We could do only two instructions with slt
|
||||||
|
d0temp = self._current_function.fdata.fresh_tmp()
|
||||||
|
d1temp = self._current_function.fdata.fresh_tmp()
|
||||||
|
self._current_function.add_instruction(RiscV.add(d0temp,ltemp,rtemp))
|
||||||
|
self._current_function.add_instruction(RiscV.mul(d1temp,ltemp,rtemp))
|
||||||
|
self._current_function.add_instruction(RiscV.sub(d0temp,d0temp,d1temp))
|
||||||
|
return d0temp
|
||||||
|
|
||||||
def visitAndExpr(self, ctx) -> Operands.Temporary:
|
def visitAndExpr(self, ctx) -> Operands.Temporary:
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
if self._debug:
|
||||||
|
print("or expression, between:",
|
||||||
|
Trees.toStringTree(ctx.expr(0), None, self._parser),
|
||||||
|
"and",
|
||||||
|
Trees.toStringTree(ctx.expr(1), None, self._parser))
|
||||||
|
ltemp = self.visit(ctx.expr(0))
|
||||||
|
rtemp = self.visit(ctx.expr(1))
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
self._current_function.add_instruction(RiscV.mul(dtemp,ltemp,rtemp))
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
||||||
return self.visitRelationalExpr(ctx)
|
return self.visitRelationalExpr(ctx)
|
||||||
@ -115,18 +160,63 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print("relational expression:")
|
print("relational expression:")
|
||||||
print(Trees.toStringTree(ctx, None, self._parser))
|
print(Trees.toStringTree(ctx, None, self._parser))
|
||||||
print("Condition:", c)
|
print("Condition:", c)
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
ltemp = self.visit(ctx.expr(0))
|
||||||
|
rtemp = self.visit(ctx.expr(1))
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
endlabel = self._current_function.fdata.fresh_label("ifverified")
|
||||||
|
|
||||||
|
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(1)))
|
||||||
|
self._current_function.add_comment("If the result of the comparison is true, branch")
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(endlabel,ltemp,Operands.Condition(ctx.myop.type),rtemp))
|
||||||
|
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(0)))
|
||||||
|
self._current_function.add_instruction(RiscV.jump(endlabel))
|
||||||
|
self._current_function.add_label(endlabel)
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
||||||
raise NotImplementedError() # TODO (Exercise 8)
|
|
||||||
|
ltemp = self.visit(ctx.expr(0))
|
||||||
|
rtemp = self.visit(ctx.expr(1))
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
|
||||||
|
if(ctx.myop.type==MiniCParser.MULT):
|
||||||
|
self._current_function.add_instruction(RiscV.mul(dtemp,ltemp,rtemp))
|
||||||
|
else:
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(div_by_zero_lbl,rtemp,Operands.Condition('beq'),Operands.ZERO))
|
||||||
|
if(ctx.myop.type==MiniCParser.DIV):
|
||||||
|
self._current_function.add_instruction(RiscV.div(dtemp,ltemp,rtemp))
|
||||||
|
elif(ctx.myop.type==MiniCParser.MOD):
|
||||||
|
self._current_function.add_instruction(RiscV.rem(dtemp,ltemp,rtemp))
|
||||||
|
else:
|
||||||
|
raise MiniCInternalError("Unknown multiplicative operator from the parser:",ctx.myop)
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitNotExpr(self, ctx) -> Operands.Temporary:
|
def visitNotExpr(self, ctx) -> Operands.Temporary:
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
if self._debug:
|
||||||
|
print("unitary not expression on expression:",
|
||||||
|
Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||||
|
vtemp = self.visit(ctx.expr())
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
|
||||||
|
# (not a) is (1 xor a)
|
||||||
|
self._current_function.add_instruction(RiscV.li(dtemp,Operands.Immediate(1)))
|
||||||
|
self._current_function.add_instruction(RiscV.xor(dtemp,dtemp,vtemp))
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
|
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
|
||||||
raise NotImplementedError("unaryminusexpr") # TODO (Exercise 2)
|
if self._debug:
|
||||||
|
print("unitary minus expression on expression:",
|
||||||
|
Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||||
|
vtemp = self.visit(ctx.expr())
|
||||||
|
# Getting a fresh temporary for the result of the opreation
|
||||||
|
dtemp = self._current_function.fdata.fresh_tmp()
|
||||||
|
self._current_function.add_instruction(RiscV.sub(dtemp,Operands.ZERO,vtemp))
|
||||||
|
return dtemp
|
||||||
|
|
||||||
def visitProgRule(self, ctx) -> None:
|
def visitProgRule(self, ctx) -> None:
|
||||||
self.visitChildren(ctx)
|
self.visitChildren(ctx)
|
||||||
@ -158,9 +248,25 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
def visitIfStat(self, ctx) -> None:
|
def visitIfStat(self, ctx) -> None:
|
||||||
if self._debug:
|
if self._debug:
|
||||||
print("if statement")
|
print("if statement")
|
||||||
end_if_label = self._current_function.fdata.fresh_label("end_if")
|
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
lendif = self._current_function.fdata.fresh_label("endif")
|
||||||
self._current_function.add_label(end_if_label)
|
if(ctx.else_block!=None):
|
||||||
|
lelse = self._current_function.fdata.fresh_label("else")
|
||||||
|
dval = self.visit(ctx.expr())
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(lelse, dval, Operands.Condition('beq'), Operands.ZERO))
|
||||||
|
self.visit(ctx.then_block)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(lendif))
|
||||||
|
self._current_function.add_label(lelse)
|
||||||
|
self.visit(ctx.else_block)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(lendif))
|
||||||
|
self._current_function.add_label(lendif)
|
||||||
|
else:
|
||||||
|
dval = self.visit(ctx.expr())
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(lendif, dval, Operands.Condition('beq'), Operands.ZERO))
|
||||||
|
self.visit(ctx.then_block)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(lendif))
|
||||||
|
self._current_function.add_label(lendif)
|
||||||
|
|
||||||
|
|
||||||
def visitWhileStat(self, ctx) -> None:
|
def visitWhileStat(self, ctx) -> None:
|
||||||
if self._debug:
|
if self._debug:
|
||||||
@ -168,7 +274,37 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print(Trees.toStringTree(ctx.expr(), None, self._parser))
|
print(Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||||
print("and block is:")
|
print("and block is:")
|
||||||
print(Trees.toStringTree(ctx.stat_block(), None, self._parser))
|
print(Trees.toStringTree(ctx.stat_block(), None, self._parser))
|
||||||
raise NotImplementedError() # TODO (Exercise 5)
|
ltest = self._current_function.fdata.fresh_label("testcond")
|
||||||
|
lendwhile = self._current_function.fdata.fresh_label("endwhile")
|
||||||
|
self._current_function.add_instruction(RiscV.jump(ltest))
|
||||||
|
self._current_function.add_label(ltest)
|
||||||
|
dcond = self.visit(ctx.expr())
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(lendwhile, dcond, Operands.Condition('beq'), Operands.ZERO))
|
||||||
|
self.visit(ctx.body)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(ltest))
|
||||||
|
self._current_function.add_label(lendwhile)
|
||||||
|
|
||||||
|
def visitForStat(self, ctx):
|
||||||
|
init_stat = ctx.init_stat
|
||||||
|
cond = ctx.cond
|
||||||
|
loop_stat = ctx.loop_stat
|
||||||
|
body = ctx.stat_block()
|
||||||
|
|
||||||
|
ltest = self._current_function.fdata.fresh_label("testcond")
|
||||||
|
lendfor = self._current_function.fdata.fresh_label("endfor")
|
||||||
|
|
||||||
|
if(init_stat != None):
|
||||||
|
self.visit(init_stat)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(ltest))
|
||||||
|
self._current_function.add_label(ltest)
|
||||||
|
dcond = self.visit(ctx.expr())
|
||||||
|
self._current_function.add_instruction(RiscV.conditional_jump(lendfor, dcond, Operands.Condition('beq'), Operands.ZERO))
|
||||||
|
self.visit(body)
|
||||||
|
if(loop_stat != None):
|
||||||
|
self.visit(loop_stat)
|
||||||
|
self._current_function.add_instruction(RiscV.jump(ltest))
|
||||||
|
self._current_function.add_label(lendfor)
|
||||||
|
|
||||||
# visit statements
|
# visit statements
|
||||||
|
|
||||||
def visitPrintlnintStat(self, ctx) -> None:
|
def visitPrintlnintStat(self, ctx) -> None:
|
||||||
|
|||||||
32
MiniC/TP04/tests/students/forTests.c
Normal file
32
MiniC/TP04/tests/students/forTests.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int x;
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
for(;x<4;){
|
||||||
|
println_int(x);
|
||||||
|
x = x+1;
|
||||||
|
}
|
||||||
|
x = 69;
|
||||||
|
for(x=42;false;){
|
||||||
|
}
|
||||||
|
println_int(x);
|
||||||
|
for(x = 100;x>=4;x = x/2){
|
||||||
|
println_int(x+4);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXITCODE 0
|
||||||
|
// EXPECTED
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
|
// 2
|
||||||
|
// 3
|
||||||
|
// 42
|
||||||
|
// 104
|
||||||
|
// 54
|
||||||
|
// 29
|
||||||
|
// 16
|
||||||
|
// 10
|
||||||
31
MiniC/TP04/tests/students/nestedFor.c
Normal file
31
MiniC/TP04/tests/students/nestedFor.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int x,y,z,t;
|
||||||
|
|
||||||
|
t = 0;
|
||||||
|
x = 0;
|
||||||
|
for(x=0;x<10;x=x+1){
|
||||||
|
y = 0;
|
||||||
|
for(y=0;y<4;){
|
||||||
|
t = t + y;
|
||||||
|
z = 1;
|
||||||
|
for(z=1;z<13;z=2*z){
|
||||||
|
t = t + 1;
|
||||||
|
}
|
||||||
|
y = y + 1;
|
||||||
|
}
|
||||||
|
for(;y<7;y=y+2){
|
||||||
|
t = t + (y/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println_int(x);
|
||||||
|
println_int(y);
|
||||||
|
println_int(z);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 10
|
||||||
|
// 8
|
||||||
|
// 16
|
||||||
48
MiniC/TP04/tests/students/nestedIfs.c
Normal file
48
MiniC/TP04/tests/students/nestedIfs.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int x,y,z;
|
||||||
|
|
||||||
|
if (10 == 10) {
|
||||||
|
println_int(44);
|
||||||
|
if (10 == 11) {
|
||||||
|
println_int(75);
|
||||||
|
} else if (10 == 10) {
|
||||||
|
println_int(42);
|
||||||
|
if (9 == 10) {
|
||||||
|
println_int(12);
|
||||||
|
} else if (10 == 9) {
|
||||||
|
println_int(15);
|
||||||
|
} else {
|
||||||
|
println_int(13);
|
||||||
|
}
|
||||||
|
println_int(19);
|
||||||
|
} else {
|
||||||
|
println_int(31);
|
||||||
|
}
|
||||||
|
println_int(25);
|
||||||
|
} else if (10 == 10) {
|
||||||
|
println_int(2);
|
||||||
|
} else {
|
||||||
|
println_int(89);
|
||||||
|
if (10 == 10) {
|
||||||
|
println_int(68);
|
||||||
|
} else if (10 == 10) {
|
||||||
|
println_int(46);
|
||||||
|
} else {
|
||||||
|
println_int(22);
|
||||||
|
}
|
||||||
|
println_int(43);
|
||||||
|
}
|
||||||
|
println_int(14);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 44
|
||||||
|
// 42
|
||||||
|
// 13
|
||||||
|
// 19
|
||||||
|
// 25
|
||||||
|
// 14
|
||||||
34
MiniC/TP04/tests/students/nestedWhile.c
Normal file
34
MiniC/TP04/tests/students/nestedWhile.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int x,y,z,t;
|
||||||
|
|
||||||
|
t = 0;
|
||||||
|
x = 0;
|
||||||
|
while(x<10){
|
||||||
|
y = 0;
|
||||||
|
while(y<4){
|
||||||
|
t = t + y;
|
||||||
|
z = 1;
|
||||||
|
while(z<13){
|
||||||
|
t = t + 1;
|
||||||
|
z = 2 * z;
|
||||||
|
}
|
||||||
|
y = y + 1;
|
||||||
|
}
|
||||||
|
while(y<7){
|
||||||
|
t = t + (y/2);
|
||||||
|
y = y + 2;
|
||||||
|
}
|
||||||
|
x = x + 1;
|
||||||
|
}
|
||||||
|
println_int(x);
|
||||||
|
println_int(y);
|
||||||
|
println_int(z);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 10
|
||||||
|
// 8
|
||||||
|
// 16
|
||||||
64
MiniC/TP04/tests/students/operators/relations/testEq.c
Normal file
64
MiniC/TP04/tests/students/operators/relations/testEq.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing ==
|
||||||
|
if( 11 == 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(57);
|
||||||
|
}
|
||||||
|
if( -11 == 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(58);
|
||||||
|
}
|
||||||
|
if( 11 == -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(59);
|
||||||
|
}
|
||||||
|
if( -11 == -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(60);
|
||||||
|
}
|
||||||
|
if( 11 == 11 ){
|
||||||
|
println_int(61);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 == -22 ){
|
||||||
|
println_int(62);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( true == true ){
|
||||||
|
println_int(63);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( true == false ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(64);
|
||||||
|
}
|
||||||
|
if( false == false ){
|
||||||
|
println_int(65);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 57
|
||||||
|
// 58
|
||||||
|
// 59
|
||||||
|
// 60
|
||||||
|
// 61
|
||||||
|
// 62
|
||||||
|
// 63
|
||||||
|
// 64
|
||||||
|
// 65
|
||||||
94
MiniC/TP04/tests/students/operators/relations/testGeq.c
Normal file
94
MiniC/TP04/tests/students/operators/relations/testGeq.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing >=
|
||||||
|
if( 11 >= 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(29);
|
||||||
|
}
|
||||||
|
if( -11 >= 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(30);
|
||||||
|
}
|
||||||
|
if( 11 >= -22 ){
|
||||||
|
println_int(31);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 >= -22 ){
|
||||||
|
println_int(32);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 >= 11 ){
|
||||||
|
println_int(33);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 >= -11 ){
|
||||||
|
println_int(34);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 >= 11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(35);
|
||||||
|
}
|
||||||
|
if( -22 >= -11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(36);
|
||||||
|
}
|
||||||
|
if( 11 >= 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(37);
|
||||||
|
}
|
||||||
|
if( -11 >= 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(38);
|
||||||
|
}
|
||||||
|
if( 11 >= -22 ){
|
||||||
|
println_int(39);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 >= -22 ){
|
||||||
|
println_int(40);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 >= 22 ){
|
||||||
|
println_int(41);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 >= -22 ){
|
||||||
|
println_int(42);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 29
|
||||||
|
// 30
|
||||||
|
// 31
|
||||||
|
// 32
|
||||||
|
// 33
|
||||||
|
// 34
|
||||||
|
// 35
|
||||||
|
// 36
|
||||||
|
// 37
|
||||||
|
// 38
|
||||||
|
// 39
|
||||||
|
// 40
|
||||||
|
// 41
|
||||||
|
// 42
|
||||||
93
MiniC/TP04/tests/students/operators/relations/testGt.c
Normal file
93
MiniC/TP04/tests/students/operators/relations/testGt.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing >
|
||||||
|
if( 11 > 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(43);
|
||||||
|
}
|
||||||
|
if( -11 > 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(44);
|
||||||
|
}
|
||||||
|
if( 11 > -22 ){
|
||||||
|
println_int(45);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 > -22 ){
|
||||||
|
println_int(46);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 > 11 ){
|
||||||
|
println_int(47);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 > -11 ){
|
||||||
|
println_int(48);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 > 11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(49);
|
||||||
|
}
|
||||||
|
if( -22 > -11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(50);
|
||||||
|
}
|
||||||
|
if( 11 > 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(51);
|
||||||
|
}
|
||||||
|
if( -11 > 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(52);
|
||||||
|
}
|
||||||
|
if( 11 > -22 ){
|
||||||
|
println_int(53);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 > -22 ){
|
||||||
|
println_int(54);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 22 > 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(55);
|
||||||
|
}
|
||||||
|
if( -22 > -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(56);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 43
|
||||||
|
// 44
|
||||||
|
// 45
|
||||||
|
// 46
|
||||||
|
// 47
|
||||||
|
// 48
|
||||||
|
// 49
|
||||||
|
// 50
|
||||||
|
// 51
|
||||||
|
// 52
|
||||||
|
// 53
|
||||||
|
// 54
|
||||||
|
// 55
|
||||||
|
// 56
|
||||||
94
MiniC/TP04/tests/students/operators/relations/testLeq.c
Normal file
94
MiniC/TP04/tests/students/operators/relations/testLeq.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing <=
|
||||||
|
if( 11 <= 22 ){
|
||||||
|
println_int(1);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 <= 22 ){
|
||||||
|
println_int(2);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 <= -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(3);
|
||||||
|
}
|
||||||
|
if( -11 <= -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(4);
|
||||||
|
}
|
||||||
|
if( 22 <= 11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(5);
|
||||||
|
}
|
||||||
|
if( 22 <= -11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(6);
|
||||||
|
}
|
||||||
|
if( -22 <= 11 ){
|
||||||
|
println_int(7);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 <= -11 ){
|
||||||
|
println_int(8);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 <= 22 ){
|
||||||
|
println_int(9);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 <= 22 ){
|
||||||
|
println_int(10);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 <= -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(11);
|
||||||
|
}
|
||||||
|
if( -11 <= -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(12);
|
||||||
|
}
|
||||||
|
if( 22 <= 22 ){
|
||||||
|
println_int(13);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 <= -22 ){
|
||||||
|
println_int(14);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 1
|
||||||
|
// 2
|
||||||
|
// 3
|
||||||
|
// 4
|
||||||
|
// 5
|
||||||
|
// 6
|
||||||
|
// 7
|
||||||
|
// 8
|
||||||
|
// 9
|
||||||
|
// 10
|
||||||
|
// 11
|
||||||
|
// 12
|
||||||
|
// 13
|
||||||
|
// 14
|
||||||
94
MiniC/TP04/tests/students/operators/relations/testLt.c
Normal file
94
MiniC/TP04/tests/students/operators/relations/testLt.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing <
|
||||||
|
if( 11 < 22 ){
|
||||||
|
println_int(15);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 < 22 ){
|
||||||
|
println_int(16);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 < -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(17);
|
||||||
|
}
|
||||||
|
if( -11 < -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(18);
|
||||||
|
}
|
||||||
|
if( 22 < 11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(19);
|
||||||
|
}
|
||||||
|
if( 22 < -11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(20);
|
||||||
|
}
|
||||||
|
if( -22 < 11 ){
|
||||||
|
println_int(21);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -22 < -11 ){
|
||||||
|
println_int(22);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 < 22 ){
|
||||||
|
println_int(23);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 < 22 ){
|
||||||
|
println_int(24);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 < -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(25);
|
||||||
|
}
|
||||||
|
if( -11 < -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(26);
|
||||||
|
}
|
||||||
|
if( 22 < 22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(27);
|
||||||
|
}
|
||||||
|
if( -22 < -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(28);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 15
|
||||||
|
// 16
|
||||||
|
// 17
|
||||||
|
// 18
|
||||||
|
// 19
|
||||||
|
// 20
|
||||||
|
// 21
|
||||||
|
// 22
|
||||||
|
// 23
|
||||||
|
// 24
|
||||||
|
// 25
|
||||||
|
// 26
|
||||||
|
// 27
|
||||||
|
// 28
|
||||||
64
MiniC/TP04/tests/students/operators/relations/testNeq.c
Normal file
64
MiniC/TP04/tests/students/operators/relations/testNeq.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Testing !=
|
||||||
|
if( 11 != 22 ){
|
||||||
|
println_int(66);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 != 22 ){
|
||||||
|
println_int(67);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 != -22 ){
|
||||||
|
println_int(68);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( -11 != -22 ){
|
||||||
|
println_int(69);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( 11 != 11 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(70);
|
||||||
|
}
|
||||||
|
if( -22 != -22 ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(71);
|
||||||
|
}
|
||||||
|
if( true != true ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(72);
|
||||||
|
}
|
||||||
|
if( true != false ){
|
||||||
|
println_int(73);
|
||||||
|
}else{
|
||||||
|
println_int(420);
|
||||||
|
}
|
||||||
|
if( false != false ){
|
||||||
|
println_int(420);
|
||||||
|
}else{
|
||||||
|
println_int(74);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 66
|
||||||
|
// 67
|
||||||
|
// 68
|
||||||
|
// 69
|
||||||
|
// 70
|
||||||
|
// 71
|
||||||
|
// 72
|
||||||
|
// 73
|
||||||
|
// 74
|
||||||
26
MiniC/TP04/tests/students/operators/testAddClause.c
Normal file
26
MiniC/TP04/tests/students/operators/testAddClause.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y,z;
|
||||||
|
|
||||||
|
x = 12;
|
||||||
|
y = -21;
|
||||||
|
z = 14;
|
||||||
|
|
||||||
|
println_int(x + y);
|
||||||
|
println_int(y + z);
|
||||||
|
println_int(z + x);
|
||||||
|
println_int(z + y);
|
||||||
|
println_int(y + x);
|
||||||
|
println_int(x + z);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// -9
|
||||||
|
// -7
|
||||||
|
// 26
|
||||||
|
// -7
|
||||||
|
// -9
|
||||||
|
// 26
|
||||||
26
MiniC/TP04/tests/students/operators/testAndClause.c
Normal file
26
MiniC/TP04/tests/students/operators/testAndClause.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
bool x,y;
|
||||||
|
|
||||||
|
x = true;
|
||||||
|
y = false;
|
||||||
|
|
||||||
|
println_bool(x);
|
||||||
|
println_bool(y);
|
||||||
|
println_bool(x && x);
|
||||||
|
println_bool(y && x);
|
||||||
|
println_bool(x && y);
|
||||||
|
println_bool(y && y);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 1
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
|
// 0
|
||||||
|
// 0
|
||||||
|
// 0
|
||||||
24
MiniC/TP04/tests/students/operators/testDivClause.c
Normal file
24
MiniC/TP04/tests/students/operators/testDivClause.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
int u,v;
|
||||||
|
|
||||||
|
x = 3;
|
||||||
|
y = -4;
|
||||||
|
u = 41;
|
||||||
|
v = -31;
|
||||||
|
|
||||||
|
println_int(u / x);
|
||||||
|
println_int(v / x);
|
||||||
|
println_int(u / y);
|
||||||
|
println_int(v / y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 13
|
||||||
|
// -10
|
||||||
|
// -10
|
||||||
|
// 7
|
||||||
25
MiniC/TP04/tests/students/operators/testDivZero.c
Normal file
25
MiniC/TP04/tests/students/operators/testDivZero.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
int u,v;
|
||||||
|
|
||||||
|
x = 3;
|
||||||
|
y = 0;
|
||||||
|
u = 41;
|
||||||
|
v = 0;
|
||||||
|
|
||||||
|
println_int(u / x);
|
||||||
|
println_int(v / x);
|
||||||
|
println_int(u / y);
|
||||||
|
println_int(v / y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 13
|
||||||
|
// 0
|
||||||
|
// Division by 0
|
||||||
|
// SKIP TEST EXPECTED
|
||||||
|
// EXECCODE 1
|
||||||
26
MiniC/TP04/tests/students/operators/testMinusClause.c
Normal file
26
MiniC/TP04/tests/students/operators/testMinusClause.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y,z;
|
||||||
|
|
||||||
|
x = 12;
|
||||||
|
y = -21;
|
||||||
|
z = 14;
|
||||||
|
|
||||||
|
println_int(x - y);
|
||||||
|
println_int(y - z);
|
||||||
|
println_int(z - x);
|
||||||
|
println_int(z - y);
|
||||||
|
println_int(y - x);
|
||||||
|
println_int(x - z);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 33
|
||||||
|
// -35
|
||||||
|
// 2
|
||||||
|
// 35
|
||||||
|
// -33
|
||||||
|
// -2
|
||||||
24
MiniC/TP04/tests/students/operators/testModClause.c
Normal file
24
MiniC/TP04/tests/students/operators/testModClause.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
int u,v;
|
||||||
|
|
||||||
|
x = 3;
|
||||||
|
y = -4;
|
||||||
|
u = 41;
|
||||||
|
v = -31;
|
||||||
|
|
||||||
|
println_int(u % x);
|
||||||
|
println_int(v % x);
|
||||||
|
println_int(u % y);
|
||||||
|
println_int(v % y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 2
|
||||||
|
// -1
|
||||||
|
// 1
|
||||||
|
// -3
|
||||||
25
MiniC/TP04/tests/students/operators/testModZero.c
Normal file
25
MiniC/TP04/tests/students/operators/testModZero.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
int u,v;
|
||||||
|
|
||||||
|
x = 3;
|
||||||
|
y = 0;
|
||||||
|
u = 41;
|
||||||
|
v = 0;
|
||||||
|
|
||||||
|
println_int(u % x);
|
||||||
|
println_int(v % x);
|
||||||
|
println_int(u % y);
|
||||||
|
println_int(v % y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 2
|
||||||
|
// 0
|
||||||
|
// Division by 0
|
||||||
|
// SKIP TEST EXPECTED
|
||||||
|
// EXECCODE 1
|
||||||
31
MiniC/TP04/tests/students/operators/testMulClause.c
Normal file
31
MiniC/TP04/tests/students/operators/testMulClause.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y,z,t;
|
||||||
|
|
||||||
|
x = 12;
|
||||||
|
y = -21;
|
||||||
|
z = 14;
|
||||||
|
t = -4;
|
||||||
|
|
||||||
|
println_int(x * y);
|
||||||
|
println_int(y * z);
|
||||||
|
println_int(z * x);
|
||||||
|
println_int(y * t);
|
||||||
|
println_int(z * y);
|
||||||
|
println_int(y * x);
|
||||||
|
println_int(x * z);
|
||||||
|
println_int(t * y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// -252
|
||||||
|
// -294
|
||||||
|
// 168
|
||||||
|
// 84
|
||||||
|
// -294
|
||||||
|
// -252
|
||||||
|
// 168
|
||||||
|
// 84
|
||||||
22
MiniC/TP04/tests/students/operators/testNotClause.c
Normal file
22
MiniC/TP04/tests/students/operators/testNotClause.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
bool x,y;
|
||||||
|
|
||||||
|
x = true;
|
||||||
|
y = false;
|
||||||
|
|
||||||
|
println_bool(x);
|
||||||
|
println_bool(y);
|
||||||
|
println_bool(!x);
|
||||||
|
println_bool(!y);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 1
|
||||||
|
// 0
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
26
MiniC/TP04/tests/students/operators/testOrClause.c
Normal file
26
MiniC/TP04/tests/students/operators/testOrClause.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
bool x,y;
|
||||||
|
|
||||||
|
x = true;
|
||||||
|
y = false;
|
||||||
|
|
||||||
|
println_bool(x);
|
||||||
|
println_bool(y);
|
||||||
|
println_bool(x || x);
|
||||||
|
println_bool(y || x);
|
||||||
|
println_bool(x || y);
|
||||||
|
println_bool(y || y);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 1
|
||||||
|
// 0
|
||||||
|
// 1
|
||||||
|
// 1
|
||||||
|
// 1
|
||||||
|
// 0
|
||||||
25
MiniC/TP04/tests/students/operators/testUMinusClause.c
Normal file
25
MiniC/TP04/tests/students/operators/testUMinusClause.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
x = 12;
|
||||||
|
y = -21;
|
||||||
|
|
||||||
|
println_int(x);
|
||||||
|
println_int(y);
|
||||||
|
println_int(-x);
|
||||||
|
println_int(-y);
|
||||||
|
println_int(x + (-y));
|
||||||
|
println_int((-x) - (-y));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 12
|
||||||
|
// -21
|
||||||
|
// -12
|
||||||
|
// 21
|
||||||
|
// 33
|
||||||
|
// -33
|
||||||
37
MiniC/TP04/tests/students/testTooManyVariables.c
Normal file
37
MiniC/TP04/tests/students/testTooManyVariables.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;
|
||||||
|
|
||||||
|
a = 5;
|
||||||
|
b = 2;
|
||||||
|
c = a + b;
|
||||||
|
d = a - b;
|
||||||
|
e = c + d;
|
||||||
|
f = d + e;
|
||||||
|
g = c - e;
|
||||||
|
h = f + g;
|
||||||
|
i = h - e;
|
||||||
|
j = d + g;
|
||||||
|
k = g + h;
|
||||||
|
l = c - d;
|
||||||
|
m = i + j;
|
||||||
|
n = j + k;
|
||||||
|
o = k + k;
|
||||||
|
p = j - e;
|
||||||
|
q = c + k;
|
||||||
|
r = d + e;
|
||||||
|
s = c + b;
|
||||||
|
t = l - p;
|
||||||
|
u = d + s;
|
||||||
|
v = m - r;
|
||||||
|
w = c + u;
|
||||||
|
x = k - m;
|
||||||
|
y = g + r;
|
||||||
|
z = l + n;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
22
MiniC/TP04/tests/students/whileClauseSyntax.c
Normal file
22
MiniC/TP04/tests/students/whileClauseSyntax.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "printlib.h"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int x,y,z;
|
||||||
|
|
||||||
|
x = 42;
|
||||||
|
y = 0;
|
||||||
|
while(y<x){
|
||||||
|
y = y+1;
|
||||||
|
}
|
||||||
|
println_int(y);
|
||||||
|
y = 0;
|
||||||
|
while(y<x)
|
||||||
|
y = y+5;
|
||||||
|
println_int(y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECTED
|
||||||
|
// 42
|
||||||
|
// 45
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ Functions to convert a CFG into SSA Form.
|
|||||||
from typing import List, Dict, Set
|
from typing import List, Dict, Set
|
||||||
from Lib.CFG import Block, CFG
|
from Lib.CFG import Block, CFG
|
||||||
from Lib.Operands import Renamer
|
from Lib.Operands import Renamer
|
||||||
from Lib.Statement import Instruction
|
from Lib.Statement import Instruction,Label,Operand
|
||||||
from Lib.PhiNode import PhiNode
|
from Lib.PhiNode import PhiNode
|
||||||
from Lib.Dominators import computeDom, computeDT, computeDF
|
from Lib.Dominators import computeDom, computeDT, computeDF
|
||||||
|
|
||||||
@ -25,8 +25,13 @@ def insertPhis(cfg: CFG, DF: Dict[Block, Set[Block]]) -> None:
|
|||||||
d = queue.pop(0)
|
d = queue.pop(0)
|
||||||
for b in DF[d]:
|
for b in DF[d]:
|
||||||
if b not in has_phi:
|
if b not in has_phi:
|
||||||
# TODO add a phi node in block `b` (Lab 5a, Exercise 4)
|
params : Dict[Label,Operand] = {}
|
||||||
raise NotImplementedError("insertPhis")
|
for bi in (set(b.get_in())):
|
||||||
|
params[bi.get_label()] = var
|
||||||
|
phi = PhiNode(var,params)
|
||||||
|
b._phis.append(phi)
|
||||||
|
queue.append(b)
|
||||||
|
has_phi.add(b)
|
||||||
|
|
||||||
|
|
||||||
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
|
def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Block) -> None:
|
||||||
@ -43,18 +48,19 @@ def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Blo
|
|||||||
for i in succ._phis:
|
for i in succ._phis:
|
||||||
assert (isinstance(i, PhiNode))
|
assert (isinstance(i, PhiNode))
|
||||||
i.rename_from(renamer, b.get_label())
|
i.rename_from(renamer, b.get_label())
|
||||||
# TODO recursive call(s) of rename_block (Lab 5a, Exercise 5)
|
for dtsucc in DT[b]:
|
||||||
|
rename_block(cfg,DT,renamer, dtsucc)
|
||||||
|
|
||||||
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
|
def rename_variables(cfg: CFG, DT: Dict[Block, Set[Block]]) -> None:
|
||||||
"""
|
"""
|
||||||
Rename variables in the CFG, to transform `temp_x = φ(temp_x, ..., temp_x)`
|
Rename variables in the CFG, to transform `temp_x = φ(temp_x, ..., temp_x)`
|
||||||
into `temp_x = φ(temp_0, ... temp_n)`.
|
into `temp_x = φ(temp_0, ..., temp_n)`.
|
||||||
|
|
||||||
This is an helper function called during SSA entry.
|
This is an helper function called during SSA entry.
|
||||||
"""
|
"""
|
||||||
renamer = Renamer(cfg.fdata._pool)
|
renamer = Renamer(cfg.fdata._pool)
|
||||||
# TODO initial call(s) to rename_block (Lab 5a, Exercise 5)
|
for etr in cfg.get_entries():
|
||||||
|
rename_block(cfg,DT,renamer,etr)
|
||||||
|
|
||||||
|
|
||||||
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
||||||
@ -66,5 +72,9 @@ def enter_ssa(cfg: CFG, dom_graphs=False, basename="prog") -> None:
|
|||||||
`dom_graphs` indicates if we have to print the domination graphs.
|
`dom_graphs` indicates if we have to print the domination graphs.
|
||||||
`basename` is used for the names of the produced graphs.
|
`basename` is used for the names of the produced graphs.
|
||||||
"""
|
"""
|
||||||
# TODO implement this function (Lab 5a, Exercise 2)
|
# Compute the DF
|
||||||
raise NotImplementedError("enter_ssa")
|
dom = computeDom(cfg)
|
||||||
|
dt = computeDT(cfg,dom,dom_graphs,basename)
|
||||||
|
df = computeDF(cfg,dom,dt,dom_graphs, basename)
|
||||||
|
insertPhis(cfg,df)
|
||||||
|
rename_variables(cfg,dt)
|
||||||
|
|||||||
@ -4,6 +4,7 @@ Functions to convert a CFG out of SSA Form.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import cast, List, Set, Tuple
|
from typing import cast, List, Set, Tuple
|
||||||
|
from Lib.Errors import MiniCInternalError
|
||||||
from Lib import RiscV
|
from Lib import RiscV
|
||||||
from Lib.Graphes import DiGraph
|
from Lib.Graphes import DiGraph
|
||||||
from Lib.CFG import Block, BlockInstr, CFG
|
from Lib.CFG import Block, BlockInstr, CFG
|
||||||
@ -24,8 +25,10 @@ def generate_moves_from_phis(phis: List[PhiNode], parent: Block) -> List[BlockIn
|
|||||||
This is an helper function called during SSA exit.
|
This is an helper function called during SSA exit.
|
||||||
"""
|
"""
|
||||||
moves: List[BlockInstr] = []
|
moves: List[BlockInstr] = []
|
||||||
# TODO compute 'moves', a list of 'mv' instructions to insert under parent
|
plabel = parent.get_label()
|
||||||
# (Lab 5a, Exercise 6)
|
for phi in phis:
|
||||||
|
if(plabel in phi.used()):
|
||||||
|
moves.append(RiscV.mv(phi.var,phi.used()[plabel]))
|
||||||
return moves
|
return moves
|
||||||
|
|
||||||
|
|
||||||
@ -38,11 +41,34 @@ def exit_ssa(cfg: CFG, is_smart: bool) -> None:
|
|||||||
for b in cfg.get_blocks():
|
for b in cfg.get_blocks():
|
||||||
phis = cast(List[PhiNode], b._phis) # Use cast for Pyright
|
phis = cast(List[PhiNode], b._phis) # Use cast for Pyright
|
||||||
b._phis = [] # Remove all phi nodes in the block
|
b._phis = [] # Remove all phi nodes in the block
|
||||||
|
blabel = b.get_label()
|
||||||
parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
|
parents: List[Block] = b.get_in().copy() # Copy as we modify it by adding blocks
|
||||||
for parent in parents:
|
for p in parents:
|
||||||
moves = generate_moves_from_phis(phis, parent)
|
moves = generate_moves_from_phis(phis, p)
|
||||||
# TODO Add the block containing 'moves' to 'cfg'
|
if(len(moves)==0):
|
||||||
# and update edges and jumps accordingly (Lab 5a, Exercise 6)
|
continue
|
||||||
raise NotImplementedError("exit_ssa")
|
# Creating the block
|
||||||
|
ilabel = cfg.fdata.fresh_label(p.get_label().name+"_to_"+b.get_label().name)
|
||||||
|
i = Block(ilabel,moves,AbsoluteJump(blabel))
|
||||||
|
# Add the block
|
||||||
|
cfg.add_block(i)
|
||||||
|
# Changing the jumps
|
||||||
|
ot = p.get_terminator()
|
||||||
|
if(isinstance(ot,BranchingTerminator)):
|
||||||
|
if(ot.label_then == blabel):
|
||||||
|
ot.label_then = ilabel
|
||||||
|
if(ot.label_else == blabel):
|
||||||
|
ot.label_else = ilabel
|
||||||
|
elif(isinstance(ot,AbsoluteJump)):
|
||||||
|
assert(ot.label == blabel)
|
||||||
|
ot = AbsoluteJump(ilabel)
|
||||||
|
elif(isinstance(ot,Return)):
|
||||||
|
raise MiniCInternalError("Malformed CFG, cannot have a return in a parent block")
|
||||||
|
else:
|
||||||
|
raise MiniCInternalError("I don't know of this terminator type:",type(ot))
|
||||||
|
p.set_terminator(ot) # This instruction might be useless
|
||||||
|
# Moving from p -> b to p -> i -> b
|
||||||
|
cfg.remove_edge(p,b)
|
||||||
|
cfg.add_edge(p,i)
|
||||||
|
cfg.add_edge(i,b)
|
||||||
|
|
||||||
|
|||||||
BIN
TP01/riscv/ex1.riscv
Executable file
BIN
TP01/riscv/ex1.riscv
Executable file
Binary file not shown.
BIN
TP01/riscv/libprint.o
Normal file
BIN
TP01/riscv/libprint.o
Normal file
Binary file not shown.
BIN
TP01/riscv/test_print
Executable file
BIN
TP01/riscv/test_print
Executable file
Binary file not shown.
BIN
TP01/riscv/test_print.o
Normal file
BIN
TP01/riscv/test_print.o
Normal file
Binary file not shown.
BIN
TP01/riscv/test_print.riscv
Executable file
BIN
TP01/riscv/test_print.riscv
Executable file
Binary file not shown.
77
TP02/ariteval/AritLexer.py
Normal file
77
TP02/ariteval/AritLexer.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Generated from Arit.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
# header - mettre les d??clarations globales
|
||||||
|
import sys
|
||||||
|
idTab = {};
|
||||||
|
|
||||||
|
class UnknownIdentifier(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DivByZero(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\6")
|
||||||
|
buf.write("\'\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\3\2\3\2\3\2\3\2")
|
||||||
|
buf.write("\7\2\20\n\2\f\2\16\2\23\13\2\3\2\3\2\3\3\6\3\30\n\3\r")
|
||||||
|
buf.write("\3\16\3\31\3\4\6\4\35\n\4\r\4\16\4\36\3\5\6\5\"\n\5\r")
|
||||||
|
buf.write("\5\16\5#\3\5\3\5\2\2\6\3\3\5\4\7\5\t\6\3\2\5\4\2\f\f\17")
|
||||||
|
buf.write("\17\4\2C\\c|\5\2\13\f\17\17\"\"\2*\2\3\3\2\2\2\2\5\3\2")
|
||||||
|
buf.write("\2\2\2\7\3\2\2\2\2\t\3\2\2\2\3\13\3\2\2\2\5\27\3\2\2\2")
|
||||||
|
buf.write("\7\34\3\2\2\2\t!\3\2\2\2\13\f\7\61\2\2\f\r\7\61\2\2\r")
|
||||||
|
buf.write("\21\3\2\2\2\16\20\n\2\2\2\17\16\3\2\2\2\20\23\3\2\2\2")
|
||||||
|
buf.write("\21\17\3\2\2\2\21\22\3\2\2\2\22\24\3\2\2\2\23\21\3\2\2")
|
||||||
|
buf.write("\2\24\25\b\2\2\2\25\4\3\2\2\2\26\30\t\3\2\2\27\26\3\2")
|
||||||
|
buf.write("\2\2\30\31\3\2\2\2\31\27\3\2\2\2\31\32\3\2\2\2\32\6\3")
|
||||||
|
buf.write("\2\2\2\33\35\4\62;\2\34\33\3\2\2\2\35\36\3\2\2\2\36\34")
|
||||||
|
buf.write("\3\2\2\2\36\37\3\2\2\2\37\b\3\2\2\2 \"\t\4\2\2! \3\2\2")
|
||||||
|
buf.write("\2\"#\3\2\2\2#!\3\2\2\2#$\3\2\2\2$%\3\2\2\2%&\b\5\2\2")
|
||||||
|
buf.write("&\n\3\2\2\2\7\2\21\31\36#\3\b\2\2")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class AritLexer(Lexer):
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
COMMENT = 1
|
||||||
|
ID = 2
|
||||||
|
INT = 3
|
||||||
|
WS = 4
|
||||||
|
|
||||||
|
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
||||||
|
|
||||||
|
modeNames = [ "DEFAULT_MODE" ]
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>",
|
||||||
|
]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>",
|
||||||
|
"COMMENT", "ID", "INT", "WS" ]
|
||||||
|
|
||||||
|
ruleNames = [ "COMMENT", "ID", "INT", "WS" ]
|
||||||
|
|
||||||
|
grammarFileName = "Arit.g4"
|
||||||
|
|
||||||
|
def __init__(self, input=None, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
||||||
|
self._actions = None
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
33
TP02/ariteval/AritListener.py
Normal file
33
TP02/ariteval/AritListener.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Generated from Arit.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
if __name__ is not None and "." in __name__:
|
||||||
|
from .AritParser import AritParser
|
||||||
|
else:
|
||||||
|
from AritParser import AritParser
|
||||||
|
|
||||||
|
# header - mettre les d??clarations globales
|
||||||
|
import sys
|
||||||
|
idTab = {};
|
||||||
|
|
||||||
|
class UnknownIdentifier(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DivByZero(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# This class defines a complete listener for a parse tree produced by AritParser.
|
||||||
|
class AritListener(ParseTreeListener):
|
||||||
|
|
||||||
|
# Enter a parse tree produced by AritParser#prog.
|
||||||
|
def enterProg(self, ctx:AritParser.ProgContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by AritParser#prog.
|
||||||
|
def exitProg(self, ctx:AritParser.ProgContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
del AritParser
|
||||||
110
TP02/ariteval/AritParser.py
Normal file
110
TP02/ariteval/AritParser.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# Generated from Arit.g4 by ANTLR 4.9.2
|
||||||
|
# encoding: utf-8
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
# header - mettre les d??clarations globales
|
||||||
|
import sys
|
||||||
|
idTab = {};
|
||||||
|
|
||||||
|
class UnknownIdentifier(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DivByZero(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\6")
|
||||||
|
buf.write("\b\4\2\t\2\3\2\3\2\3\2\3\2\2\2\3\2\2\2\2\6\2\4\3\2\2\2")
|
||||||
|
buf.write("\4\5\7\4\2\2\5\6\b\2\1\2\6\3\3\2\2\2\2")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class AritParser ( Parser ):
|
||||||
|
|
||||||
|
grammarFileName = "Arit.g4"
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
sharedContextCache = PredictionContextCache()
|
||||||
|
|
||||||
|
literalNames = [ ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>", "COMMENT", "ID", "INT", "WS" ]
|
||||||
|
|
||||||
|
RULE_prog = 0
|
||||||
|
|
||||||
|
ruleNames = [ "prog" ]
|
||||||
|
|
||||||
|
EOF = Token.EOF
|
||||||
|
COMMENT=1
|
||||||
|
ID=2
|
||||||
|
INT=3
|
||||||
|
WS=4
|
||||||
|
|
||||||
|
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ProgContext(ParserRuleContext):
|
||||||
|
__slots__ = 'parser'
|
||||||
|
|
||||||
|
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
||||||
|
super().__init__(parent, invokingState)
|
||||||
|
self.parser = parser
|
||||||
|
self._ID = None # Token
|
||||||
|
|
||||||
|
def ID(self):
|
||||||
|
return self.getToken(AritParser.ID, 0)
|
||||||
|
|
||||||
|
def getRuleIndex(self):
|
||||||
|
return AritParser.RULE_prog
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterProg" ):
|
||||||
|
listener.enterProg(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitProg" ):
|
||||||
|
listener.exitProg(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def prog(self):
|
||||||
|
|
||||||
|
localctx = AritParser.ProgContext(self, self._ctx, self.state)
|
||||||
|
self.enterRule(localctx, 0, self.RULE_prog)
|
||||||
|
try:
|
||||||
|
self.enterOuterAlt(localctx, 1)
|
||||||
|
self.state = 2
|
||||||
|
localctx._ID = self.match(AritParser.ID)
|
||||||
|
print("prog = "+str((None if localctx._ID is None else localctx._ID.text)));
|
||||||
|
except RecognitionException as re:
|
||||||
|
localctx.exception = re
|
||||||
|
self._errHandler.reportError(self, re)
|
||||||
|
self._errHandler.recover(self, re)
|
||||||
|
finally:
|
||||||
|
self.exitRule()
|
||||||
|
return localctx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5
TP02/ariteval/tree.dot
Normal file
5
TP02/ariteval/tree.dot
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
digraph {
|
||||||
|
139921865517408 [label=prog]
|
||||||
|
139921863565696 [label=Hello]
|
||||||
|
139921865517408 -> 139921863565696
|
||||||
|
}
|
||||||
BIN
TP02/ariteval/tree.dot.pdf
Normal file
BIN
TP02/ariteval/tree.dot.pdf
Normal file
Binary file not shown.
69
TP02/demo_files/ex1/Example1.py
Normal file
69
TP02/demo_files/ex1/Example1.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Generated from Example1.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\t")
|
||||||
|
buf.write("*\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
|
||||||
|
buf.write("\4\b\t\b\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\7\5\33\n")
|
||||||
|
buf.write("\5\f\5\16\5\36\13\5\3\6\6\6!\n\6\r\6\16\6\"\3\6\3\6\3")
|
||||||
|
buf.write("\7\3\7\3\b\3\b\2\2\t\3\3\5\4\7\5\t\6\13\7\r\b\17\t\3\2")
|
||||||
|
buf.write("\6\5\2,-//\61\61\3\2\62;\4\2C\\c|\5\2\13\f\17\17\"\"\2")
|
||||||
|
buf.write(",\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13")
|
||||||
|
buf.write("\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\3\21\3\2\2\2\5\23\3")
|
||||||
|
buf.write("\2\2\2\7\25\3\2\2\2\t\27\3\2\2\2\13 \3\2\2\2\r&\3\2\2")
|
||||||
|
buf.write("\2\17(\3\2\2\2\21\22\t\2\2\2\22\4\3\2\2\2\23\24\t\3\2")
|
||||||
|
buf.write("\2\24\6\3\2\2\2\25\26\t\4\2\2\26\b\3\2\2\2\27\34\5\7\4")
|
||||||
|
buf.write("\2\30\33\5\7\4\2\31\33\5\5\3\2\32\30\3\2\2\2\32\31\3\2")
|
||||||
|
buf.write("\2\2\33\36\3\2\2\2\34\32\3\2\2\2\34\35\3\2\2\2\35\n\3")
|
||||||
|
buf.write("\2\2\2\36\34\3\2\2\2\37!\t\5\2\2 \37\3\2\2\2!\"\3\2\2")
|
||||||
|
buf.write("\2\" \3\2\2\2\"#\3\2\2\2#$\3\2\2\2$%\b\6\2\2%\f\3\2\2")
|
||||||
|
buf.write("\2&\'\7*\2\2\'\16\3\2\2\2()\7+\2\2)\20\3\2\2\2\6\2\32")
|
||||||
|
buf.write("\34\"\3\b\2\2")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class Example1(Lexer):
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
OP = 1
|
||||||
|
DIGIT = 2
|
||||||
|
LETTER = 3
|
||||||
|
ID = 4
|
||||||
|
WS = 5
|
||||||
|
OPENP = 6
|
||||||
|
ENDP = 7
|
||||||
|
|
||||||
|
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
||||||
|
|
||||||
|
modeNames = [ "DEFAULT_MODE" ]
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>",
|
||||||
|
"'('", "')'" ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>",
|
||||||
|
"OP", "DIGIT", "LETTER", "ID", "WS", "OPENP", "ENDP" ]
|
||||||
|
|
||||||
|
ruleNames = [ "OP", "DIGIT", "LETTER", "ID", "WS", "OPENP", "ENDP" ]
|
||||||
|
|
||||||
|
grammarFileName = "Example1.g4"
|
||||||
|
|
||||||
|
def __init__(self, input=None, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
||||||
|
self._actions = None
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
64
TP02/demo_files/ex2/Example2Lexer.py
Normal file
64
TP02/demo_files/ex2/Example2Lexer.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Generated from Example2.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\7")
|
||||||
|
buf.write("\"\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\3\2\3\2")
|
||||||
|
buf.write("\3\3\3\3\3\4\6\4\23\n\4\r\4\16\4\24\3\5\6\5\30\n\5\r\5")
|
||||||
|
buf.write("\16\5\31\3\6\6\6\35\n\6\r\6\16\6\36\3\6\3\6\2\2\7\3\3")
|
||||||
|
buf.write("\5\4\7\5\t\6\13\7\3\2\5\5\2,-//\61\61\4\2C\\c|\5\2\13")
|
||||||
|
buf.write("\f\17\17\"\"\2$\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2")
|
||||||
|
buf.write("\t\3\2\2\2\2\13\3\2\2\2\3\r\3\2\2\2\5\17\3\2\2\2\7\22")
|
||||||
|
buf.write("\3\2\2\2\t\27\3\2\2\2\13\34\3\2\2\2\r\16\7=\2\2\16\4\3")
|
||||||
|
buf.write("\2\2\2\17\20\t\2\2\2\20\6\3\2\2\2\21\23\4\62;\2\22\21")
|
||||||
|
buf.write("\3\2\2\2\23\24\3\2\2\2\24\22\3\2\2\2\24\25\3\2\2\2\25")
|
||||||
|
buf.write("\b\3\2\2\2\26\30\t\3\2\2\27\26\3\2\2\2\30\31\3\2\2\2\31")
|
||||||
|
buf.write("\27\3\2\2\2\31\32\3\2\2\2\32\n\3\2\2\2\33\35\t\4\2\2\34")
|
||||||
|
buf.write("\33\3\2\2\2\35\36\3\2\2\2\36\34\3\2\2\2\36\37\3\2\2\2")
|
||||||
|
buf.write("\37 \3\2\2\2 !\b\6\2\2!\f\3\2\2\2\6\2\24\31\36\3\b\2\2")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class Example2Lexer(Lexer):
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
T__0 = 1
|
||||||
|
OP = 2
|
||||||
|
INT = 3
|
||||||
|
ID = 4
|
||||||
|
WS = 5
|
||||||
|
|
||||||
|
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
||||||
|
|
||||||
|
modeNames = [ "DEFAULT_MODE" ]
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>",
|
||||||
|
"';'" ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>",
|
||||||
|
"OP", "INT", "ID", "WS" ]
|
||||||
|
|
||||||
|
ruleNames = [ "T__0", "OP", "INT", "ID", "WS" ]
|
||||||
|
|
||||||
|
grammarFileName = "Example2.g4"
|
||||||
|
|
||||||
|
def __init__(self, input=None, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
||||||
|
self._actions = None
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
30
TP02/demo_files/ex2/Example2Listener.py
Normal file
30
TP02/demo_files/ex2/Example2Listener.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Generated from Example2.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
if __name__ is not None and "." in __name__:
|
||||||
|
from .Example2Parser import Example2Parser
|
||||||
|
else:
|
||||||
|
from Example2Parser import Example2Parser
|
||||||
|
|
||||||
|
# This class defines a complete listener for a parse tree produced by Example2Parser.
|
||||||
|
class Example2Listener(ParseTreeListener):
|
||||||
|
|
||||||
|
# Enter a parse tree produced by Example2Parser#full_expr.
|
||||||
|
def enterFull_expr(self, ctx:Example2Parser.Full_exprContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by Example2Parser#full_expr.
|
||||||
|
def exitFull_expr(self, ctx:Example2Parser.Full_exprContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by Example2Parser#expr.
|
||||||
|
def enterExpr(self, ctx:Example2Parser.ExprContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by Example2Parser#expr.
|
||||||
|
def exitExpr(self, ctx:Example2Parser.ExprContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
del Example2Parser
|
||||||
221
TP02/demo_files/ex2/Example2Parser.py
Normal file
221
TP02/demo_files/ex2/Example2Parser.py
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
# Generated from Example2.g4 by ANTLR 4.9.2
|
||||||
|
# encoding: utf-8
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\7")
|
||||||
|
buf.write("\31\4\2\t\2\4\3\t\3\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\5")
|
||||||
|
buf.write("\3\17\n\3\3\3\3\3\3\3\7\3\24\n\3\f\3\16\3\27\13\3\3\3")
|
||||||
|
buf.write("\2\3\4\4\2\4\2\2\2\30\2\6\3\2\2\2\4\16\3\2\2\2\6\7\5\4")
|
||||||
|
buf.write("\3\2\7\b\7\3\2\2\b\t\7\2\2\3\t\3\3\2\2\2\n\13\b\3\1\2")
|
||||||
|
buf.write("\13\f\7\6\2\2\f\17\b\3\1\2\r\17\7\5\2\2\16\n\3\2\2\2\16")
|
||||||
|
buf.write("\r\3\2\2\2\17\25\3\2\2\2\20\21\f\5\2\2\21\22\7\4\2\2\22")
|
||||||
|
buf.write("\24\5\4\3\6\23\20\3\2\2\2\24\27\3\2\2\2\25\23\3\2\2\2")
|
||||||
|
buf.write("\25\26\3\2\2\2\26\5\3\2\2\2\27\25\3\2\2\2\4\16\25")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class Example2Parser ( Parser ):
|
||||||
|
|
||||||
|
grammarFileName = "Example2.g4"
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
sharedContextCache = PredictionContextCache()
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>", "';'" ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>", "<INVALID>", "OP", "INT", "ID", "WS" ]
|
||||||
|
|
||||||
|
RULE_full_expr = 0
|
||||||
|
RULE_expr = 1
|
||||||
|
|
||||||
|
ruleNames = [ "full_expr", "expr" ]
|
||||||
|
|
||||||
|
EOF = Token.EOF
|
||||||
|
T__0=1
|
||||||
|
OP=2
|
||||||
|
INT=3
|
||||||
|
ID=4
|
||||||
|
WS=5
|
||||||
|
|
||||||
|
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Full_exprContext(ParserRuleContext):
|
||||||
|
__slots__ = 'parser'
|
||||||
|
|
||||||
|
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
||||||
|
super().__init__(parent, invokingState)
|
||||||
|
self.parser = parser
|
||||||
|
|
||||||
|
def expr(self):
|
||||||
|
return self.getTypedRuleContext(Example2Parser.ExprContext,0)
|
||||||
|
|
||||||
|
|
||||||
|
def EOF(self):
|
||||||
|
return self.getToken(Example2Parser.EOF, 0)
|
||||||
|
|
||||||
|
def getRuleIndex(self):
|
||||||
|
return Example2Parser.RULE_full_expr
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterFull_expr" ):
|
||||||
|
listener.enterFull_expr(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitFull_expr" ):
|
||||||
|
listener.exitFull_expr(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def full_expr(self):
|
||||||
|
|
||||||
|
localctx = Example2Parser.Full_exprContext(self, self._ctx, self.state)
|
||||||
|
self.enterRule(localctx, 0, self.RULE_full_expr)
|
||||||
|
try:
|
||||||
|
self.enterOuterAlt(localctx, 1)
|
||||||
|
self.state = 4
|
||||||
|
self.expr(0)
|
||||||
|
self.state = 5
|
||||||
|
self.match(Example2Parser.T__0)
|
||||||
|
self.state = 6
|
||||||
|
self.match(Example2Parser.EOF)
|
||||||
|
except RecognitionException as re:
|
||||||
|
localctx.exception = re
|
||||||
|
self._errHandler.reportError(self, re)
|
||||||
|
self._errHandler.recover(self, re)
|
||||||
|
finally:
|
||||||
|
self.exitRule()
|
||||||
|
return localctx
|
||||||
|
|
||||||
|
|
||||||
|
class ExprContext(ParserRuleContext):
|
||||||
|
__slots__ = 'parser'
|
||||||
|
|
||||||
|
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
||||||
|
super().__init__(parent, invokingState)
|
||||||
|
self.parser = parser
|
||||||
|
self._ID = None # Token
|
||||||
|
|
||||||
|
def ID(self):
|
||||||
|
return self.getToken(Example2Parser.ID, 0)
|
||||||
|
|
||||||
|
def INT(self):
|
||||||
|
return self.getToken(Example2Parser.INT, 0)
|
||||||
|
|
||||||
|
def expr(self, i:int=None):
|
||||||
|
if i is None:
|
||||||
|
return self.getTypedRuleContexts(Example2Parser.ExprContext)
|
||||||
|
else:
|
||||||
|
return self.getTypedRuleContext(Example2Parser.ExprContext,i)
|
||||||
|
|
||||||
|
|
||||||
|
def OP(self):
|
||||||
|
return self.getToken(Example2Parser.OP, 0)
|
||||||
|
|
||||||
|
def getRuleIndex(self):
|
||||||
|
return Example2Parser.RULE_expr
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterExpr" ):
|
||||||
|
listener.enterExpr(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitExpr" ):
|
||||||
|
listener.exitExpr(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def expr(self, _p:int=0):
|
||||||
|
_parentctx = self._ctx
|
||||||
|
_parentState = self.state
|
||||||
|
localctx = Example2Parser.ExprContext(self, self._ctx, _parentState)
|
||||||
|
_prevctx = localctx
|
||||||
|
_startState = 2
|
||||||
|
self.enterRecursionRule(localctx, 2, self.RULE_expr, _p)
|
||||||
|
try:
|
||||||
|
self.enterOuterAlt(localctx, 1)
|
||||||
|
self.state = 12
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
token = self._input.LA(1)
|
||||||
|
if token in [Example2Parser.ID]:
|
||||||
|
self.state = 9
|
||||||
|
localctx._ID = self.match(Example2Parser.ID)
|
||||||
|
print('oh an id : '+(None if localctx._ID is None else localctx._ID.text))
|
||||||
|
pass
|
||||||
|
elif token in [Example2Parser.INT]:
|
||||||
|
self.state = 11
|
||||||
|
self.match(Example2Parser.INT)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise NoViableAltException(self)
|
||||||
|
|
||||||
|
self._ctx.stop = self._input.LT(-1)
|
||||||
|
self.state = 19
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
_alt = self._interp.adaptivePredict(self._input,1,self._ctx)
|
||||||
|
while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
|
||||||
|
if _alt==1:
|
||||||
|
if self._parseListeners is not None:
|
||||||
|
self.triggerExitRuleEvent()
|
||||||
|
_prevctx = localctx
|
||||||
|
localctx = Example2Parser.ExprContext(self, _parentctx, _parentState)
|
||||||
|
self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
|
||||||
|
self.state = 14
|
||||||
|
if not self.precpred(self._ctx, 3):
|
||||||
|
from antlr4.error.Errors import FailedPredicateException
|
||||||
|
raise FailedPredicateException(self, "self.precpred(self._ctx, 3)")
|
||||||
|
self.state = 15
|
||||||
|
self.match(Example2Parser.OP)
|
||||||
|
self.state = 16
|
||||||
|
self.expr(4)
|
||||||
|
self.state = 21
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
_alt = self._interp.adaptivePredict(self._input,1,self._ctx)
|
||||||
|
|
||||||
|
except RecognitionException as re:
|
||||||
|
localctx.exception = re
|
||||||
|
self._errHandler.reportError(self, re)
|
||||||
|
self._errHandler.recover(self, re)
|
||||||
|
finally:
|
||||||
|
self.unrollRecursionContexts(_parentctx)
|
||||||
|
return localctx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int):
|
||||||
|
if self._predicates == None:
|
||||||
|
self._predicates = dict()
|
||||||
|
self._predicates[1] = self.expr_sempred
|
||||||
|
pred = self._predicates.get(ruleIndex, None)
|
||||||
|
if pred is None:
|
||||||
|
raise Exception("No predicate with index:" + str(ruleIndex))
|
||||||
|
else:
|
||||||
|
return pred(localctx, predIndex)
|
||||||
|
|
||||||
|
def expr_sempred(self, localctx:ExprContext, predIndex:int):
|
||||||
|
if predIndex == 0:
|
||||||
|
return self.precpred(self._ctx, 3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
18
TP03/tree/Makefile
Normal file
18
TP03/tree/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
PACKAGE = Tree
|
||||||
|
MAINFILE = tree
|
||||||
|
|
||||||
|
ifndef ANTLR4
|
||||||
|
abort:
|
||||||
|
$(error variable ANTLR4 is not set)
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PACKAGE).g4
|
||||||
|
$(ANTLR4) $^ -Dlanguage=Python3 -visitor
|
||||||
|
|
||||||
|
run: $(MAINFILE).py
|
||||||
|
python3 $^
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
find . \( -iname "~" -or -iname "*.cache*" -or -iname "*.diff" -or -iname "log.txt" -or -iname "*.pyc" -or -iname "*.tokens" -or -iname "*.interp" \) -exec rm -rf '{}' \;
|
||||||
|
rm -rf $(PACKAGE)*.py
|
||||||
60
TP03/tree/TreeLexer.py
Normal file
60
TP03/tree/TreeLexer.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Generated from Tree.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\6")
|
||||||
|
buf.write("\33\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\3\2\3\2\3\3\3")
|
||||||
|
buf.write("\3\3\4\6\4\21\n\4\r\4\16\4\22\3\5\6\5\26\n\5\r\5\16\5")
|
||||||
|
buf.write("\27\3\5\3\5\2\2\6\3\3\5\4\7\5\t\6\3\2\4\3\2\62;\4\2\13")
|
||||||
|
buf.write("\f\"\"\2\34\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3")
|
||||||
|
buf.write("\2\2\2\3\13\3\2\2\2\5\r\3\2\2\2\7\20\3\2\2\2\t\25\3\2")
|
||||||
|
buf.write("\2\2\13\f\7*\2\2\f\4\3\2\2\2\r\16\7+\2\2\16\6\3\2\2\2")
|
||||||
|
buf.write("\17\21\t\2\2\2\20\17\3\2\2\2\21\22\3\2\2\2\22\20\3\2\2")
|
||||||
|
buf.write("\2\22\23\3\2\2\2\23\b\3\2\2\2\24\26\t\3\2\2\25\24\3\2")
|
||||||
|
buf.write("\2\2\26\27\3\2\2\2\27\25\3\2\2\2\27\30\3\2\2\2\30\31\3")
|
||||||
|
buf.write("\2\2\2\31\32\b\5\2\2\32\n\3\2\2\2\5\2\22\27\3\b\2\2")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class TreeLexer(Lexer):
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
T__0 = 1
|
||||||
|
T__1 = 2
|
||||||
|
INT = 3
|
||||||
|
WS = 4
|
||||||
|
|
||||||
|
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
||||||
|
|
||||||
|
modeNames = [ "DEFAULT_MODE" ]
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>",
|
||||||
|
"'('", "')'" ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>",
|
||||||
|
"INT", "WS" ]
|
||||||
|
|
||||||
|
ruleNames = [ "T__0", "T__1", "INT", "WS" ]
|
||||||
|
|
||||||
|
grammarFileName = "Tree.g4"
|
||||||
|
|
||||||
|
def __init__(self, input=None, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
||||||
|
self._actions = None
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
39
TP03/tree/TreeListener.py
Normal file
39
TP03/tree/TreeListener.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Generated from Tree.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
if __name__ is not None and "." in __name__:
|
||||||
|
from .TreeParser import TreeParser
|
||||||
|
else:
|
||||||
|
from TreeParser import TreeParser
|
||||||
|
|
||||||
|
# This class defines a complete listener for a parse tree produced by TreeParser.
|
||||||
|
class TreeListener(ParseTreeListener):
|
||||||
|
|
||||||
|
# Enter a parse tree produced by TreeParser#top.
|
||||||
|
def enterTop(self, ctx:TreeParser.TopContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by TreeParser#top.
|
||||||
|
def exitTop(self, ctx:TreeParser.TopContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by TreeParser#leaf.
|
||||||
|
def enterLeaf(self, ctx:TreeParser.LeafContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by TreeParser#leaf.
|
||||||
|
def exitLeaf(self, ctx:TreeParser.LeafContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by TreeParser#node.
|
||||||
|
def enterNode(self, ctx:TreeParser.NodeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by TreeParser#node.
|
||||||
|
def exitNode(self, ctx:TreeParser.NodeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
del TreeParser
|
||||||
247
TP03/tree/TreeParser.py
Normal file
247
TP03/tree/TreeParser.py
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
# Generated from Tree.g4 by ANTLR 4.9.2
|
||||||
|
# encoding: utf-8
|
||||||
|
from antlr4 import *
|
||||||
|
from io import StringIO
|
||||||
|
import sys
|
||||||
|
if sys.version_info[1] > 5:
|
||||||
|
from typing import TextIO
|
||||||
|
else:
|
||||||
|
from typing.io import TextIO
|
||||||
|
|
||||||
|
|
||||||
|
def serializedATN():
|
||||||
|
with StringIO() as buf:
|
||||||
|
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\6")
|
||||||
|
buf.write("\26\4\2\t\2\4\3\t\3\3\2\3\2\3\2\3\3\3\3\3\3\3\3\6\3\16")
|
||||||
|
buf.write("\n\3\r\3\16\3\17\3\3\3\3\5\3\24\n\3\3\3\2\2\4\2\4\2\2")
|
||||||
|
buf.write("\2\25\2\6\3\2\2\2\4\23\3\2\2\2\6\7\5\4\3\2\7\b\7\2\2\3")
|
||||||
|
buf.write("\b\3\3\2\2\2\t\24\7\5\2\2\n\13\7\3\2\2\13\r\7\5\2\2\f")
|
||||||
|
buf.write("\16\5\4\3\2\r\f\3\2\2\2\16\17\3\2\2\2\17\r\3\2\2\2\17")
|
||||||
|
buf.write("\20\3\2\2\2\20\21\3\2\2\2\21\22\7\4\2\2\22\24\3\2\2\2")
|
||||||
|
buf.write("\23\t\3\2\2\2\23\n\3\2\2\2\24\5\3\2\2\2\4\17\23")
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class TreeParser ( Parser ):
|
||||||
|
|
||||||
|
grammarFileName = "Tree.g4"
|
||||||
|
|
||||||
|
atn = ATNDeserializer().deserialize(serializedATN())
|
||||||
|
|
||||||
|
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
||||||
|
|
||||||
|
sharedContextCache = PredictionContextCache()
|
||||||
|
|
||||||
|
literalNames = [ "<INVALID>", "'('", "')'" ]
|
||||||
|
|
||||||
|
symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "INT", "WS" ]
|
||||||
|
|
||||||
|
RULE_int_tree_top = 0
|
||||||
|
RULE_int_tree = 1
|
||||||
|
|
||||||
|
ruleNames = [ "int_tree_top", "int_tree" ]
|
||||||
|
|
||||||
|
EOF = Token.EOF
|
||||||
|
T__0=1
|
||||||
|
T__1=2
|
||||||
|
INT=3
|
||||||
|
WS=4
|
||||||
|
|
||||||
|
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
||||||
|
super().__init__(input, output)
|
||||||
|
self.checkVersion("4.9.2")
|
||||||
|
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
|
||||||
|
self._predicates = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Int_tree_topContext(ParserRuleContext):
|
||||||
|
__slots__ = 'parser'
|
||||||
|
|
||||||
|
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
||||||
|
super().__init__(parent, invokingState)
|
||||||
|
self.parser = parser
|
||||||
|
|
||||||
|
|
||||||
|
def getRuleIndex(self):
|
||||||
|
return TreeParser.RULE_int_tree_top
|
||||||
|
|
||||||
|
|
||||||
|
def copyFrom(self, ctx:ParserRuleContext):
|
||||||
|
super().copyFrom(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TopContext(Int_tree_topContext):
|
||||||
|
|
||||||
|
def __init__(self, parser, ctx:ParserRuleContext): # actually a TreeParser.Int_tree_topContext
|
||||||
|
super().__init__(parser)
|
||||||
|
self.copyFrom(ctx)
|
||||||
|
|
||||||
|
def int_tree(self):
|
||||||
|
return self.getTypedRuleContext(TreeParser.Int_treeContext,0)
|
||||||
|
|
||||||
|
def EOF(self):
|
||||||
|
return self.getToken(TreeParser.EOF, 0)
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterTop" ):
|
||||||
|
listener.enterTop(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitTop" ):
|
||||||
|
listener.exitTop(self)
|
||||||
|
|
||||||
|
def accept(self, visitor:ParseTreeVisitor):
|
||||||
|
if hasattr( visitor, "visitTop" ):
|
||||||
|
return visitor.visitTop(self)
|
||||||
|
else:
|
||||||
|
return visitor.visitChildren(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def int_tree_top(self):
|
||||||
|
|
||||||
|
localctx = TreeParser.Int_tree_topContext(self, self._ctx, self.state)
|
||||||
|
self.enterRule(localctx, 0, self.RULE_int_tree_top)
|
||||||
|
try:
|
||||||
|
localctx = TreeParser.TopContext(self, localctx)
|
||||||
|
self.enterOuterAlt(localctx, 1)
|
||||||
|
self.state = 4
|
||||||
|
self.int_tree()
|
||||||
|
self.state = 5
|
||||||
|
self.match(TreeParser.EOF)
|
||||||
|
except RecognitionException as re:
|
||||||
|
localctx.exception = re
|
||||||
|
self._errHandler.reportError(self, re)
|
||||||
|
self._errHandler.recover(self, re)
|
||||||
|
finally:
|
||||||
|
self.exitRule()
|
||||||
|
return localctx
|
||||||
|
|
||||||
|
|
||||||
|
class Int_treeContext(ParserRuleContext):
|
||||||
|
__slots__ = 'parser'
|
||||||
|
|
||||||
|
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
||||||
|
super().__init__(parent, invokingState)
|
||||||
|
self.parser = parser
|
||||||
|
|
||||||
|
|
||||||
|
def getRuleIndex(self):
|
||||||
|
return TreeParser.RULE_int_tree
|
||||||
|
|
||||||
|
|
||||||
|
def copyFrom(self, ctx:ParserRuleContext):
|
||||||
|
super().copyFrom(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NodeContext(Int_treeContext):
|
||||||
|
|
||||||
|
def __init__(self, parser, ctx:ParserRuleContext): # actually a TreeParser.Int_treeContext
|
||||||
|
super().__init__(parser)
|
||||||
|
self.copyFrom(ctx)
|
||||||
|
|
||||||
|
def INT(self):
|
||||||
|
return self.getToken(TreeParser.INT, 0)
|
||||||
|
def int_tree(self, i:int=None):
|
||||||
|
if i is None:
|
||||||
|
return self.getTypedRuleContexts(TreeParser.Int_treeContext)
|
||||||
|
else:
|
||||||
|
return self.getTypedRuleContext(TreeParser.Int_treeContext,i)
|
||||||
|
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterNode" ):
|
||||||
|
listener.enterNode(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitNode" ):
|
||||||
|
listener.exitNode(self)
|
||||||
|
|
||||||
|
def accept(self, visitor:ParseTreeVisitor):
|
||||||
|
if hasattr( visitor, "visitNode" ):
|
||||||
|
return visitor.visitNode(self)
|
||||||
|
else:
|
||||||
|
return visitor.visitChildren(self)
|
||||||
|
|
||||||
|
|
||||||
|
class LeafContext(Int_treeContext):
|
||||||
|
|
||||||
|
def __init__(self, parser, ctx:ParserRuleContext): # actually a TreeParser.Int_treeContext
|
||||||
|
super().__init__(parser)
|
||||||
|
self.copyFrom(ctx)
|
||||||
|
|
||||||
|
def INT(self):
|
||||||
|
return self.getToken(TreeParser.INT, 0)
|
||||||
|
|
||||||
|
def enterRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "enterLeaf" ):
|
||||||
|
listener.enterLeaf(self)
|
||||||
|
|
||||||
|
def exitRule(self, listener:ParseTreeListener):
|
||||||
|
if hasattr( listener, "exitLeaf" ):
|
||||||
|
listener.exitLeaf(self)
|
||||||
|
|
||||||
|
def accept(self, visitor:ParseTreeVisitor):
|
||||||
|
if hasattr( visitor, "visitLeaf" ):
|
||||||
|
return visitor.visitLeaf(self)
|
||||||
|
else:
|
||||||
|
return visitor.visitChildren(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def int_tree(self):
|
||||||
|
|
||||||
|
localctx = TreeParser.Int_treeContext(self, self._ctx, self.state)
|
||||||
|
self.enterRule(localctx, 2, self.RULE_int_tree)
|
||||||
|
self._la = 0 # Token type
|
||||||
|
try:
|
||||||
|
self.state = 17
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
token = self._input.LA(1)
|
||||||
|
if token in [TreeParser.INT]:
|
||||||
|
localctx = TreeParser.LeafContext(self, localctx)
|
||||||
|
self.enterOuterAlt(localctx, 1)
|
||||||
|
self.state = 7
|
||||||
|
self.match(TreeParser.INT)
|
||||||
|
pass
|
||||||
|
elif token in [TreeParser.T__0]:
|
||||||
|
localctx = TreeParser.NodeContext(self, localctx)
|
||||||
|
self.enterOuterAlt(localctx, 2)
|
||||||
|
self.state = 8
|
||||||
|
self.match(TreeParser.T__0)
|
||||||
|
self.state = 9
|
||||||
|
self.match(TreeParser.INT)
|
||||||
|
self.state = 11
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
_la = self._input.LA(1)
|
||||||
|
while True:
|
||||||
|
self.state = 10
|
||||||
|
self.int_tree()
|
||||||
|
self.state = 13
|
||||||
|
self._errHandler.sync(self)
|
||||||
|
_la = self._input.LA(1)
|
||||||
|
if not (_la==TreeParser.T__0 or _la==TreeParser.INT):
|
||||||
|
break
|
||||||
|
|
||||||
|
self.state = 15
|
||||||
|
self.match(TreeParser.T__1)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise NoViableAltException(self)
|
||||||
|
|
||||||
|
except RecognitionException as re:
|
||||||
|
localctx.exception = re
|
||||||
|
self._errHandler.reportError(self, re)
|
||||||
|
self._errHandler.recover(self, re)
|
||||||
|
finally:
|
||||||
|
self.exitRule()
|
||||||
|
return localctx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
28
TP03/tree/TreeVisitor.py
Normal file
28
TP03/tree/TreeVisitor.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Generated from Tree.g4 by ANTLR 4.9.2
|
||||||
|
from antlr4 import *
|
||||||
|
if __name__ is not None and "." in __name__:
|
||||||
|
from .TreeParser import TreeParser
|
||||||
|
else:
|
||||||
|
from TreeParser import TreeParser
|
||||||
|
|
||||||
|
# This class defines a complete generic visitor for a parse tree produced by TreeParser.
|
||||||
|
|
||||||
|
class TreeVisitor(ParseTreeVisitor):
|
||||||
|
|
||||||
|
# Visit a parse tree produced by TreeParser#top.
|
||||||
|
def visitTop(self, ctx:TreeParser.TopContext):
|
||||||
|
return self.visitChildren(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
# Visit a parse tree produced by TreeParser#leaf.
|
||||||
|
def visitLeaf(self, ctx:TreeParser.LeafContext):
|
||||||
|
return self.visitChildren(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
# Visit a parse tree produced by TreeParser#node.
|
||||||
|
def visitNode(self, ctx:TreeParser.NodeContext):
|
||||||
|
return self.visitChildren(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
del TreeParser
|
||||||
35
TP03/tree/main.py
Normal file
35
TP03/tree/main.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from TreeLexer import TreeLexer
|
||||||
|
from TreeParser import TreeParser
|
||||||
|
from TreeVisitor import TreeVisitor
|
||||||
|
|
||||||
|
from antlr4 import InputStream, CommonTokenStream
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class MyTreeVisitor(TreeVisitor):
|
||||||
|
def visitLeaf(self, ctx):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def visitNode(self, ctx):
|
||||||
|
nodes = ctx.int_tree();
|
||||||
|
if(len(nodes)>2):
|
||||||
|
return False
|
||||||
|
for node in nodes:
|
||||||
|
if(not self.visit(node)):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def visitTop(self, ctx):
|
||||||
|
return self.visit(ctx.int_tree())
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lexer = TreeLexer(InputStream(sys.stdin.read()))
|
||||||
|
stream = CommonTokenStream(lexer)
|
||||||
|
parser = TreeParser(stream)
|
||||||
|
tree = parser.int_tree_top()
|
||||||
|
visitor = MyTreeVisitor()
|
||||||
|
b = visitor.visit(tree)
|
||||||
|
print("Is it a binary tree ? " + str(b))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user