Patches item #2478216, was opened at 2008-12-31 04:07 Message generated for change (Settings changed) made by helly You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=616202&aid=2478216&group_id=96864
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Jakob Stoklund Olesen (stoklund) Assigned to: Marcus Börger (helly) Summary: Wrong start_label in -c mode Initial Comment: Re: Bug #2462777: Infinite loop in generated code with -c There is a bit of confusion about the meaning of start_label in DFA::emit() when using -c. The global start label is the point immediately before the code generated by genCondGoto() (YYGETCONDITION+goto condition). This is where re2c:startlabel should be and it should be the default target for genGetStateGoto() when state==-1. The local start label is the initial state for the condition of the DFA that happens to be emitting the prolog. Sometimes the initial state is not emitted first, and yy0 is not the first label in the emitted code. In this case, the current -c code will generate an infinite loop because yy0 has been placed at the global start label. The attached patch does the following: * Allow Initial::emit() to generate the proper local start label in -c mode * Replace hard-coded references to labels 0 and 1 with start_label{,+1} * Create a separate prolog_label=0 to represent the global start label. The prolog_label must be called yy0 because the call to genGetStateGoto(default=yy0) in scanner.re Unfortunately this offsets all label numbers by one in -c code, causing huge diffs for all the -c test cases. With this patch re2c generates correct code for Bug #2462777: ./re2c -ci --no-generation-date tc.re << END > /*!re2c > <X> [a]* {x;} > */ > END /* Generated by re2c 0.13.6.dev */ { YYCTYPE yych; switch (YYGETCONDITION()) { case yycX: goto yyc_X; } /* *********************************** */ yyc_X: goto yy1; yy2: ++YYCURSOR; yy1: if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; switch (yych) { case 'a': goto yy2; default: goto yy4; } yy4: {x;} } ---------------------------------------------------------------------- Comment By: Jakob Stoklund Olesen (stoklund) Date: 2008-12-31 12:51 Message: Small correction: next_label should only be bumped once, not once per condition. Check for bProlog: @@ -1783,6 +1783,16 @@ void DFA::emit(std::ostream &o, uint& ind, const RegExpMap* specMap, const std:: bUsedYYAccept = false; } + // In -c mode, the prolog needs its own label separate from start_label. + // prolog_label is before the condition branch (GenCondGoto). It is equivalent to startLabelName. + // start_label corresponds to current condition. + // NOTE: prolog_label must be yy0 because of the !getstate:re2c handling in scanner.re + uint prolog_label = next_label; + if (bProlog && cFlag) + { + next_label++; + } + uint start_label = next_label; (void) new Initial(head, next_label++, bSaveOnHead); Test case diffs are much smaller if you first run perl -i -pe 's/yy(\d+)/"yy".($1+1)/eg' test/*.c*.c test/yyaccept_missing.bci.c ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=616202&aid=2478216&group_id=96864 ------------------------------------------------------------------------------ _______________________________________________ Re2c-general mailing list Re2c-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/re2c-general