1- #nullable enable
1+ #nullable enable
22
33using Diagnostics ;
44using Microsoft . CodeAnalysis ;
@@ -175,18 +175,20 @@ private string GenerateDfaCode(DfaState start, int startIndent)
175175 }
176176
177177 sb . AppendLine ( $$ """
178- int currentPos = startPos;
179- int length = input.Length;
180- int currentState = {{ start . Id }} ;
181- int lastAccept = -1;
178+ var currentPos = startPos;
179+ var length = input.Length;
180+ var currentState = {{ start . Id }} ;
181+ var lastAccept = -1;
182182 {{ ( start . IsFinal ? "lastAccept = currentPos;" : "" ) }}
183- """ ) ;
183+ //System.Diagnostics.Debugger.Launch( );
184184
185- sb . AppendLine ( """
186- while (currentPos < length)
185+ while (currentPos <= length)
187186 {
188- char c = input[currentPos];
189- bool transitionFound = false;
187+ var c = currentPos < length ? input[currentPos] : '\0';
188+ if (c == '\0')
189+ {
190+ }
191+ var transitionFound = false;
190192 switch (currentState)
191193 {
192194 """ ) ;
@@ -216,14 +218,15 @@ private string GenerateDfaCode(DfaState start, int startIndent)
216218 static string generateStateTransitions ( DfaState state , IndentHelper indent )
217219 {
218220 var sb = new StringBuilder ( ) ;
219- foreach ( var transition in state . Transitions )
221+
222+ foreach ( var transition in state . Transitions )
220223 {
221224 var condition = generateTransitionCondition ( transition . Condition ) ;
222225 sb . AppendLine ( $$ """
223226 if ({{ condition }} )
224227 {
225228 currentState = {{ transition . Target . Id }} ;
226- currentPos++;
229+ {{ ( transition . Condition is RegexEndOfLine ? "" : " currentPos++;" ) }}
227230 {{ ( transition . Target . IsFinal ? "lastAccept = currentPos;" : "" ) }}
228231 transitionFound = true;
229232 continue;
@@ -237,24 +240,25 @@ static string generateTransitionCondition(RegexNode node)
237240 {
238241 return node switch
239242 {
240- RegexChar rc => $ """ c == '{ EscapeChar ( rc . Value ) } '""" ,
241- RegexAnyChar => "true" ,
242- RangesCharClass rcc when rcc . ToString ( ) == "[^[\\ n]]" => "c != '\\ n'" ,
243+ RegexEndOfLine x => $@ "c == '\0' /* { x } */",
244+ RegexChar rc => $ """ c == '{ EscapeChar ( rc . Value ) } ' /* { rc } */""" ,
245+ RegexAnyChar => "true /* RegexAnyChar */" ,
246+ NegatedCharClassGroup rcc when rcc . ToString ( ) == $@ "[^[\n]]" => $@ "c is not '\n' and not '\0' /* { rcc } */",
243247 RangesCharClass rcc => GenerateRangeCondition ( rcc ) ,
244248 WordCharClass wcc => $ """ { ( wcc . Negated ? "!" : "" ) } (char.IsLetterOrDigit(c) || c == '_')""" ,
245249 DigitCharClass dcc => $ """ { ( dcc . Negated ? "!" : "" ) } char.IsDigit(c)""" ,
246250 WhitespaceCharClass scc => $ """ { ( scc . Negated ? "!" : "" ) } char.IsWhiteSpace(c)""" ,
247251 LetterCharClass lcc => $ """ { ( lcc . Negated ? "!" : "" ) } char.IsLetter(c)""" ,
248- _ => "false"
252+ _ => $ "false /* { node } ( { node . GetType ( ) . Name } ) */ "
249253 } ;
250254 }
251255 }
252256 }
253257
254258 private static string GenerateRangeCondition ( RangesCharClass rcc )
255259 {
256- if ( rcc . ToString ( ) == "[^[\ \ n]]" ) // Специальный случай для [^\n]
257- return rcc . Negated ? "c == '\\ n'" : "c != '\ \ n'" ;
260+ if ( rcc . ToString ( ) == @ "[^[\n]]") // Специальный случай для [^\n]
261+ return rcc . Negated ? @ "c == '\n'" : @ "c != '\n'";
258262
259263 var conditions = rcc . Ranges
260264 . Select ( r => r . From == r . To
0 commit comments