mirror of
https://github.com/mudabbir-ahmad/UNI-PROG3-CW2-DYOPL.git
synced 2026-10-07 20:00:20 +00:00
Q2 prep
This commit is contained in:
1 parent
b3fd98703a
commit
d20c595e0f
10 files changed
+204
No files matched your search
Binary file not shown.
File renamed without changes.
File renamed without changes.
BIN
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
from antlr4.Utils import escapeWhitespace
|
||||
from antlr4.tree.Tree import Tree
|
||||
from antlr4.tree.Trees import Trees
|
||||
|
||||
# need forward declaration
|
||||
Parser = None
|
||||
|
||||
class TreesUser(Trees):
|
||||
|
||||
# Print out a whole tree in prettier form
|
||||
# Based on Trees.toStringTree()
|
||||
# indent is the number of indents to use in the display
|
||||
@classmethod
|
||||
def PrettyPrint(cls, t:Tree, ruleNames:list=None, recog:Parser=None, indent:int=0):
|
||||
# indentation is the indent to actually display
|
||||
indentation = ''
|
||||
for n in range(indent):
|
||||
indentation += ' '
|
||||
if recog is not None:
|
||||
ruleNames = recog.ruleNames
|
||||
s = escapeWhitespace(cls.getNodeText(t, ruleNames), False)
|
||||
retval = indentation + s + "\n"
|
||||
if t.getChildCount()>0:
|
||||
# we have children to deal with
|
||||
for i in range(0, t.getChildCount()):
|
||||
retval += cls.PrettyPrint(t.getChild(i), ruleNames, indent=indent+1)
|
||||
return retval
|
||||
@@ -0,0 +1,62 @@
|
||||
grammar fspow;
|
||||
// workshop 4 version
|
||||
|
||||
prog: stat+ ;
|
||||
|
||||
// labelling alternatives creates extra visitor methods
|
||||
// the labels migh clash with rule names, so I make them unique
|
||||
stat:
|
||||
assignment # statAssignment
|
||||
| fcList # statFcList
|
||||
| fcApplySelector # statFcApplySelector
|
||||
| message # statMessage
|
||||
;
|
||||
|
||||
assignment :
|
||||
ID '=' expression ;
|
||||
|
||||
// when alternatives are introduced, try using labels to distinguish
|
||||
expression :
|
||||
ID # exprID
|
||||
|
|
||||
selCreation # exprSelCreation
|
||||
|
|
||||
fcCreation # exprFcCreation
|
||||
;
|
||||
// -------
|
||||
// filecollection statements
|
||||
// -------
|
||||
fcCreation: fcCreationName '(' rootSpecifier ')' ;
|
||||
|
||||
fcCreationName: 'FileCollection' ;
|
||||
rootSpecifier: STRING ;
|
||||
// -------
|
||||
// selector statements
|
||||
// -------
|
||||
selCreation : selCreationName '(' filterSpecifier ')' ;
|
||||
|
||||
selCreationName: 'Selector' ;
|
||||
filterSpecifier: selfilter '(' STRING ')' ;
|
||||
selfilter: 'name' ;
|
||||
// -------
|
||||
// apply statement
|
||||
// -------
|
||||
fcApplySelector: ID '.' applyName '(' expression ')' ;
|
||||
|
||||
applyName: 'apply' ;
|
||||
// -------
|
||||
// print statement
|
||||
// -------
|
||||
fcList: ID '.' printName ;
|
||||
|
||||
printName: 'print()' ;
|
||||
// -------
|
||||
// message statement
|
||||
// -------
|
||||
message: 'message' STRING ;
|
||||
|
||||
ID: [a-zA-Z][a-zA-Z0-9]* ;
|
||||
STRING: '"'.*?'"'
|
||||
{self.text = self.text[1:-1]} ;
|
||||
WS : [ \t\r\n]+ -> skip ;
|
||||
COMMENT : '//' ~[\r\n]* -> channel(HIDDEN) ;
|
||||
@@ -0,0 +1,64 @@
|
||||
# main.py
|
||||
"""
|
||||
Parse and execute statements either in stdin or in file
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from antlr4 import *
|
||||
from fspowLexer import fspowLexer
|
||||
from fspowParser import fspowParser
|
||||
# from fspowListener import fspowListener
|
||||
# from antlr4.tree.Trees import Trees
|
||||
from TreesUser import TreesUser
|
||||
from Q2.Artefacts.fspowVisitorUser import fspowVisitorUser
|
||||
|
||||
|
||||
def main(argv):
|
||||
# argv[1] s/be name of source file
|
||||
# if missing, use stdin
|
||||
if len(argv) == 1:
|
||||
# StdinStream is a standard ANTLR class read by the lexer
|
||||
# (It is not a file descriptor)
|
||||
inpstream = StdinStream()
|
||||
else:
|
||||
inpname = argv[1]
|
||||
# FileStream is a standard ANTLR class read by the lexer
|
||||
# (It is not a file descriptor)
|
||||
inpstream = FileStream(inpname)
|
||||
|
||||
|
||||
|
||||
# The lexer analyses the characters on inpstream and produces tokens
|
||||
lexer = fspowLexer(inpstream)
|
||||
# .. on the token stream (belonging to a standard ANTLR class)
|
||||
tokstream = CommonTokenStream(lexer)
|
||||
|
||||
# The parser produces an abstract syntax tree
|
||||
parser = fspowParser(tokstream)
|
||||
# When we execute the parse, we need to give it the starting rule of our grammar,
|
||||
# which in our case is 'start' (as defined in fspow.g4),
|
||||
# so here we invoke the method named after this rule: start()
|
||||
tree = parser.prog()
|
||||
|
||||
# print the parse tree
|
||||
#print(TreesUser.toStringTree(tree, None, parser))
|
||||
print(TreesUser.PrettyPrint(tree, None, parser))
|
||||
|
||||
visitor = fspowVisitorUser()
|
||||
visitor.visit(tree)
|
||||
|
||||
# The listener defines the actions to take upon entering an exiting nodes for
|
||||
# specific tokens on the AST
|
||||
# listener = fspowListener()
|
||||
|
||||
# A ParseTreeWalker is annother standard ANTLR class, that performs a walk on the AST
|
||||
# walker = ParseTreeWalker()
|
||||
|
||||
# Get the tree walker to perform a walk on the AST, getting the listener to perform
|
||||
# the appropriate actions
|
||||
# walker.walk~(listener, tree)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
@@ -0,0 +1,36 @@
|
||||
# Generated from fspow.g4 by ANTLR
|
||||
from antlr4 import *
|
||||
#from idlelib.idle_test.test_configdialog import root
|
||||
if __name__ is not None and "." in __name__:
|
||||
from .fspowParser import fspowParser
|
||||
else:
|
||||
from fspowParser import fspowParser
|
||||
|
||||
# superclass
|
||||
from fspowVisitor import fspowVisitor
|
||||
|
||||
# our own imports:
|
||||
from repertoire.FileCollection import *
|
||||
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):
|
||||
|
||||
# where all the variables reside
|
||||
variablesTable = defaultdict()
|
||||
|
||||
|
||||
# just write methods to be overridden
|
||||
# in future, may want to implement multiple subclasses
|
||||
# but for now, I'd copy the ones I need to override here to implement them
|
||||
|
||||
|
||||
|
||||
del fspowParser
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
message "Hello world!"
|
||||
// wombats = FileCollection("wombats")
|
||||
// wombats.print()
|
||||
// hairies = Selector(name("hairy"))
|
||||
// wombats.apply(hairies)
|
||||
// the following not yet implemented
|
||||
// wombats.apply(Selector(name("")))
|
||||
// wombats.print()
|
||||
// marsupials = FileCollection("marsupials")
|
||||
// marsupials.print()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
Binary file not shown.
Reference in new issue
Block a user