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; using namespace std;
static auto g_grammar = R"( static auto g_grammar = R"(
PROGRAM <- _ STATEMENTS PROGRAM <- _ STATEMENTS
STATEMENTS <- (EXPRESSION (';' _)?)* STATEMENTS <- (EXPRESSION (';' _)?)*
@ -53,12 +54,12 @@ static auto g_grammar = R"(
EndOfLine <- '\r\n' / '\n' / '\r' EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !. EndOfFile <- !.
Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile) Comment <- '/*' (!'*/' .)* '*/' / ('#' / '//') (!(EndOfLine / EndOfFile) .)* (EndOfLine / EndOfFile)
)"; )";
peg& get_parser() peg& get_parser()
{ {
static peg parser; static peg parser;
static bool initialized = false; static bool initialized = false;
if (!initialized) { if (!initialized) {
@ -73,14 +74,17 @@ peg& get_parser()
} }
parser.enable_ast({ parser.enable_ast({
/*
Definition, Tag Optimize
---------------------- ------------------ ---------- */
{ "STATEMENTS", Statements }, { "STATEMENTS", Statements },
{ "WHILE", While }, { "WHILE", While },
{ "ASSIGNMENT", Assignment }, { "ASSIGNMENT", Assignment },
{ "IF", If }, { "IF", If },
{ "FUNCTION", Function }, { "FUNCTION", Function },
{ "PARAMETERS", Undefined }, { "PARAMETERS", Default },
{ "FUNCTION_CALL", FunctionCall }, { "FUNCTION_CALL", FunctionCall },
{ "ARGUMENTS", Undefined }, { "ARGUMENTS", Default },
{ "PRIMARY", LogicalOr, true }, { "PRIMARY", LogicalOr, true },
{ "LOGICAL_OR", LogicalAnd, true }, { "LOGICAL_OR", LogicalAnd, true },
{ "LOGICAL_AND", Condition, true }, { "LOGICAL_AND", Condition, true },
@ -93,8 +97,7 @@ peg& get_parser()
{ "BOOLEAN", Boolean }, { "BOOLEAN", Boolean },
{ "IDENTIFIER", Identifier }, { "IDENTIFIER", Identifier },
{ "INTERPOLATED_STRING", InterpolatedString }, { "INTERPOLATED_STRING", InterpolatedString },
}, });
Undefined);
} }
return parser; return parser;

View File

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

View File

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