From: Ulya Trofimovich Date: Tue, 4 Aug 2015 12:38:57 +0000 (+0100) Subject: Better representation for rule actions; omit line info for autogenerated actions. X-Git-Tag: 0.15~161 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d4462d5d531dc707a442bc984283ea51f77338c;p=re2c Better representation for rule actions; omit line info for autogenerated actions. Since there's no such code in source file, there's no sense in pointing into it. Updated test. --- diff --git a/re2c/Makefile.am b/re2c/Makefile.am index d27ff3b3..3e33456f 100644 --- a/re2c/Makefile.am +++ b/re2c/Makefile.am @@ -50,12 +50,12 @@ SRC_HDR = \ src/ir/regexp/regexp_close.h \ src/ir/rule_rank.h \ src/globals.h \ + src/parse/code.h \ src/parse/extop.h \ src/parse/input.h \ src/parse/loc.h \ src/parse/parser.h \ src/parse/scanner.h \ - src/parse/token.h \ src/util/allocate.h \ src/util/attribute.h \ src/util/c99_stdint.h \ @@ -109,6 +109,7 @@ SRC = \ src/ir/regexp/regexp.cc \ src/ir/rule_rank.cc \ src/main.cc \ + src/parse/code.cc \ src/parse/input.cc \ src/parse/scanner.cc \ src/parse/unescape.cc \ diff --git a/re2c/src/codegen/emit_action.cc b/re2c/src/codegen/emit_action.cc index 1d33c924..bc9717e1 100644 --- a/re2c/src/codegen/emit_action.cc +++ b/re2c/src/codegen/emit_action.cc @@ -233,7 +233,7 @@ void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleO { if (DFlag) { - o << s->label << " [label=\"" << rule->code->loc.filename << ":" << rule->code->loc.line << "\"]\n"; + o << s->label << " [label=\"" << rule->code.loc.filename << ":" << rule->code.loc.line << "\"]\n"; return; } @@ -243,37 +243,39 @@ void emit_rule (OutputFile & o, uint32_t ind, const State * const s, const RuleO o << input_api.stmt_restorectx (ind); } - if (rule->newcond.length() && condName != rule->newcond) - { - genSetCondition(o, ind, rule->newcond); - } - - if (!yySetupRule.empty() && !rule->code->autogen) - { - o << indent(ind) << yySetupRule << "\n"; - } - - o.write_line_info (rule->code->loc.line, rule->code->loc.filename.c_str ()); - o << indent(ind); if (flag_skeleton) { - o << "{ if (cursor == &data[result[i].endpos] && result[i].rule == " << rule->rank << ") "; - o << "{ cursor = &data[result[i].startpos]; continue; }"; - o << " else "; - o << "{ printf (\"error: %lu/%u, %u/%u, '%s'\\n\", cursor - data, result[i].endpos, result[i].rule, " + o << indent (ind) + << "{ if (cursor == &data[result[i].endpos] && result[i].rule == " << rule->rank << ") " + << "{ cursor = &data[result[i].startpos]; continue; }" + << " else " + << "{ printf (\"error: %lu/%u, %u/%u, '%s'\\n\", cursor - data, result[i].endpos, result[i].rule, " << rule->rank - << ", &data[result[i].startpos]); return 1; } }"; - } - else if (rule->code->autogen) - { - o << replaceParam(condGoto, condGotoParam, condPrefix + rule->newcond); + << ", &data[result[i].startpos]); return 1; } }\n"; } else { - o << rule->code->text; + if (rule->newcond.length() && condName != rule->newcond) + { + genSetCondition(o, ind, rule->newcond); + } + + const bool autogen = rule->code.text.empty (); + if (autogen) + { + o << indent (ind) << replaceParam(condGoto, condGotoParam, condPrefix + rule->newcond) << "\n"; + } + else + { + if (!yySetupRule.empty ()) + { + o << indent(ind) << yySetupRule << "\n"; + } + o.write_line_info (rule->code.loc.line, rule->code.loc.filename.c_str ()); + o << indent (ind) << rule->code.text << "\n"; + o.insert_line_info (); + } } - o << "\n"; - o.insert_line_info (); } void need (OutputFile & o, uint32_t ind, bool & readCh, uint32_t n, bool bSetMarker) diff --git a/re2c/src/codegen/prepare_dfa.cc b/re2c/src/codegen/prepare_dfa.cc index 6ea355e7..1b72b7d8 100644 --- a/re2c/src/codegen/prepare_dfa.cc +++ b/re2c/src/codegen/prepare_dfa.cc @@ -257,7 +257,7 @@ void DFA::prepare(OutputFile & o, uint32_t & max_fill, const std::string & cond) // warn about not shadowed rule that matches empty string if (empty_rule && !stray_cunits.empty ()) { - warn.match_empty_string (head->rule->code->loc.line); + warn.match_empty_string (head->rule->code.loc.line); } // split ``base'' states into two parts diff --git a/re2c/src/ir/regexp/regexp_rule.h b/re2c/src/ir/regexp/regexp_rule.h index a85751ff..53a61089 100644 --- a/re2c/src/ir/regexp/regexp_rule.h +++ b/re2c/src/ir/regexp/regexp_rule.h @@ -5,7 +5,7 @@ #include "src/ir/regexp/regexp.h" #include "src/ir/rule_rank.h" -#include "src/parse/token.h" +#include "src/parse/code.h" namespace re2c { @@ -18,10 +18,10 @@ public: RegExp * ctx; Ins * ins; rule_rank_t rank; - Token * code; + const Code & code; const std::string newcond; - inline RuleOp (RegExp * e, RegExp * c, Token * t, rule_rank_t r, InsAccess access, const std::string * n) + inline RuleOp (RegExp * e, RegExp * c, const Code & t, rule_rank_t r, InsAccess access, const std::string * n) : exp (e) , ctx (c) , ins (NULL) @@ -31,10 +31,6 @@ public: { ins_access = access; } - inline ~RuleOp () - { - delete code; - } void display (std::ostream & o) const; void split (CharSet &); void calcSize (Char *); diff --git a/re2c/src/parse/code.cc b/re2c/src/parse/code.cc new file mode 100644 index 00000000..97a865ce --- /dev/null +++ b/re2c/src/parse/code.cc @@ -0,0 +1,8 @@ +#include "src/parse/code.h" + +namespace re2c +{ + +free_list Code::freelist; + +} // namespace re2c diff --git a/re2c/src/parse/code.h b/re2c/src/parse/code.h new file mode 100644 index 00000000..10d87389 --- /dev/null +++ b/re2c/src/parse/code.h @@ -0,0 +1,34 @@ +#ifndef _RE2C_PARSE_CODE_ +#define _RE2C_PARSE_CODE_ + +#include "src/parse/loc.h" +#include "src/util/c99_stdint.h" +#include "src/util/free_list.h" + +namespace re2c +{ + +struct Code +{ + static free_list freelist; + + const Loc loc; + const std::string text; + + inline Code (const char * t, size_t t_len, const std::string & f, uint32_t l) + : loc (f, l) + , text (t, t_len) + { + freelist.insert (this); + } + inline Code (const std::string & f, uint32_t l) + : loc (f, l) + , text () + { + freelist.insert (this); + } +}; + +} // namespace re2c + +#endif // _RE2C_PARSE_CODE_ diff --git a/re2c/src/parse/parser.h b/re2c/src/parse/parser.h index 2c973279..73333740 100644 --- a/re2c/src/parse/parser.h +++ b/re2c/src/parse/parser.h @@ -18,7 +18,7 @@ extern void parse_cleanup(); typedef std::set CondList; typedef std::list RuleOpList; typedef std::map > SetupMap; -typedef std::map DefaultMap; +typedef std::map DefaultMap; typedef std::map symbol_table_t; } // namespace re2c diff --git a/re2c/src/parse/parser.ypp b/re2c/src/parse/parser.ypp index 3e0fac10..5dbfc78a 100644 --- a/re2c/src/parse/parser.ypp +++ b/re2c/src/parse/parser.ypp @@ -16,6 +16,7 @@ #include "src/ir/regexp/regexp_null.h" #include "src/codegen/emit.h" // genTypes #include "src/globals.h" +#include "src/parse/code.h" #include "src/parse/extop.h" #include "src/parse/parser.h" #include "src/util/c99_stdint.h" @@ -39,7 +40,7 @@ static RuleOpList specStar; static Scanner *in = NULL; static Scanner::ParseMode parseMode; static SetupMap ruleSetupMap; -static Token *ruleDefault = NULL; +static const Code * ruleDefault = NULL; static DefaultMap ruleDefaultMap; static bool foundRules; static symbol_table_t symbol_table; @@ -67,7 +68,7 @@ void context_none(CondList *clist) in->fatal("no expression specified"); } -void context_rule(CondList *clist, RegExp *expr, RegExp *look, const std::string * newcond, Token *code) +void context_rule(CondList *clist, RegExp *expr, RegExp *look, const std::string * newcond, const Code & code) { context_check(clist); const RegExp::InsAccess ins_access = clist->size() > 1 @@ -75,8 +76,7 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, const std::string : RegExp::SHARED; for(CondList::const_iterator it = clist->begin(); it != clist->end(); ++it) { - Token *token = new Token(code, in->get_fname (), in->get_cline ()); - RuleOp *rule = new RuleOp(expr, look, token, rank_counter.next (), ins_access, newcond); + RuleOp *rule = new RuleOp(expr, look, code, rank_counter.next (), ins_access, newcond); RegExpMap::iterator itRE = specMap.find(*it); @@ -94,10 +94,9 @@ void context_rule(CondList *clist, RegExp *expr, RegExp *look, const std::string } delete clist; delete newcond; - delete code; } -void setup_rule(CondList *clist, Token *code) +void setup_rule(CondList *clist, const Code * code) { assert(clist); assert(code); @@ -111,10 +110,9 @@ void setup_rule(CondList *clist, Token *code) ruleSetupMap[*it] = std::make_pair(code->loc.line, code->text); } delete clist; - delete code; } -void default_rule(CondList *clist, Token *code) +void default_rule(CondList *clist, const Code * code) { assert(clist); assert(code); @@ -136,7 +134,7 @@ void default_rule(CondList *clist, Token *code) %union { re2c::RegExp *regexp; - re2c::Token *token; + const re2c::Code * code; char op; int number; re2c::ExtOp extop; @@ -150,7 +148,7 @@ void default_rule(CondList *clist, Token *code) %type CLOSE STAR SETUP FID_END %type close %type CLOSESIZE -%type CODE +%type CODE %type RANGE STRING %type rule look expr diff term factor primary %type CONFIG VALUE newcond ID FID @@ -217,7 +215,7 @@ rule: { in->fatal("condition or '<*>' required when using -c switch"); } - $$ = new RuleOp($1, $2, $3, rank_counter.next (), RegExp::SHARED, NULL); + $$ = new RuleOp($1, $2, *$3, rank_counter.next (), RegExp::SHARED, NULL); spec = spec? mkAlt(spec, $$) : $$; } | STAR CODE /* default rule */ @@ -231,12 +229,13 @@ rule: } | '<' cond '>' expr look newcond CODE { - context_rule($2, $4, $5, $6, $7); + context_rule($2, $4, $5, $6, *$7); } | '<' cond '>' expr look ':' newcond { assert($7); - context_rule($2, $4, $5, $7, NULL); + const Code * code = new Code (in->get_fname (), in->get_cline ()); + context_rule($2, $4, $5, $7, *code); } | '<' cond '>' look newcond CODE { @@ -256,17 +255,15 @@ rule: | '<' STAR '>' expr look newcond CODE { context_check(NULL); - Token *token = new Token($7, $7->loc.filename, $7->loc.line); - delete $7; - specStar.push_back(new RuleOp($4, $5, token, rank_counter.next (), RegExp::PRIVATE, $6)); + specStar.push_back(new RuleOp($4, $5, *$7, rank_counter.next (), RegExp::PRIVATE, $6)); delete $6; } | '<' STAR '>' expr look ':' newcond { assert($7); context_check(NULL); - Token *token = new Token(NULL, in->get_fname (), in->get_cline ()); - specStar.push_back(new RuleOp($4, $5, token, rank_counter.next (), RegExp::PRIVATE, $7)); + const Code * code = new Code (in->get_fname (), in->get_cline ()); + specStar.push_back(new RuleOp($4, $5, *code, rank_counter.next (), RegExp::PRIVATE, $7)); delete $7; } | '<' STAR '>' look newcond CODE @@ -293,9 +290,7 @@ rule: { in->fatal("code to handle illegal condition already defined"); } - Token *token = new Token($3, $3->loc.filename, $3->loc.line); - delete $3; - $$ = specNone = new RuleOp(new NullOp(), new NullOp(), token, rank_counter.next (), RegExp::SHARED, $2); + $$ = specNone = new RuleOp(new NullOp(), new NullOp(), *$3, rank_counter.next (), RegExp::SHARED, $2); delete $2; } | NOCOND ':' newcond @@ -306,8 +301,8 @@ rule: { in->fatal("code to handle illegal condition already defined"); } - Token *token = new Token(NULL, in->get_fname (), in->get_cline ()); - $$ = specNone = new RuleOp(new NullOp(), new NullOp(), token, rank_counter.next (), RegExp::SHARED, $3); + const Code * code = new Code (in->get_fname (), in->get_cline ()); + $$ = specNone = new RuleOp(new NullOp(), new NullOp(), *code, rank_counter.next (), RegExp::SHARED, $3); delete $3; } | SETUP STAR '>' CODE @@ -637,7 +632,7 @@ void parse(Scanner& i, Output & o) itRuleDefault = ruleDefaultMap.find(it->first); if (itRuleDefault != ruleDefaultMap.end()) { - RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), itRuleDefault->second, rank_counter.next (), RegExp::SHARED, NULL); + RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), *(itRuleDefault->second), rank_counter.next (), RegExp::SHARED, NULL); it->second.second = it->second.second ? mkAlt(def, it->second.second) : def; } else @@ -645,7 +640,7 @@ void parse(Scanner& i, Output & o) itRuleDefault = ruleDefaultMap.find("*"); if (itRuleDefault != ruleDefaultMap.end()) { - RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), itRuleDefault->second, rank_counter.next (), RegExp::SHARED, NULL); + RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), *(itRuleDefault->second), rank_counter.next (), RegExp::SHARED, NULL); it->second.second = it->second.second ? mkAlt(def, it->second.second) : def; } } @@ -663,7 +658,7 @@ void parse(Scanner& i, Output & o) { if (ruleDefault != NULL && parseMode != Scanner::Reuse) { - RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), ruleDefault, rank_counter.next (), RegExp::SHARED, NULL); + RuleOp * def = new RuleOp(in->mkDefault(), new NullOp(), *ruleDefault, rank_counter.next (), RegExp::SHARED, NULL); spec = spec ? mkAlt(def, spec) : def; } if (spec || !dfa_map.empty()) @@ -714,6 +709,7 @@ void parse_cleanup() RegExp::vFreeList.clear(); Range::vFreeList.clear(); RangeSuffix::freeList.clear(); + Code::freelist.clear(); symbol_table.clear (); specMap.clear(); specStar.clear(); diff --git a/re2c/src/parse/scanner.h b/re2c/src/parse/scanner.h index bd97177f..3eda866f 100644 --- a/re2c/src/parse/scanner.h +++ b/re2c/src/parse/scanner.h @@ -6,8 +6,8 @@ #include "src/codegen/output.h" #include "src/ir/regexp/regexp.h" #include "src/globals.h" +#include "src/parse/code.h" #include "src/parse/input.h" -#include "src/parse/token.h" #include "src/util/attribute.h" #include "src/util/forbid_copy.h" #include "src/util/substr.h" diff --git a/re2c/src/parse/scanner_lex.re b/re2c/src/parse/scanner_lex.re index ad64e543..e7032ed5 100644 --- a/re2c/src/parse/scanner_lex.re +++ b/re2c/src/parse/scanner_lex.re @@ -464,7 +464,7 @@ code: else if (--depth == 0) { cur = cursor; - yylval.token = new Token(tok, cur - tok, get_fname (), tline); + yylval.code = new Code (tok, cur - tok, get_fname (), tline); return CODE; } goto code; @@ -506,7 +506,7 @@ code: { --cur; } - yylval.token = new Token(tok, cur - tok, get_fname (), tline); + yylval.code = new Code (tok, cur - tok, get_fname (), tline); return CODE; } else if (cursor == eof) diff --git a/re2c/src/parse/token.h b/re2c/src/parse/token.h deleted file mode 100644 index 125925ab..00000000 --- a/re2c/src/parse/token.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _RE2C_PARSE_TOKEN_ -#define _RE2C_PARSE_TOKEN_ - -#include "src/parse/loc.h" -#include "src/util/c99_stdint.h" -#include "src/util/forbid_copy.h" - -namespace re2c -{ - -class Token -{ -public: - const Loc loc; - const std::string text; - const bool autogen; - - inline Token (const char * t, uint32_t t_len, const std::string & s, uint32_t l) - : loc (s, l) - , text (t, t_len) - , autogen (false) - {} - inline Token (const Token * t, const std::string & s, uint32_t l) - : loc (t ? t->loc : Loc (s, l)) - , text (t ? t->text : "") - , autogen (t == NULL) - {} - - FORBID_COPY (Token); -}; - -} // namespace re2c - -#endif // _RE2C_PARSE_TOKEN_ diff --git a/re2c/test/condition_13.cg.c b/re2c/test/condition_13.cg.c index 7eebd569..f456b226 100644 --- a/re2c/test/condition_13.cg.c +++ b/re2c/test/condition_13.cg.c @@ -16,9 +16,7 @@ re2c: warning: line 9: naked default case in condition r2 (stray code units: [0x /* *********************************** */ yyc_0: YYSETCONDITION(yycr1); -#line 3 "condition_13.cg.re" goto yyc_r1; -#line 19 "" /* *********************************** */ yyc_r1: if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -35,26 +33,18 @@ yyc_r1: yy6: yy7: ++YYCURSOR; -#line 5 "condition_13.cg.re" goto yyc_r1; -#line 38 "" yy9: ++YYCURSOR; -#line 4 "condition_13.cg.re" goto yyc_r1; -#line 43 "" yy11: ++YYCURSOR; YYSETCONDITION(yycr2); -#line 6 "condition_13.cg.re" goto yyc_r2; -#line 49 "" yy13: ++YYCURSOR; YYSETCONDITION(yycr2); -#line 7 "condition_13.cg.re" goto yyc_r2; -#line 55 "" /* *********************************** */ yyc_r2: if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -70,20 +60,14 @@ yy17: yy18: ++YYCURSOR; YYSETCONDITION(yycr1); -#line 5 "condition_13.cg.re" goto yyc_r1; -#line 73 "" yy20: ++YYCURSOR; YYSETCONDITION(yycr1); -#line 4 "condition_13.cg.re" goto yyc_r1; -#line 79 "" yy22: ++YYCURSOR; -#line 7 "condition_13.cg.re" goto yyc_r2; -#line 84 "" } #line 9 "condition_13.cg.re"