Updated documentation and examples.

This commit is contained in:
yhirose 2015-03-11 13:53:24 -04:00
parent e30b4a281f
commit 6c59c02ea9
4 changed files with 22 additions and 54 deletions

View File

@ -21,16 +21,14 @@ How to use
This is a simple calculator sample. It shows how to define grammar, associate samantic actions to the grammar and handle semantic values. This is a simple calculator sample. It shows how to define grammar, associate samantic actions to the grammar and handle semantic values.
```c++ ```c++
#include <assert.h>
// (1) Include the header file // (1) Include the header file
#include <peglib.h> #include <peglib.h>
#include <assert.h>
using namespace peglib; using namespace peglib;
using namespace std; using namespace std;
int main(void) { int main(void) {
// (2) Make a parser // (2) Make a parser
auto syntax = R"( auto syntax = R"(
# Grammar for Calculator... # Grammar for Calculator...
@ -42,22 +40,20 @@ int main(void) {
peg parser(syntax); peg parser(syntax);
parser.packrat_parsing(true); // Enable packrat parsing
// (3) Setup an action // (3) Setup an action
parser["Additive"] = { parser["Additive"] = {
nullptr, // Default action nullptr, // Default action
[](const SemanticValues& sv) { [](const SemanticValues& sv) {
return sv[0].get<int>() + sv[1].get<int>(); // 1st choice return sv[0].get<int>() + sv[1].get<int>(); // "Multitive '+' Additive"
}, },
[](const SemanticValues& sv) { return sv[0]; } // 2nd choice [](const SemanticValues& sv) { return sv[0]; } // "Multitive"
}; };
parser["Multitive"] = [](const SemanticValues& sv) { parser["Multitive"] = [](const SemanticValues& sv) {
switch (sv.choice) { switch (sv.choice) {
case 0: // 1st choice case 0: // "Multitive '+' Additive"
return sv[0].get<int>() * sv[1].get<int>(); return sv[0].get<int>() * sv[1].get<int>();
default: // 2nd choice default: // "Multitive"
return sv[0].get<int>(); return sv[0].get<int>();
} }
}; };
@ -67,6 +63,8 @@ int main(void) {
}; };
// (4) Parse // (4) Parse
parser.packrat_parsing(true); // Enable packrat parsing.
int val; int val;
parser.parse("(1+2)*3", val); parser.parse("(1+2)*3", val);

View File

@ -12,17 +12,6 @@
using namespace peglib; using namespace peglib;
using namespace std; using namespace std;
//
// PEG syntax:
//
// EXPRESSION <- _ TERM (TERM_OPERATOR TERM)*
// TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
// FACTOR <- NUMBER / '(' _ EXPRESSION ')' _
// TERM_OPERATOR <- < [-+] > _
// FACTOR_OPERATOR <- < [/*] > _
// NUMBER <- < [0-9]+ > _
// ~_ <- [ \t\r\n]*
//
int main(int argc, const char** argv) int main(int argc, const char** argv)
{ {
if (argc < 2 || string("--help") == argv[1]) { if (argc < 2 || string("--help") == argv[1]) {
@ -30,8 +19,6 @@ int main(int argc, const char** argv)
return 1; return 1;
} }
const char* s = argv[1];
auto reduce = [](const SemanticValues& sv) -> long { auto reduce = [](const SemanticValues& sv) -> long {
auto result = sv[0].get<long>(); auto result = sv[0].get<long>();
for (auto i = 1u; i < sv.size(); i += 2) { for (auto i = 1u; i < sv.size(); i += 2) {
@ -47,7 +34,7 @@ int main(int argc, const char** argv)
return result; return result;
}; };
const char* syntax = peg parser(
" EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* " " EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* "
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " " TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* "
" FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ " " FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ "
@ -55,9 +42,7 @@ int main(int argc, const char** argv)
" FACTOR_OPERATOR <- < [/*] > _ " " FACTOR_OPERATOR <- < [/*] > _ "
" NUMBER <- < [0-9]+ > _ " " NUMBER <- < [0-9]+ > _ "
" ~_ <- [ \t\r\n]* " " ~_ <- [ \t\r\n]* "
; );
peg parser(syntax);
parser["EXPRESSION"] = reduce; parser["EXPRESSION"] = reduce;
parser["TERM"] = reduce; parser["TERM"] = reduce;
@ -65,9 +50,10 @@ int main(int argc, const char** argv)
parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; }; parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; };
parser["NUMBER"] = [](const char* s, size_t n) { return atol(s); }; parser["NUMBER"] = [](const char* s, size_t n) { return atol(s); };
auto expr = argv[1];
long val = 0; long val = 0;
if (parser.parse(s, val)) { if (parser.parse(expr, val)) {
cout << s << " = " << val << endl; cout << expr << " = " << val << endl;
return 0; return 0;
} }

View File

@ -29,8 +29,6 @@ int main(int argc, const char** argv)
return 1; return 1;
} }
const char* s = argv[1];
auto reduce = [](const SemanticValues& sv) -> long { auto reduce = [](const SemanticValues& sv) -> long {
auto result = sv[0].get<long>(); auto result = sv[0].get<long>();
for (auto i = 1u; i < sv.size(); i += 2) { for (auto i = 1u; i < sv.size(); i += 2) {
@ -55,9 +53,10 @@ int main(int argc, const char** argv)
FACTOR_OPERATOR <= cls("*/"), [](const char* s, size_t n) { return (char)*s; }; FACTOR_OPERATOR <= cls("*/"), [](const char* s, size_t n) { return (char)*s; };
NUMBER <= oom(cls("0-9")), [](const char* s, size_t n) { return atol(s); }; NUMBER <= oom(cls("0-9")), [](const char* s, size_t n) { return atol(s); };
auto expr = argv[1];
long val = 0; long val = 0;
if (EXPRESSION.parse_and_get_value(s, val).ret) { if (EXPRESSION.parse_and_get_value(expr, val).ret) {
cout << s << " = " << val << endl; cout << expr << " = " << val << endl;
return 0; return 0;
} }

View File

@ -12,24 +12,12 @@
using namespace peglib; using namespace peglib;
using namespace std; using namespace std;
//
// PEG syntax:
//
// EXPRESSION <- _ TERM (TERM_OPERATOR TERM)*
// TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
// FACTOR <- NUMBER / '(' _ EXPRESSION ')' _
// TERM_OPERATOR <- < [-+] > _
// FACTOR_OPERATOR <- < [/*] > _
// NUMBER <- < [0-9]+ > _
// ~_ <- [ \t\r\n]*
//
template <typename T, typename U, typename F> template <typename T, typename U, typename F>
static U reduce(T i, T end, U val, F f) { static U reduce(T i, T end, U val, F f) {
if (i == end) { if (i == end) {
return val; return val;
} }
std::tie(val, i) = f(val, i); tie(val, i) = f(val, i);
return reduce(i, end, val, f); return reduce(i, end, val, f);
}; };
@ -96,9 +84,7 @@ int main(int argc, const char** argv)
return 1; return 1;
} }
const char* s = argv[1]; peg parser(
const char* syntax =
" EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* " " EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* "
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " " TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* "
" FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ " " FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ "
@ -106,9 +92,7 @@ int main(int argc, const char** argv)
" FACTOR_OPERATOR <- < [/*] > _ " " FACTOR_OPERATOR <- < [/*] > _ "
" NUMBER <- < [0-9]+ > _ " " NUMBER <- < [0-9]+ > _ "
" ~_ <- [ \t\r\n]* " " ~_ <- [ \t\r\n]* "
; );
peg parser(syntax);
parser["EXPRESSION"] = ast_ope::create; parser["EXPRESSION"] = ast_ope::create;
parser["TERM"] = ast_ope::create; parser["TERM"] = ast_ope::create;
@ -116,9 +100,10 @@ int main(int argc, const char** argv)
parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return *s; }; parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return *s; };
parser["NUMBER"] = ast_num::create; parser["NUMBER"] = ast_num::create;
auto expr = argv[1];
shared_ptr<ast_node> ast; shared_ptr<ast_node> ast;
if (parser.parse(s, ast)) { if (parser.parse(expr, ast)) {
cout << s << " = " << ast->eval() << endl; cout << expr << " = " << ast->eval() << endl;
return 0; return 0;
} }