mirror of
https://github.com/mudabbir-ahmad/UNI-PROG3-CW2-DYOPL.git
synced 2026-10-07 20:00:20 +00:00
Q2 done?! maybe
This commit is contained in:
1 parent
d20c595e0f
commit
c76af24421
6 files changed
+116
-55
No files matched your search
@@ -20,4 +20,8 @@ repeatStat: 'REPEAT' NUMBER '{' stat+ '}' ;
|
|||||||
ID_PREFIX: '// STUDENT ID:' ;
|
ID_PREFIX: '// STUDENT ID:' ;
|
||||||
NUMBER: [0-9]+ ;
|
NUMBER: [0-9]+ ;
|
||||||
STRING: '"' .*? '"' ;
|
STRING: '"' .*? '"' ;
|
||||||
WS: [ \t\r\n]+ -> skip ;
|
WS: [ \t\r\n]+ -> skip ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,4 +36,8 @@ class RobotLangVisitorUser(RobotLangVisitor):
|
|||||||
for _ in range(times):
|
for _ in range(times):
|
||||||
for stat_ctx in ctx.stat():
|
for stat_ctx in ctx.stat():
|
||||||
self.visit(stat_ctx)
|
self.visit(stat_ctx)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
Binary file not shown.
+27
-27
@@ -1,62 +1,62 @@
|
|||||||
grammar fspow;
|
grammar fspow;
|
||||||
// workshop 4 version
|
|
||||||
|
|
||||||
prog: stat+ ;
|
prog: stat+ ;
|
||||||
|
|
||||||
// labelling alternatives creates extra visitor methods
|
// labelling alternatives creates extra visitor methods
|
||||||
// the labels migh clash with rule names, so I make them unique
|
// the labels might clash with rule names, so I make them unique
|
||||||
stat:
|
stat: assignment # statAssignment
|
||||||
assignment # statAssignment
|
|
||||||
| fcList # statFcList
|
| fcList # statFcList
|
||||||
| fcApplySelector # statFcApplySelector
|
| fcApplySelector # statFcApplySelector
|
||||||
| message # statMessage
|
| message # statMessage
|
||||||
;
|
;
|
||||||
|
|
||||||
assignment :
|
assignment :
|
||||||
ID '=' expression ;
|
ID '=' expression;
|
||||||
|
|
||||||
// when alternatives are introduced, try using labels to distinguish
|
// when alternatives are introduced, try using labels to distinguish
|
||||||
expression :
|
expression : ID # exprID
|
||||||
ID # exprID
|
| selCreation # exprSelCreation
|
||||||
|
|
| fcCreation # exprFcCreation
|
||||||
selCreation # exprSelCreation
|
|
||||||
|
|
|
||||||
fcCreation # exprFcCreation
|
|
||||||
;
|
;
|
||||||
// -------
|
// -------
|
||||||
// filecollection statements
|
// filecollection statements
|
||||||
// -------
|
// -------
|
||||||
fcCreation: fcCreationName '(' rootSpecifier ')' ;
|
fcCreation: fcCreationName '(' rootSpecifier ')' ;
|
||||||
|
|
||||||
fcCreationName: 'FileCollection' ;
|
fcCreationName: 'FileCollection' ;
|
||||||
rootSpecifier: STRING ;
|
rootSpecifier: STRING ;
|
||||||
// -------
|
// -------
|
||||||
// selector statements
|
// selector statements
|
||||||
// -------
|
// -------
|
||||||
selCreation : selCreationName '(' filterSpecifier ')' ;
|
selCreation : selCreationName '(' testexpression ')' ;
|
||||||
|
selCreationName: 'Selector' ;
|
||||||
|
|
||||||
selCreationName: 'Selector' ;
|
testexpression : testunit (testoperator testunit)* ;
|
||||||
filterSpecifier: selfilter '(' STRING ')' ;
|
|
||||||
selfilter: 'name' ;
|
testoperator: 'intersect' #testoperatorIntersect ;
|
||||||
|
|
||||||
|
testunit: 'name' '(' STRING ')' #testunitname
|
||||||
|
| 'size' '(' STRING ')' #testunitsize
|
||||||
|
| 'type' '(' STRING ')' #testunittype
|
||||||
|
| 'date' '(' STRING ')' #testunitdate
|
||||||
|
| '(' testexpression ')' #testunittestexpression
|
||||||
|
| 'not' '(' testexpression ')' #testunitnottestexpression ;
|
||||||
// -------
|
// -------
|
||||||
// apply statement
|
// apply statement
|
||||||
// -------
|
// -------
|
||||||
fcApplySelector: ID '.' applyName '(' expression ')' ;
|
fcApplySelector: ID '.' applyName '(' expression ')' ;
|
||||||
|
|
||||||
applyName: 'apply' ;
|
applyName: 'apply' ;
|
||||||
// -------
|
// -------
|
||||||
// print statement
|
// print statement
|
||||||
// -------
|
// -------
|
||||||
fcList: ID '.' printName ;
|
fcList: ID '.' printName ; // fc.print()
|
||||||
|
|
||||||
printName: 'print()' ;
|
printName: 'print()' ;
|
||||||
// -------
|
// -------
|
||||||
// message statement
|
// message statement
|
||||||
// -------
|
// -------
|
||||||
message: 'message' STRING ;
|
message: 'message' STRING ;
|
||||||
|
|
||||||
ID: [a-zA-Z][a-zA-Z0-9]* ;
|
ID: [a-zA-Z][a-zA-Z0-9]* ;
|
||||||
STRING: '"'.*?'"'
|
STRING: '"'.*?'"' {self.text = self.text[1:-1]} ;
|
||||||
{self.text = self.text[1:-1]} ;
|
|
||||||
WS : [ \t\r\n]+ -> skip ;
|
WS : [ \t\r\n]+ -> skip ;
|
||||||
COMMENT : '//' ~[\r\n]* -> channel(HIDDEN) ;
|
COMMENT : '//' ~[\r\n]* -> channel(HIDDEN) ;
|
||||||
@@ -4,6 +4,7 @@ Parse and execute statements either in stdin or in file
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
from antlr4 import *
|
from antlr4 import *
|
||||||
from fspowLexer import fspowLexer
|
from fspowLexer import fspowLexer
|
||||||
@@ -11,7 +12,7 @@ from fspowParser import fspowParser
|
|||||||
# from fspowListener import fspowListener
|
# from fspowListener import fspowListener
|
||||||
# from antlr4.tree.Trees import Trees
|
# from antlr4.tree.Trees import Trees
|
||||||
from TreesUser import TreesUser
|
from TreesUser import TreesUser
|
||||||
from Q2.Artefacts.fspowVisitorUser import fspowVisitorUser
|
from fspowVisitorUser import fspowVisitorUser
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|||||||
@@ -1,36 +1,88 @@
|
|||||||
# Generated from fspow.g4 by ANTLR
|
|
||||||
from antlr4 import *
|
from antlr4 import *
|
||||||
#from idlelib.idle_test.test_configdialog import root
|
from fspowParser import fspowParser
|
||||||
if __name__ is not None and "." in __name__:
|
|
||||||
from .fspowParser import fspowParser
|
|
||||||
else:
|
|
||||||
from fspowParser import fspowParser
|
|
||||||
|
|
||||||
# superclass
|
|
||||||
from fspowVisitor import fspowVisitor
|
from fspowVisitor import fspowVisitor
|
||||||
|
|
||||||
# our own imports:
|
from repertoire.FileCollection import FileCollection
|
||||||
from repertoire.FileCollection import *
|
from repertoire.Selector import Selector
|
||||||
from repertoire.Selector import *
|
|
||||||
from repertoire.FSObject import *
|
|
||||||
|
|
||||||
# for symbol table
|
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
# This class defines a complete specific visitor for a parse tree produced by fspowParser.
|
|
||||||
|
|
||||||
class fspowVisitorUser(fspowVisitor):
|
class fspowVisitorUser(fspowVisitor):
|
||||||
|
def __init__(self):
|
||||||
# where all the variables reside
|
# Dictionary to track assigned variables during the AST walk
|
||||||
variablesTable = defaultdict()
|
self.variablesTable = {}
|
||||||
|
|
||||||
|
def visitMessage(self, ctx):
|
||||||
# just write methods to be overridden
|
# Quotes are already stripped by the inline lexer action
|
||||||
# in future, may want to implement multiple subclasses
|
print(ctx.STRING().getText())
|
||||||
# but for now, I'd copy the ones I need to override here to implement them
|
return self.visitChildren(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
def visitFcCreation(self, ctx):
|
||||||
|
root_name = self.visit(ctx.rootSpecifier())
|
||||||
|
return FileCollection(root_name)
|
||||||
|
|
||||||
del fspowParser
|
def visitRootSpecifier(self, ctx):
|
||||||
|
return ctx.STRING().getText()
|
||||||
|
|
||||||
|
def visitAssignment(self, ctx):
|
||||||
|
# Maps string identifiers to their evaluated backend objects
|
||||||
|
var_id = ctx.ID().getText()
|
||||||
|
self.variablesTable[var_id] = self.visit(ctx.expression())
|
||||||
|
return True
|
||||||
|
|
||||||
|
def visitFcList(self, ctx):
|
||||||
|
var_id = ctx.getChild(0).getText()
|
||||||
|
if var_id in self.variablesTable:
|
||||||
|
print(self.variablesTable[var_id].list())
|
||||||
|
else:
|
||||||
|
print(f"File collection {var_id} not found")
|
||||||
|
|
||||||
|
def visitFcApplySelector(self, ctx):
|
||||||
|
fc_id = ctx.ID().getText()
|
||||||
|
if fc_id in self.variablesTable:
|
||||||
|
sel_id = ctx.expression().getText()
|
||||||
|
if sel_id in self.variablesTable:
|
||||||
|
self.variablesTable[fc_id].apply(self.variablesTable[sel_id])
|
||||||
|
else:
|
||||||
|
print(f"Selector {sel_id} not found")
|
||||||
|
else:
|
||||||
|
print(f"File collection {fc_id} not found")
|
||||||
|
|
||||||
|
def visitSelCreation(self, ctx):
|
||||||
|
# Triggers the AST walk to process the complex filter expression
|
||||||
|
return self.visit(ctx.testexpression())
|
||||||
|
|
||||||
|
def visitExprID(self, ctx):
|
||||||
|
var_id = ctx.ID().getText()
|
||||||
|
return self.variablesTable.get(var_id)
|
||||||
|
|
||||||
|
# --- Filter List ---
|
||||||
|
|
||||||
|
def visitTestexpression(self, ctx):
|
||||||
|
# Dynamically builds the recursive list, encoding 'intersect' as 1
|
||||||
|
expr_list = []
|
||||||
|
for i in range(ctx.getChildCount()):
|
||||||
|
child = ctx.getChild(i)
|
||||||
|
if child.getText() == 'intersect':
|
||||||
|
expr_list.append(1)
|
||||||
|
else:
|
||||||
|
expr_list.append(self.visit(child))
|
||||||
|
return expr_list
|
||||||
|
|
||||||
|
def visitTestunitnottestexpression(self, ctx):
|
||||||
|
# Appends -1 to mathematically encode the 'not' inversion
|
||||||
|
return [-1, self.visit(ctx.testexpression())]
|
||||||
|
|
||||||
|
def visitTestunittestexpression(self, ctx):
|
||||||
|
return self.visit(ctx.testexpression())
|
||||||
|
|
||||||
|
def visitTestunitname(self, ctx):
|
||||||
|
return {"name": ctx.STRING().getText()}
|
||||||
|
|
||||||
|
def visitTestunitsize(self, ctx):
|
||||||
|
return {"size": ctx.STRING().getText()}
|
||||||
|
|
||||||
|
def visitTestunittype(self, ctx):
|
||||||
|
return {"type": ctx.STRING().getText()}
|
||||||
|
|
||||||
|
def visitTestunitdate(self, ctx):
|
||||||
|
return {"date": ctx.STRING().getText()}
|
||||||
Reference in new issue
Block a user