Create parsers for literals (atoms)
This commit is contained in:
57
smnp/ast/node/atom.py
Normal file
57
smnp/ast/node/atom.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from smnp.ast.node.model import Node
|
||||
from smnp.ast.parser import Parser
|
||||
from smnp.token.type import TokenType
|
||||
|
||||
|
||||
class Atom(Node):
|
||||
def __init__(self, pos):
|
||||
super().__init__(pos)
|
||||
self.children = [None]
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self[0]
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self[0] = value
|
||||
|
||||
@classmethod
|
||||
def withValue(cls, value, pos):
|
||||
node = cls(pos)
|
||||
node.value = value
|
||||
return node
|
||||
|
||||
|
||||
class IntegerLiteral(Atom):
|
||||
pass
|
||||
|
||||
|
||||
class StringLiteral(Atom):
|
||||
pass
|
||||
|
||||
|
||||
class NoteLiteral(Atom):
|
||||
pass
|
||||
|
||||
|
||||
class BoolLiteral(Atom):
|
||||
pass
|
||||
|
||||
integerParser = Parser.oneOf(
|
||||
Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)),
|
||||
Parser.allOf(
|
||||
Parser.terminalParser(TokenType.MINUS),
|
||||
Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)),
|
||||
createNode=lambda minus, integer: IntegerLiteral.withValue(-integer.value, minus.pos)
|
||||
)
|
||||
)
|
||||
|
||||
parser = Parser.oneOf(
|
||||
integerParser,
|
||||
Parser.terminalParser(TokenType.STRING, lambda val, pos: StringLiteral.withValue(val, pos)),
|
||||
Parser.terminalParser(TokenType.NOTE, lambda val, pos: NoteLiteral.withValue(val, pos)),
|
||||
Parser.terminalParser(TokenType.BOOL, lambda val, pos: BoolLiteral.withValue(val, pos)),
|
||||
)
|
||||
|
||||
AtomParser = Parser(parser, "atom", parser)
|
||||
2
smnp/ast/node/chain.py
Normal file
2
smnp/ast/node/chain.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class Node:
|
||||
self._print(first=True)
|
||||
|
||||
def _print(self, prefix="", last=True, first=False):
|
||||
print(prefix, '' if first else '└─' if last else '├─', self.__class__.__name__, sep="")
|
||||
print(prefix, '' if first else '└─' if last else '├─', self.__class__.__name__, f" (line {self.pos[0]+1}, col {self.pos[1]+1})", sep="")
|
||||
prefix += ' ' if last else '│ '
|
||||
for i, child in enumerate(self.children):
|
||||
last = i == len(self.children) - 1
|
||||
|
||||
@@ -1,32 +1,44 @@
|
||||
from smnp.ast.node.expression import ExpressionNode
|
||||
from smnp.ast.node.extend import ExtendNode
|
||||
from smnp.ast.node.function import FunctionDefinitionNode
|
||||
from smnp.ast.node.imports import ImportNode
|
||||
from smnp.ast.node.atom import AtomParser
|
||||
from smnp.ast.node.model import Node, ParseResult
|
||||
from smnp.ast.node.statement import StatementNode
|
||||
from smnp.ast.parser import Parser
|
||||
from smnp.error.syntax import SyntaxException
|
||||
|
||||
|
||||
class Program(Node):
|
||||
def __init__(self):
|
||||
super().__init__((-1, -1))
|
||||
|
||||
@classmethod
|
||||
def _parse(cls, input):
|
||||
def parseToken(input):
|
||||
return Parser.oneOf(
|
||||
FunctionDefinitionNode.parse,
|
||||
ExtendNode.parse,
|
||||
ExpressionNode.parse,
|
||||
ImportNode.parse,
|
||||
StatementNode.parse,
|
||||
exception = SyntaxException(f"Invalid statement: {input.currentToEndOfLine()}", input.current().pos)
|
||||
)(input)
|
||||
def parse(input):
|
||||
root = Program()
|
||||
while input.hasCurrent():
|
||||
result = Parser.oneOf(
|
||||
# Start Symbol
|
||||
|
||||
root = Program()
|
||||
while input.hasCurrent():
|
||||
result = parseToken(input)
|
||||
if result.result:
|
||||
root.append(result.node)
|
||||
return ParseResult.OK(root)
|
||||
|
||||
#TODO -> temporary (to remove):
|
||||
AtomParser
|
||||
)(input)
|
||||
|
||||
if result.result:
|
||||
root.append(result.node)
|
||||
|
||||
return ParseResult.OK(root)
|
||||
|
||||
ProgramParser = Parser(parse, name="program")
|
||||
# @classmethod
|
||||
# def _parse(cls, input):
|
||||
# def parseToken(input):
|
||||
# return Parser.oneOf(
|
||||
# FunctionDefinitionNode.parse,
|
||||
# ExtendNode.parse,
|
||||
# ExpressionNode.parse,
|
||||
# ImportNode.parse,
|
||||
# StatementNode.parse,
|
||||
# exception = SyntaxException(f"Invalid statement: {input.currentToEndOfLine()}", input.current().pos)
|
||||
# )(input)
|
||||
#
|
||||
# root = Program()
|
||||
# while input.hasCurrent():
|
||||
# result = parseToken(input)
|
||||
# if result.result:
|
||||
# root.append(result.node)
|
||||
# return ParseResult.OK(root)
|
||||
@@ -5,8 +5,8 @@ from smnp.error.syntax import SyntaxException
|
||||
|
||||
|
||||
def parse(input):
|
||||
from smnp.ast.node.program import Program
|
||||
return Program.parse(input).node
|
||||
from smnp.ast.node.program import ProgramParser
|
||||
return ProgramParser(input).node
|
||||
|
||||
|
||||
class Parser:
|
||||
@@ -58,7 +58,7 @@ class Parser:
|
||||
|
||||
return ParseResult.FAIL()
|
||||
|
||||
return Parser(parse, expectedType.name.lower())
|
||||
return Parser(parse, name=expectedType.name.lower())
|
||||
|
||||
# oneOf -> a | b | c | ...
|
||||
@staticmethod
|
||||
|
||||
@@ -31,7 +31,7 @@ class Operation(Node):
|
||||
return self[2]
|
||||
|
||||
def atom():
|
||||
return Parser.terminalParser(TokenType.INTEGER, lambda val, pos: Atom(val, pos))
|
||||
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")
|
||||
@@ -60,8 +60,7 @@ def evaluate(node):
|
||||
|
||||
def draft():
|
||||
|
||||
tokens = tokenize(['2**3/2 + 10 - 2'])
|
||||
tokens = tokenize(['"fesf fe" + "fsefsef" + "fsefs"'])
|
||||
e = expr()
|
||||
node = e(tokens).node
|
||||
node.print()
|
||||
print(evaluate(node))
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from smnp.calc import draft
|
||||
import sys
|
||||
|
||||
from smnp.error.base import SmnpException
|
||||
from smnp.program.interpreter import Interpreter
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
#stdLibraryEnv = loadStandardLibrary()
|
||||
#Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=False, baseEnvironment=stdLibraryEnv)
|
||||
draft()
|
||||
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=False, baseEnvironment=None)
|
||||
#draft()
|
||||
|
||||
except SmnpException as e:
|
||||
print(e.message())
|
||||
|
||||
Reference in New Issue
Block a user