Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from string import ascii_uppercase
- from pyparsing import *
- class Node(object):
- def __init__(self, s, loc, toks):
- self.children = toks
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, ', '.join(map(str, self.children)))
- @classmethod
- def grammar(cls, expression):
- return expression.setParseAction(cls)
- class Module(Node):
- def __init__(self, s, loc, toks):
- self.body = toks
- super().__init__(s, loc, toks)
- class Expression(Node):
- def __init__(self, s, loc, toks):
- self.left, self.op, self.right = toks[0]
- super().__init__(s, loc, toks)
- class Main(Node):
- def __init__(self, s, loc, toks):
- self.body = toks
- super().__init__(s, loc, toks)
- class AliasDefinition(Node):
- def __init__(self, s, loc, toks):
- self.alias, self.value = toks
- super().__init__(s, loc, toks)
- class Alias(Node):
- def __init__(self, s, loc, toks):
- self.alias = toks[0]
- super().__init__(s, loc, toks)
- class Assignment(Node):
- def __init__(self, s, loc, toks):
- self.left, self.right = toks
- super().__init__(s, loc, toks)
- class MemoryAssignment(Node):
- def __init__(self, s, loc, toks):
- self.left, self.right = toks
- super().__init__(s, loc, toks)
- class AugmentedAssignment(Node):
- def __init__(self, s, loc, toks):
- self.left, self.operator, self.right = toks
- super().__init__(s, loc, toks)
- class BuiltinCall(Node):
- def __init__(self, s, loc, toks):
- self.name = toks[0]
- self.args = toks[1:]
- super().__init__(s, loc, toks)
- class FunctionCall(Node):
- def __init__(self, s, loc, toks):
- self.name = toks[0]
- super().__init__(s, loc, toks)
- class Register(Node):
- def __init__(self, s, loc, toks):
- self.r = toks[0]
- super().__init__(s, loc, toks)
- class Name(Node):
- def __init__(self, s, loc, toks):
- self.n = toks[0]
- super().__init__(s, loc, toks)
- class Variable(Node):
- def __init__(self, s, loc, toks):
- self.v = toks[0]
- super().__init__(s, loc, toks)
- class String(Node):
- def __init__(self, s, loc, toks):
- self.s = toks[0][1:-1]
- super().__init__(s, loc, toks)
- class Hex(Node):
- def __init__(self, s, loc, toks):
- self.h = toks[0]
- super().__init__(s, loc, toks)
- @property
- def i(self):
- return int(self.h, 16)
- class Integer(Node):
- def __int__(self, s, loc, toks):
- super().__init__(s, loc, toks)
- @property
- def i(self):
- return int(self.children[0])
- class MemoryLocation(Node):
- def __init__(self, s, loc, toks):
- if len(toks) == 1:
- self.location = toks[0]
- self.simple = True
- else:
- self.left, self.op, self.right = toks
- self.simple = False
- super().__init__(s, loc, toks)
- class ForLoop(Node):
- def __init__(self, s, loc, toks):
- self.targets, self.iterator, self.body = toks
- super().__init__(s, loc, toks)
- class FunctionDefinition(Node):
- def __init__(self, s, loc, toks):
- self.alias = toks[0]
- self.body = toks[1:]
- super().__init__(s, loc, toks)
- class Import(Node):
- def __init__(self, s, loc, toks):
- self.module = '.'.join(toks[0])
- super().__init__(s, loc, toks)
- class Data(Node):
- def __init__(self, s, loc, toks):
- self.alias = toks[0]
- self.values = toks[1:]
- super().__init__(s, loc, toks)
- indentStack = [1]
- def checkPeerIndent(s,l,t):
- curCol = col(l,s)
- if curCol != indentStack[-1]:
- if (not indentStack) or curCol > indentStack[-1]:
- raise ParseFatalException(s,l,"illegal nesting")
- raise ParseException(s,l,"not a peer entry")
- def checkSubIndent(s,l,t):
- curCol = col(l,s)
- if curCol > indentStack[-1]:
- indentStack.append( curCol )
- else:
- raise ParseException(s,l,"not a subentry")
- def checkUnindent(s,l,t):
- if l >= len(s): return
- curCol = col(l,s)
- if not(curCol < indentStack[-1] and curCol <= indentStack[-2]):
- raise ParseException(s,l,"not an unindent")
- def doUnindent():
- indentStack.pop()
- INDENT = lineEnd.suppress() + empty + empty.copy().setParseAction(checkSubIndent)
- UNDENT = FollowedBy(empty).setParseAction(checkUnindent)
- UNDENT.setParseAction(doUnindent)
- stmt = Forward()
- suite = OneOrMore(empty + stmt.setParseAction(checkPeerIndent))
- register = Register.grammar(Word(ascii_uppercase, exact=1))
- _nameish = Word(alphas + '_', alphanums + '_')
- name = Name.grammar(delimitedList(_nameish, '.', True))
- func_decl = Suppress("def") + _nameish + Suppress(":")
- func_def = FunctionDefinition.grammar(func_decl + INDENT + suite + UNDENT)
- alias_identifier = Alias.grammar(_nameish)
- maindef = Main.grammar(Suppress('main:') + INDENT + suite + UNDENT)
- string = String.grammar(dblQuotedString) | String.grammar(sglQuotedString)
- numeric = Hex.grammar(Combine('0x' + Word(hexnums, exact=4))) | Integer.grammar(Word(nums))
- constant = string | numeric
- memloc = MemoryLocation.grammar(Suppress('[') + (register | numeric) + Optional('+' + (register | numeric)) + Suppress(']'))
- func_call = FunctionCall.grammar(name + Suppress("()"))
- builtin_names = Forward()
- for key in BUILTINS:
- builtin_names |= Word(key)
- builtin_call = BuiltinCall.grammar(builtin_names + Suppress("(") + Optional(delimitedList(constant)) + Suppress(")"))
- operand = builtin_call | func_call | constant
- expr = Expression.grammar(operatorPrecedence(operand, [
- (Literal('<<'), 2, opAssoc.LEFT),
- (Literal('|'), 2, opAssoc.LEFT),
- ]))
- for_decl = Suppress('for') + Group(delimitedList(register)) + Suppress('in') + (string | alias_identifier) + Suppress(':')
- for_loop = ForLoop.grammar(for_decl + INDENT + Group(suite) + UNDENT)
- math_operator = Literal('+') | Literal('-') | Literal('*') | Literal('/') | Literal('|') | Literal('&') | Literal('<<') | Literal('>>')
- rvalue = (alias_identifier | memloc | numeric | expr)
- assignment = Assignment.grammar(register + Suppress("=") + rvalue)
- aug_assignment = AugmentedAssignment.grammar(register + math_operator + Suppress('=') + rvalue)
- mem_assignment = MemoryAssignment.grammar(memloc + Suppress('=') + (register | numeric))
- stmt << (assignment | aug_assignment | mem_assignment | for_loop | func_call)
- alias_rvalue = (builtin_call | name | numeric | expr)
- aliasdef = AliasDefinition.grammar(alias_identifier + Suppress("=") + alias_rvalue)
- import_def = Import.grammar(Suppress('import') + Group(delimitedList(Word(alphas, alphanums), '.')))
- data_rvalue = delimitedList(alias_rvalue | string, ',')
- datadef = Data.grammar(alias_identifier + Suppress("= data") + data_rvalue)
- grammar = Module.grammar(ZeroOrMore(import_def) + ZeroOrMore(datadef | aliasdef) + Optional(maindef) + ZeroOrMore(func_def))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement