diff --git a/smnp/newast/node/block.py b/smnp/newast/node/block.py new file mode 100644 index 0000000..577bd3f --- /dev/null +++ b/smnp/newast/node/block.py @@ -0,0 +1,20 @@ +from smnp.newast.node.statement import StatementNode +from smnp.newast.parser import Parser +from smnp.token.type import TokenType + + +class BlockNode(StatementNode): + + @classmethod + def _parse(cls, input): + def createNode(start, items, end): + node = StatementNode(start.pos) + node.children = items + return node + + return Parser.loop( + Parser.terminalParser(TokenType.OPEN_BRACKET), + StatementNode.parse, + Parser.terminalParser(TokenType.CLOSE_BRACKET), + createNode=createNode + )(input) \ No newline at end of file diff --git a/smnp/newast/node/program.py b/smnp/newast/node/program.py index c96e6d0..b72ce33 100644 --- a/smnp/newast/node/program.py +++ b/smnp/newast/node/program.py @@ -1,6 +1,7 @@ from smnp.error.syntax import SyntaxException from smnp.newast.node.expression import ExpressionNode from smnp.newast.node.model import Node, ParseResult +from smnp.newast.node.statement import StatementNode from smnp.newast.parser import Parser @@ -13,6 +14,7 @@ class Program(Node): def parseToken(input): return Parser.oneOf( ExpressionNode.parse, + StatementNode.parse, exception = SyntaxException("Unknown statement") )(input) diff --git a/smnp/newast/node/statement.py b/smnp/newast/node/statement.py new file mode 100644 index 0000000..9dbbc47 --- /dev/null +++ b/smnp/newast/node/statement.py @@ -0,0 +1,15 @@ +from smnp.newast.node.model import Node +from smnp.newast.parser import Parser + + +class StatementNode(Node): + + @classmethod + def _parse(cls, input): + from smnp.newast.node.block import BlockNode + from smnp.newast.node.expression import ExpressionNode + + return Parser.oneOf( + BlockNode.parse, + ExpressionNode.parse + )(input) \ No newline at end of file diff --git a/smnp/newast/parser.py b/smnp/newast/parser.py index 99e7c01..96c1c26 100644 --- a/smnp/newast/parser.py +++ b/smnp/newast/parser.py @@ -97,8 +97,21 @@ class Parser: return parse @staticmethod - def epsilon(): - def parser(input): - return ParseResult.OK(IgnoredNode((-1, -1))) + def loop(startParser, itemParser, endParser, createNode): + def parse(input): + items = [] + start = startParser(input) + if start.result: + while True: + end = endParser(input) + if end.result: + return ParseResult.OK(createNode(start.node, items, end.node)) + item = itemParser(input) + if not item.result: + return ParseResult.FAIL() + items.append(item.node) + + return ParseResult.FAIL() + + return parse - return parser