From c3b556d99f80e4527682691c6ce33a8420e6c331 Mon Sep 17 00:00:00 2001 From: Evan Smal Date: Wed, 6 Sep 2023 17:31:49 -0400 Subject: [PATCH] Add entire PEG grammar --- src/grammar.hpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++--- src/main.cpp | 25 ++++++++++++++++++-- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/grammar.hpp b/src/grammar.hpp index c0ebb05..a84a6c9 100644 --- a/src/grammar.hpp +++ b/src/grammar.hpp @@ -7,27 +7,33 @@ const auto GRAMMAR = ast::Grammar( ast::Sequence(ast::Identifier("Spacing"), ast::OneOrMore(ast::Identifier("Definition")), ast::Identifier("EndOfFile"))), + ast::Definition(ast::Identifier("Definition"), ast::Sequence(ast::Identifier("Identifier"), ast::Identifier("LEFT_ARROW"), ast::Identifier("Expression"))), + ast::Definition( ast::Identifier("Expression"), ast::Sequence(ast::Identifier("Sequence"), ast::ZeroOrMore(ast::Sequence(ast::Identifier("SLASH"), ast::Identifier("Sequence"))))), + ast::Definition(ast::Identifier("Sequence"), ast::ZeroOrMore(ast::Identifier("Prefix"))), + ast::Definition(ast::Identifier("Prefix"), ast::Sequence(ast::Optional(ast::Alternative(ast::Identifier("AND"), ast::Identifier("NOT"))), ast::Identifier("Suffix"))), + ast::Definition( ast::Identifier("Suffix"), ast::Sequence(ast::Identifier("Primary"), ast::Optional(ast::Alternative(ast::Identifier("QUESTION"), ast::Identifier("STAR"), ast::Identifier("PLUS"))))), + ast::Definition( ast::Identifier("Primary"), ast::Alternative(ast::Sequence(ast::Identifier("Identifier"), @@ -38,16 +44,20 @@ const auto GRAMMAR = ast::Grammar( ast::Identifier("Literal"), ast::Identifier("Class"), ast::Identifier("DOT"))), + ast::Definition(ast::Identifier("Identifier"), ast::Sequence(ast::Identifier("IdentStart"), ast::ZeroOrMore(ast::Identifier("IdentCont")), ast::Identifier("Spacing"))), + ast::Definition( ast::Identifier("IdentStart"), ast::Class({ast::Range("a", "z"), ast::Range("A", "Z")}, {ast::Literal("_")})), + ast::Definition(ast::Identifier("IdentCont"), ast::Alternative(ast::Identifier("IdentStart"), ast::Class({ast::Range("0", "9")}, {}))), + ast::Definition( ast::Identifier("Literal"), ast::Alternative(ast::Sequence(ast::Class({}, {ast::Literal("'")}), @@ -62,9 +72,7 @@ const auto GRAMMAR = ast::Grammar( ast::Identifier("Char"))), ast::Class({}, {ast::Literal("\"")}), ast::Identifier("Spacing")))), - ast::Definition(ast::Identifier("IdentCont"), - ast::Alternative(ast::Identifier("IdentStart"), - ast::Class({ast::Range("0", "9")}, {}))), + ast::Definition( ast::Identifier("Class"), ast::Sequence(ast::Literal("["), @@ -72,6 +80,7 @@ const auto GRAMMAR = ast::Grammar( ast::Identifier("Range"))), ast::Literal("]"), ast::Identifier("Spacing"))), + ast::Definition(ast::Identifier("Range"), ast::Alternative(ast::Sequence(ast::Identifier("Char"), ast::Literal("-"), @@ -99,4 +108,51 @@ const auto GRAMMAR = ast::Grammar( ast::Optional(ast::Class({ast::Range("0", "7")}, {}))), ast::Sequence(ast::Literal("\\"), ast::Literal("-")), ast::Sequence(ast::Not(ast::Literal("\\")), ast::Dot()))), + + ast::Definition(ast::Identifier("LEFT_ARROW"), + ast::Sequence(ast::Literal("<-"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("SLASH"), + ast::Sequence(ast::Literal("/"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("AND"), + ast::Sequence(ast::Literal("&"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("NOT"), + ast::Sequence(ast::Literal("!"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("QUESTION"), + ast::Sequence(ast::Literal("?"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("STAR"), + ast::Sequence(ast::Literal("*"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("PLUS"), + ast::Sequence(ast::Literal("+"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("OPEN"), + ast::Sequence(ast::Literal("("), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("CLOSE"), + ast::Sequence(ast::Literal(")"), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("DOT"), + ast::Sequence(ast::Literal("."), ast::Identifier("Spacing"))), + + ast::Definition(ast::Identifier("Spacing"), + ast::ZeroOrMore(ast::Alternative(ast::Identifier("Space"), + ast::Identifier("Comment")))), + ast::Definition(ast::Identifier("Comment"), + ast::Sequence(ast::Literal("#"), + ast::ZeroOrMore(ast::Sequence( + ast::Not(ast::Identifier("EndOfLine")), + ast::Dot())))), + ast::Definition(ast::Identifier("Space"), + ast::Alternative(ast::Literal(" "), + ast::Literal("\t"), + ast::Identifier("EndOfLine"))), + ast::Definition( + ast::Identifier("EndOfLine"), + ast::Alternative(ast::Literal("\r\n"), ast::Literal("\n"), ast::Literal("\r"))), + ast::Definition(ast::Identifier("EndOfFile"), ast::Not(ast::Dot()))); diff --git a/src/main.cpp b/src/main.cpp index 7173a70..10b36ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,8 @@ #include "ast.hpp" #include "combinator.hpp" #include "generator.hpp" -#include "parser.hpp" #include "grammar.hpp" +#include "parser.hpp" #include #include @@ -23,7 +23,28 @@ auto main() -> int std::cout << "Created grammar" << std::endl; - std::cout << ast::ToString(GRAMMAR) << std::endl; + const auto peg = Generate(GRAMMAR); + + const std::string grammar = "Expression <- Number BinaryOperand Number\n" + "BinaryOperand <- Plus / Minus\n" + "Plus <- '+'\n" + "Minus <- '-'\n" + "Number <- [0-9]\n"; + + const auto parse = peg.Get("Grammar")(grammar); + if (std::holds_alternative(parse)) + { + std::cout << "Parser success!" << std::endl; + const auto &success = std::get(parse); + for (const auto &node : success.node) + { + Dump(node); + } + } + else + { + std::cout << "Parser failure!" << std::endl; + } const auto collection = Generate(g);