Changed the way to handle default tag in AST.

This commit is contained in:
yhirose 2015-06-04 14:12:09 -04:00
parent e0c657e52c
commit b91efa1489
3 changed files with 37 additions and 32 deletions

View File

@ -4,6 +4,7 @@ using namespace peglib;
using namespace std;
static auto g_grammar = R"(
PROGRAM <- _ STATEMENTS
STATEMENTS <- (EXPRESSION (';' _)?)*
@ -53,12 +54,12 @@ static auto g_grammar = R"(
EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
)";
peg& get_parser()
{
static peg parser;
static peg parser;
static bool initialized = false;
if (!initialized) {
@ -73,28 +74,30 @@ peg& get_parser()
}
parser.enable_ast({
{ "STATEMENTS", Statements },
{ "WHILE", While },
{ "ASSIGNMENT", Assignment },
{ "IF", If },
{ "FUNCTION", Function },
{ "PARAMETERS", Undefined },
{ "FUNCTION_CALL", FunctionCall },
{ "ARGUMENTS", Undefined },
{ "PRIMARY", LogicalOr, true },
{ "LOGICAL_OR", LogicalAnd, true },
{ "LOGICAL_AND", Condition, true },
{ "CONDITION", BinExpresion, true },
{ "TERM", UnaryPlus, true },
{ "UNARY_PLUS", UnaryMinus, true },
{ "UNARY_MINUS", UnaryNot, true },
{ "UNARY_NOT", BinExpresion, true },
{ "NUMBER", Number },
{ "BOOLEAN", Boolean },
{ "IDENTIFIER", Identifier },
{ "INTERPOLATED_STRING", InterpolatedString },
},
Undefined);
/*
Definition, Tag Optimize
---------------------- ------------------ ---------- */
{ "STATEMENTS", Statements },
{ "WHILE", While },
{ "ASSIGNMENT", Assignment },
{ "IF", If },
{ "FUNCTION", Function },
{ "PARAMETERS", Default },
{ "FUNCTION_CALL", FunctionCall },
{ "ARGUMENTS", Default },
{ "PRIMARY", LogicalOr, true },
{ "LOGICAL_OR", LogicalAnd, true },
{ "LOGICAL_AND", Condition, true },
{ "CONDITION", BinExpresion, true },
{ "TERM", UnaryPlus, true },
{ "UNARY_PLUS", UnaryMinus, true },
{ "UNARY_MINUS", UnaryNot, true },
{ "UNARY_NOT", BinExpresion, true },
{ "NUMBER", Number },
{ "BOOLEAN", Boolean },
{ "IDENTIFIER", Identifier },
{ "INTERPOLATED_STRING", InterpolatedString },
});
}
return parser;

View File

@ -2,7 +2,7 @@
enum AstTag
{
Undefined,
Default = peglib::Ast::DefaultTag,
Statements, While, If, FunctionCall, Assignment,
LogicalOr, LogicalAnd, Condition, UnaryPlus, UnaryMinus, UnaryNot, BinExpresion,
Identifier, InterpolatedString,

View File

@ -1834,6 +1834,8 @@ private:
struct Ast
{
static const int DefaultTag = -1;
Ast(const char* _name, int _tag, const std::vector<std::shared_ptr<Ast>>& _nodes)
: name(_name), tag(_tag), is_token(false), nodes(_nodes) {}
@ -2031,16 +2033,16 @@ public:
bool optimize;
};
peg& enable_ast(std::initializer_list<AstNodeInfo> list, int tag) {
peg& enable_ast(std::initializer_list<AstNodeInfo> list) {
for (const auto& info: list) {
ast_node(info);
}
ast_end(tag);
ast_end();
return *this;
}
peg& enable_ast() {
ast_end(-1);
ast_end();
return *this;
}
@ -2073,21 +2075,21 @@ private:
};
}
void ast_end(int tag) {
void ast_end() {
for (auto& x: *grammar_) {
const auto& name = x.first;
auto& def = x.second;
auto& action = def.actions.front();
if (!action) {
action = [tag, name](const SemanticValues& sv) {
action = [name](const SemanticValues& sv) {
if (sv.is_token()) {
return std::make_shared<Ast>(name.c_str(), tag, std::string(sv.s, sv.n));
return std::make_shared<Ast>(name.c_str(), Ast::DefaultTag, std::string(sv.s, sv.n));
}
if (sv.size() == 1) {
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
return ast;
}
return std::make_shared<Ast>(name.c_str(), tag, sv.map<std::shared_ptr<Ast>>());
return std::make_shared<Ast>(name.c_str(), Ast::DefaultTag, sv.map<std::shared_ptr<Ast>>());
};
}
}