automated commit TP3

This commit is contained in:
Rémi Di Guardia
2022-09-28 09:28:41 +02:00
parent 530ff7e694
commit 2e15c1352e
45 changed files with 1723 additions and 1 deletions
+2
View File
@@ -0,0 +1,2 @@
/AritListener.py
/AritVisitor.py
+33
View File
@@ -0,0 +1,33 @@
grammar Arit;
prog: statement+ EOF #statementList
;
statement
: expr SCOL #exprInstr
| 'set' ID '=' expr SCOL #assignInstr
;
expr: expr multop=(MULT | DIV) expr #multiplicationExpr
| expr addop=(PLUS | MINUS) expr #additiveExpr
| atom #atomExpr
;
atom: INT #numberAtom
| ID #idAtom
| '(' expr ')' #parens
;
SCOL : ';';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
ID: [a-zA-Z_] [a-zA-Z_0-9]*;
INT: [0-9]+;
COMMENT: '#' ~[\r\n]* -> skip;
NEWLINE: '\r'? '\n' -> skip;
WS : (' '|'\t')+ -> skip;
+23
View File
@@ -0,0 +1,23 @@
PACKAGE = Arit
MAINFILE = arit
ifndef ANTLR4
abort:
$(error variable ANTLR4 is not set)
endif
all: $(PACKAGE).g4
$(ANTLR4) $^ -Dlanguage=Python3 -visitor
run: $(MAINFILE).py
python3 $^
ex: $(MAINFILE).py
python3 $^ < myexample
test: all
python3 ./test_arith_visitor.py
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
+58
View File
@@ -0,0 +1,58 @@
from AritVisitor import AritVisitor
from AritParser import AritParser
class UnknownIdentifier(Exception):
pass
class MyAritVisitor(AritVisitor):
"""Visitor that evaluates an expression. Derives and overrides methods
from ArithVisitor (generated by ANTLR4)."""
def __init__(self):
self._memory = dict() # store id -> values
def visitNumberAtom(self, ctx):
try:
value = int(ctx.getText())
return value
except ValueError:
return float(ctx.getText())
def visitIdAtom(self, ctx):
try:
return self._memory[ctx.getText()]
except KeyError:
raise UnknownIdentifier(ctx.getText())
def visitMultiplicationExpr(self, ctx):
# Recursive calls to children. The visitor will choose the
# appropriate method (visitSomething) automatically.
leftval = self.visit(ctx.expr(0))
rightval = self.visit(ctx.expr(1))
# an elegant way to match the token:
if ctx.multop.type == AritParser.MULT:
return leftval * rightval
else:
return leftval / rightval
def visitAdditiveExpr(self, ctx):
leftval = self.visit(ctx.expr(0))
rightval = self.visit(ctx.expr(1))
if ctx.addop.type == AritParser.PLUS:
return leftval + rightval
else:
return leftval - rightval
def visitExprInstr(self, ctx):
val = self.visit(ctx.expr())
print('The value is ' + str(val))
def visitParens(self, ctx):
return self.visit(ctx.expr())
def visitAssignInstr(self, ctx):
val = self.visit(ctx.expr())
name = ctx.ID().getText()
print('now ' + name + ' has value ' + str(val))
self._memory[name] = val
+28
View File
@@ -0,0 +1,28 @@
from AritLexer import AritLexer
from AritParser import AritParser
# from AritVisitor import AritVisitor
from MyAritVisitor import MyAritVisitor, UnknownIdentifier
from antlr4 import InputStream, CommonTokenStream
import sys
# example of use of visitors to parse arithmetic expressions.
# stops when the first SyntaxError is launched.
def main():
lexer = AritLexer(InputStream(sys.stdin.read()))
stream = CommonTokenStream(lexer)
parser = AritParser(stream)
tree = parser.prog()
print("Parsing : done.")
visitor = MyAritVisitor()
try:
visitor.visit(tree)
except UnknownIdentifier as exc:
print('Unknown identifier: {}'.format(exc.args[0]))
exit(-1)
if __name__ == '__main__':
main()
+5
View File
@@ -0,0 +1,5 @@
1 ;
12 ;
1+2 ;
1+2*3+4;
(1+2)*(3+4);
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python
from AritLexer import AritLexer
from AritParser import AritParser
import pytest
from MyAritVisitor import MyAritVisitor
from antlr4 import InputStream, CommonTokenStream
import sys
@pytest.mark.parametrize("input, expected", [
pytest.param('1+1;', 2),
pytest.param('2-1;', 1),
pytest.param('2*3;', 6),
pytest.param('6/2;', 3),
pytest.param('set x=42; x+1;', 43),
pytest.param('set x=42; set x=12; x+1;', 13)
])
def test_expr(input, expected):
lexer = AritLexer(InputStream(input))
stream = CommonTokenStream(lexer)
parser = AritParser(stream)
tree = parser.prog()
print("Parsing : done.")
visitor = MyAritVisitor()
def patched_visit(self, ctx):
self.last_expr = self.visit(ctx.expr())
visitor.visitExprInstr = patched_visit.__get__(visitor)
visitor.visit(tree)
assert visitor.last_expr == expected
if __name__ == '__main__':
pytest.main(sys.argv)