From 978a8dc2744097c6212fb2ff6156a947a108464d Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 19 Aug 2022 23:11:02 -0400 Subject: [PATCH] Resolve #239 --- README.md | 34 ------------- peglib.h | 139 ------------------------------------------------------ 2 files changed, 173 deletions(-) diff --git a/README.md b/README.md index 2aae1b7..5969b3d 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,6 @@ The PEG syntax is well described on page 2 in the [document](http://www.brynosau * `label { message "..." }` (Error message instruction) * `{ no_ast_opt }` (No AST node optimazation instruction) -The following syntax is available with `CPPPEGLIB_SYMBOL_TABLE_SUPPORT`. - - * `{ declare_symbol "..." }` (Declare symbol instruction) - * `{ check_symbol "..." }` (Check symbol instruction) - 'End of Input' check will be done as default. In order to disable the check, please call `disable_eoi_check`. This library supports the linear-time parsing known as the [*Packrat*](http://pdos.csail.mit.edu/~baford/packrat/thesis/thesis.pdf) parsing. @@ -462,35 +457,6 @@ It internally calls `peg::AstOptimizer` to do the job. You can make your own AST See actual usages in the [AST calculator example](https://github.com/yhirose/cpp-peglib/blob/master/example/calc3.cc) and [PL/0 language example](https://github.com/yhirose/cpp-peglib/blob/master/pl0/pl0.cc). -Symbol Table ------------- - -NOTE: This feature is available with `CPPPEGLIB_SYMBOL_TABLE_SUPPORT`, and has [some limitations](https://github.com/yhirose/cpp-peglib/issues/231#issuecomment-1173215709). - -Simple symbol table support is available with `declare_symbol` and `check_symbol` instructions. - -```peg -S <- (Decl / Ref)* -Decl <- 'decl' symbol -Ref <- 'ref' is_symbol -Name <- < [a-zA-Z]+ > -%whitespace <- [ \t\r\n]* - -# 'var_table' is a table name. -symbol <- Name { declare_symbol var_table } # Declare symbol instruction -is_symbol <- Name { check_symbol var_table } # Check symbol instruction -``` - -If we parse the following text with the above grammar, it will fail. - -``` -decl aaa -ref aaa -ref bbb -``` - -It is because the line 3 references undeclared 'bbb'. - Make a parser with parser combinators ------------------------------------- diff --git a/peglib.h b/peglib.h index 6377d5c..2509afd 100644 --- a/peglib.h +++ b/peglib.h @@ -778,12 +778,6 @@ public: std::vector cut_stack; -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - std::vector>> - symbol_tables_stack; - size_t symbol_tables_stack_size = 0; -#endif - const size_t def_count; const bool enablePackratParsing; std::vector cache_registered; @@ -813,10 +807,6 @@ public: push_args({}); push_capture_scope(); - -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - push_symbol_tables(); -#endif } ~Context() { @@ -825,11 +815,6 @@ public: assert(!value_stack_size); assert(!capture_scope_stack_size); assert(cut_stack.empty()); - -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - pop_symbol_tables(); - assert(!symbol_tables_stack_size); -#endif } Context(const Context &) = delete; @@ -870,18 +855,12 @@ public: SemanticValues &push() { push_capture_scope(); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - push_symbol_tables(); -#endif return push_semantic_values_scope(); } void pop() { pop_capture_scope(); pop_semantic_values_scope(); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - pop_symbol_tables(); -#endif } // Semantic values @@ -944,53 +923,6 @@ public: } } -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - // Symbol tables - void push_symbol_tables() { - assert(symbol_tables_stack_size <= symbol_tables_stack.size()); - if (symbol_tables_stack_size == symbol_tables_stack.size()) { - symbol_tables_stack.emplace_back( - std::map>()); - } else { - auto &tables = symbol_tables_stack[symbol_tables_stack_size]; - if (!tables.empty()) { tables.clear(); } - } - symbol_tables_stack_size++; - } - - void pop_symbol_tables() { symbol_tables_stack_size--; } - - void shift_symbol_tables() { - assert(symbol_tables_stack_size >= 2); - auto curr = &symbol_tables_stack[symbol_tables_stack_size - 1]; - auto prev = curr - 1; - for (const auto &[k, v] : *curr) { - (*prev)[k].insert(v.begin(), v.end()); - } - } - - void declare_symbol(const std::string &table_name, - const std::string &symbol) { - assert(symbol_tables_stack_size >= 1); - auto &table = symbol_tables_stack[symbol_tables_stack_size - 1][table_name]; - table.insert(symbol); - } - - bool check_symbol(const std::string &table_name, const std::string &symbol) { - int i = symbol_tables_stack_size - 1; - while (i >= 0) { - const auto &tables = symbol_tables_stack[i]; - if (auto it = tables.find(table_name); it != tables.end()) { - if (const auto &table = it->second; table.find(symbol) != table.end()) { - return true; - } - } - i--; - } - return false; - } -#endif - // Error void set_error_pos(const char *a_s, const char *literal = nullptr); @@ -1082,9 +1014,6 @@ public: vs.choice_count_ = opes_.size(); vs.choice_ = id; c.shift_capture_values(); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - c.shift_symbol_tables(); -#endif break; } else if (!c.cut_stack.empty() && c.cut_stack.back()) { break; @@ -1124,9 +1053,6 @@ public: if (success(len)) { vs.append(chvs); c.shift_capture_values(); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - c.shift_symbol_tables(); -#endif } else { return len; } @@ -1143,9 +1069,6 @@ public: if (success(len)) { vs.append(chvs); c.shift_capture_values(); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - c.shift_symbol_tables(); -#endif } else { break; } @@ -2426,12 +2349,6 @@ public: bool eoi_check = true; -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - bool declare_symbol = false; - bool check_symbol = false; - std::string symbol_table_name; -#endif - private: friend class Reference; friend class ParserGenerator; @@ -2808,24 +2725,6 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs, c.error_info.message = msg; } len = static_cast(-1); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - } else if (outer_->declare_symbol) { - assert(outer_->is_token()); - auto symbol = chvs.token_to_string(); - if (c.check_symbol(outer_->symbol_table_name, symbol)) { - msg = "'" + symbol + "' already exists."; - len = static_cast(-1); - } else { - c.declare_symbol(outer_->symbol_table_name, symbol); - } - } else if (outer_->check_symbol) { - assert(outer_->is_token()); - auto symbol = chvs.token_to_string(); - if (!c.check_symbol(outer_->symbol_table_name, symbol)) { - msg = "'" + symbol + "' doesn't exist."; - len = static_cast(-1); - } -#endif } if (success(len)) { @@ -3485,10 +3384,6 @@ private: g["EndBlacket"]); g["InstructionItem"] <= cho(g["PrecedenceClimbing"], g["ErrorMessage"], g["NoAstOpt"] -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - , - g["DeclareSymbol"], g["CheckSymbol"] -#endif ); ~g["InstructionItemSeparator"] <= seq(chr(';'), g["Spacing"]); @@ -3522,14 +3417,6 @@ private: // No Ast node optimazation instruction g["NoAstOpt"] <= seq(lit("no_ast_opt"), g["SpacesZom"]); -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - // Symbol table instruction - g["DeclareSymbol"] <= seq(lit("declare_symbol"), g["SpacesZom"], - g["Identifier"], g["SpacesZom"]); - g["CheckSymbol"] <= seq(lit("check_symbol"), g["SpacesZom"], - g["Identifier"], g["SpacesZom"]); -#endif - // Set definition names for (auto &x : g) { x.second.name = x.first; @@ -3932,24 +3819,6 @@ private: return instruction; }; -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - g["DeclareSymbol"] = [](const SemanticValues &vs) { - Instruction instruction; - instruction.type = "declare_symbol"; - instruction.data = std::string("default"); - instruction.sv = vs.sv(); - return instruction; - }; - - g["CheckSymbol"] = [](const SemanticValues &vs) { - Instruction instruction; - instruction.type = "check_symbol"; - instruction.data = std::string("default"); - instruction.sv = vs.sv(); - return instruction; - }; -#endif - g["Instruction"] = [](const SemanticValues &vs) { return vs.transform(); }; @@ -4200,14 +4069,6 @@ private: rule.error_message = std::any_cast(instruction.data); } else if (instruction.type == "no_ast_opt") { rule.no_ast_opt = true; -#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT - } else if (instruction.type == "declare_symbol") { - rule.declare_symbol = true; - rule.symbol_table_name = std::any_cast(instruction.data); - } else if (instruction.type == "check_symbol") { - rule.check_symbol = true; - rule.symbol_table_name = std::any_cast(instruction.data); -#endif } } }