Added example/indent.cc

This commit is contained in:
yhirose 2022-04-02 08:12:48 -04:00
parent 82fd01f3d1
commit 199f788ad8
2 changed files with 70 additions and 0 deletions

View File

@ -17,3 +17,6 @@ target_link_libraries(calc4 ${add_link_deps})
add_executable(calc5 calc5.cc) add_executable(calc5 calc5.cc)
target_link_libraries(calc5 ${add_link_deps}) target_link_libraries(calc5 ${add_link_deps})
add_executable(indent indent.cc)
target_link_libraries(indent ${add_link_deps})

67
example/indent.cc Normal file
View File

@ -0,0 +1,67 @@
//
// indent.cc
//
// Copyright (c) 2022 Yuji Hirose. All rights reserved.
// MIT License
//
// Based on https://gist.github.com/dmajda/04002578dd41ae8190fc
#include <cstdlib>
#include <iostream>
#include <peglib.h>
using namespace peg;
int main(void) {
parser parser(R"(Start <- Statements {}
Statements <- Statement*
Statement <- Samedent (S / I)
S <- 'S' EOS { no_ast_opt }
I <- 'I' EOL Block / 'I' EOS { no_ast_opt }
Block <- Statements {}
~Samedent <- ' '* {}
~EOS <- EOL / EOF
~EOL <- '\n'
~EOF <- !.
)");
size_t indent = 0;
parser["Block"].enter = [&](const char * /*s*/, size_t /*n*/,
std::any & /*dt*/) { indent += 2; };
parser["Block"].leave = [&](const char * /*s*/, size_t /*n*/,
size_t /*matchlen*/, std::any & /*value*/,
std::any & /*dt*/) { indent -= 2; };
parser["Samedent"] = [&](const SemanticValues &vs, std::any & /*dt*/) {
if (indent != vs.sv().size()) { throw parse_error("different indent..."); }
};
parser.enable_ast();
const auto source = R"(I
S
I
I
S
S
S
S
)";
std::shared_ptr<Ast> ast;
if (parser.parse(source, ast)) {
ast = parser.optimize_ast(ast);
std::cout << ast_to_s(ast);
return 0;
}
std::cout << "syntax error..." << std::endl;
return -1;
}