Mon commit avec mes modifs à moi ! Na

This commit is contained in:
Mysaa 2022-10-26 11:51:37 +02:00
parent 52ce1488c5
commit 62d045512a
Signed by: Mysaa
GPG Key ID: 7054D5D6A90F084F
62 changed files with 2342 additions and 77 deletions

View File

@ -86,7 +86,9 @@ define CLEAN
import glob
import os
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:
os.remove(s)
print("Removed {}".format(s))

View File

@ -3,23 +3,32 @@ LAB4 (simple code generation), MIF08 / CAP 2022-23
# Authors
YOUR NAME HERE
Samy Avrillon
# 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
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
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
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
@ -28,30 +37,30 @@ and *tested* with appropriate test cases.
## Code generation
- [ ] Number Atom
- [ ] Boolean Atom
- [ ] Id Atom
- [ ] Additive expression
- [ ] Multiplicative expression
- [ ] UnaryMinus expression
- [ ] Or expression
- [ ] And expression
- [ ] Equality expression
- [ ] Relational expression (! many cases -> many tests)
- [ ] Not expression
- [X] Number Atom
- [X] Boolean Atom
- [X] Id Atom
- [X] Additive expression
- [X] Multiplicative expression
- [X] UnaryMinus expression
- [X] Or expression
- [X] And expression
- [X] Equality expression
- [X] Relational expression (! many cases -> many tests)
- [X] Not expression
## Statements
- [ ] Prog, assignements
- [ ] While
- [ ] Cond Block
- [ ] If
- [ ] Nested ifs
- [ ] Nested whiles
- [X] Prog, assignements
- [X] While
- [X] Cond Block
- [X] If
- [X] Nested ifs
- [X] Nested whiles
## Allocation
- [ ] Naive allocation
- [ ] All in memory allocation
- [ ] Massive tests of memory allocation
- [X] Naive allocation
- [X] All in memory allocation
- [X] Massive tests of memory allocation

View File

@ -110,7 +110,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
self._raise(ctx,"boolean operator", fstT,sndT)
def visitAndExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@ -121,7 +121,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
self._raise(ctx,"boolean operator", fstT,sndT)
def visitEqualityExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@ -140,7 +140,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
self._raise(ctx, "comparaison operator", fstT)
else:
self._assertSameType(ctx,"comparaison operator", fstT,sndT)
self._raise(ctx,"comparaison operator", fstT,sndT)
def visitAdditiveExpr(self, ctx):
assert ctx.myop is not None
@ -152,9 +152,9 @@ class MiniCTypingVisitor(MiniCVisitor):
elif (fstT == BaseType.String and ctx.myop.type == MiniCParser.PLUS):
return BaseType.String
else:
self._raise(ctx, "additive operands", fstT)
self._raise(ctx, "additive operands", fstT,sndT)
else:
self._assertSameType(ctx,"additive operator", fstT,sndT)
self._raise(ctx,"additive operator", fstT,sndT)
def visitMultiplicativeExpr(self, ctx):
fstT = self.visit(ctx.expr(0))
@ -165,7 +165,7 @@ class MiniCTypingVisitor(MiniCVisitor):
else:
return fstT
else:
self._assertSameType(ctx,"multiplicative operator", fstT,sndT)
self._raise(ctx,"multiplicative operands", fstT,sndT)
def visitNotExpr(self, ctx):
fstT = self.visit(ctx.expr())

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -6,4 +6,4 @@ int main(){
}
// EXITCODE 2
// 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

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -13,4 +13,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -19,4 +19,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -13,4 +13,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// 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

View File

@ -14,12 +14,32 @@ class AllInMemAllocator(Allocator):
before: List[Instruction] = []
after: List[Instruction] = []
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): iterate over old_args, check which argument
# 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): temporary with S[1], S[2] or S[3] physical registers.
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
def prepare(self):

View File

