67 lines
2.0 KiB
Python
67 lines
2.0 KiB
Python
from smnp.ast.node.model import Node
|
|
from smnp.ast.parser import Parser
|
|
from smnp.token.tokenizer import tokenize
|
|
from smnp.token.type import TokenType
|
|
|
|
|
|
class Atom(Node):
|
|
def __init__(self, value, pos):
|
|
super().__init__(pos)
|
|
self.children = [value]
|
|
|
|
@property
|
|
def value(self):
|
|
return self[0]
|
|
|
|
class Operation(Node):
|
|
def __init__(self, left, op, right, pos):
|
|
super().__init__(pos)
|
|
self.children = [left, op, right]
|
|
|
|
@property
|
|
def left(self):
|
|
return self[0]
|
|
|
|
@property
|
|
def operator(self):
|
|
return self[1]
|
|
|
|
@property
|
|
def right(self):
|
|
return self[2]
|
|
|
|
def atom():
|
|
return Parser.oneOfTerminals(TokenType.INTEGER, TokenType.NOTE, TokenType.STRING, createNode=lambda val, pos: Atom(val, pos))
|
|
|
|
def chain():
|
|
return Parser.leftAssociativeOperatorParser(atom(), [TokenType.DOT], atom(), lambda left, op, right: Operation(left, op, right, op.pos), name="chain")
|
|
|
|
def factor():
|
|
return Parser.leftAssociativeOperatorParser(chain(), [TokenType.DOUBLE_ASTERISK], chain(), lambda left, op, right: Operation(left, op, right, op.pos), name="factor")
|
|
|
|
def term():
|
|
return Parser.leftAssociativeOperatorParser(factor(), [TokenType.ASTERISK, TokenType.SLASH], factor(), lambda left, op, right: Operation(left, op, right, op.pos), name="term")
|
|
|
|
def expr():
|
|
return Parser.leftAssociativeOperatorParser(term(), [TokenType.PLUS, TokenType.MINUS], term(), lambda left, op, right: Operation(left, op, right, op.pos), name="expr")
|
|
#
|
|
def evaluate(node):
|
|
if type(node) == Atom:
|
|
return node.value
|
|
lhs = evaluate(node.left)
|
|
rhs = evaluate(node.right)
|
|
return {
|
|
"+": int(lhs) + int(rhs),
|
|
"*": int(lhs) * int(rhs),
|
|
"-": int(lhs) - int(rhs),
|
|
"/": int(lhs) / int(rhs),
|
|
"**": int(lhs) ** int(rhs)
|
|
}[node.operator.value]
|
|
|
|
def draft():
|
|
|
|
tokens = tokenize(['"fesf fe" + "fsefsef" + "fsefs"'])
|
|
e = expr()
|
|
node = e(tokens).node
|
|
node.print()
|