This commit is contained in:
bobbert committed 2026-04-28 13:36:46 +01:00
1 parent b3fd98703a
commit d20c595e0f
10 files changed
+204

No files matched your search

Binary file not shown.
BIN
View File
Binary file not shown.
+27
View File
@@ -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
+62
View File
@@ -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) ;
+64
View File
@@ -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)
+36
View File
@@ -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
+15
View File
@@ -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
View File
Binary file not shown.