public Token Parse( Token source ) { this.Source = source.String; int sourceEned = this.Source.Length; this.Line = 1; this.BOL = true; this.EnableOutput = true; //Accumulate ouput into this token var output = new Token( Token.Kind.Text ); int emptyLines = 0; //Enabel output only if all embedded #if's were true bool oldOutputEnabled = true; bool outputEnabled = true; int outputDisabledLine = 0; for ( int i = 0; i < sourceEned; i++ ) { int oldLine = this.Line; Token t = this.GetToken( true ); NextToken: switch ( t.Type ) { case Token.Kind.Error: return t; case Token.Kind.EOS: return output; //Force termination case Token.Kind.Comment: //C comments are replaced with single spaces. if ( outputEnabled ) { output.Append( " ", 1 ); output.AppendNL( this.Line - oldLine ); } break; case Token.Kind.Linecomment: //C++ comments are ignored continue; case Token.Kind.Directive: t = this.HandleDirective( t, oldLine ); outputEnabled = this.EnableOutput; if ( outputEnabled != oldOutputEnabled ) { if ( outputEnabled ) { output.AppendNL( oldLine - outputDisabledLine ); } else { outputDisabledLine = oldLine; } oldOutputEnabled = outputEnabled; } if ( outputEnabled ) { output.AppendNL( this.Line - oldLine - t.CountNL ); } goto NextToken; case Token.Kind.Linecont: //Backslash-Newline sequences are delted, no matter where. emptyLines++; break; case Token.Kind.Newline: if ( emptyLines > 0 ) { // Compensate for the backslash-newline combinations // we have encountered, otherwise line numeration is broken if ( outputEnabled ) { output.AppendNL( emptyLines ); } emptyLines = 0; } goto default; case Token.Kind.Whitespace: default: //Passthrough all other tokens if ( outputEnabled ) { output.Append( t ); } break; } } if ( this.EnableOutput == false ) { this.Error( this.Line, "Unclosed #if at end of source", null ); return Token.Error; } return output; }