@ -20,7 +20,14 @@ def find_leaders(instructions: List[CodeStatement]) -> List[int]:
last is len(instructions)
"""
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
leaders.append(len(instructions))
return leaders
@ -64,9 +71,19 @@ def prepare_chunk(pre_chunk: List[CodeStatement], fdata: FunctionData) -> tuple[
jump = None
inner_statements: List[CodeStatement] = pre_chunk
# 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
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
l: List[BlockInstr] = []
for i in inner_statements:

View File

@ -23,10 +23,32 @@ def linearize(cfg) -> List[Statement]:
"""
Linearize the given control flow graph as a list of instructions.
"""
# TODO (Lab 4b, Exercise 5)
l: List[Statement] = [] # Linearized 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
l.append(block.get_label())
# 2. Add the body of the block to the linearization

View File

@ -75,7 +75,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
# 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:
try:
@ -97,13 +103,52 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitAdditiveExpr(self, ctx) -> Operands.Temporary:
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:
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:
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:
return self.visitRelationalExpr(ctx)
@ -115,18 +160,63 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print("relational expression:")
print(Trees.toStringTree(ctx, None, self._parser))
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:
assert ctx.myop is not None
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:
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:
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:
self.visitChildren(ctx)
@ -158,9 +248,25 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitIfStat(self, ctx) -> None:
if self._debug:
print("if statement")
end_if_label = self._current_function.fdata.fresh_label("end_if")
raise NotImplementedError() # TODO (Exercise 5)
self._current_function.add_label(end_if_label)
lendif = self._current_function.fdata.fresh_label("endif")
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:
if self._debug:
@ -168,7 +274,37 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print(Trees.toStringTree(ctx.expr(), None, self._parser))
print("and block is:")
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
def visitPrintlnintStat(self, ctx) -> None:

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -6,7 +6,7 @@ Functions to convert a CFG into SSA Form.
from typing import List, Dict, Set
from Lib.CFG import Block, CFG
from Lib.Operands import Renamer
from Lib.Statement import Instruction
from Lib.Statement import Instruction,Label,Operand
from Lib.PhiNode import PhiNode
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)
for b in DF[d]:
if b not in has_phi:
# TODO add a phi node in block `b` (Lab 5a, Exercise 4)
raise NotImplementedError("insertPhis")
params : Dict[Label,Operand] = {}
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:
@ -43,18 +48,19 @@ def rename_block(cfg: CFG, DT: Dict[Block, Set[Block]], renamer: Renamer, b: Blo
for i in succ._phis:
assert (isinstance(i, PhiNode))
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:
"""
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.
"""
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:
@ -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.
`basename` is used for the names of the produced graphs.
"""
# TODO implement this function (Lab 5a, Exercise 2)
raise NotImplementedError("enter_ssa")
# Compute the DF
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)

View File

@ -4,6 +4,7 @@ Functions to convert a CFG out of SSA Form.
"""
from typing import cast, List, Set, Tuple
from Lib.Errors import MiniCInternalError
from Lib import RiscV
from Lib.Graphes import DiGraph
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.
"""
moves: List[BlockInstr] = []
# TODO compute 'moves', a list of 'mv' instructions to insert under parent
# (Lab 5a, Exercise 6)
plabel = parent.get_label()
for phi in phis:
if(plabel in phi.used()):
moves.append(RiscV.mv(phi.var,phi.used()[plabel]))
return moves
@ -38,11 +41,34 @@ def exit_ssa(cfg: CFG, is_smart: bool) -> None:
for b in cfg.get_blocks():
phis = cast(List[PhiNode], b._phis) # Use cast for Pyright
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
for parent in parents:
moves = generate_moves_from_phis(phis, parent)
# TODO Add the block containing 'moves' to 'cfg'
# and update edges and jumps accordingly (Lab 5a, Exercise 6)
raise NotImplementedError("exit_ssa")
for p in parents:
moves = generate_moves_from_phis(phis, p)
if(len(moves)==0):
continue
# 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

Binary file not shown.

BIN
TP01/riscv/libprint.o Normal file

Binary file not shown.

BIN
TP01/riscv/test_print Executable file

Binary file not shown.

BIN
TP01/riscv/test_print.o Normal file

Binary file not shown.

BIN
TP01/riscv/test_print.riscv Executable file

Binary file not shown.

View 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

View 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
View 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
View File

@ -0,0 +1,5 @@
digraph {
139921865517408 [label=prog]
139921863565696 [label=Hello]
139921865517408 -> 139921863565696
}

BIN
TP02/ariteval/tree.dot.pdf Normal file

Binary file not shown.

View 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

View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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()