using System.Globalization; using Nemerle.Compiler; using Nemerle.IO; class LexerDumper : LexerFile { mutable last_loc : Location = Location.Default; public this (file : string) { base (file); } private Escape (str : string) : string { str.Replace ("&", "&").Replace ("<", "<").Replace (">", ">") } public override GetToken () : Token { def tok = base.GetToken (); def token_str = match (tok) { | Token.Identifier (name) => Escape (name) | Token.Keyword (name) => $"$name" | Token.Operator (name) => $"$(Escape (name))" | Token.Semicolon => ";" | Token.Comma => "," | Token.BeginBrace => "{" | Token.EndBrace => "}" | Token.BeginRound => "(" | Token.EndRound => ")" | Token.BeginSquare => "[" | Token.EndSquare => "]" | Token.BeginQuote => "<[" | Token.EndQuote => "]>" | Token.StringLiteral (_, value) => $"\"$value\"" | Token.CharLiteral (value) => $"'$(value)'" | Token.SByteLiteral (value) => $"$(value)SB" | Token.ByteLiteral (value) => $"$(value)B" | Token.ShortLiteral (value) => $"$(value)S" | Token.UShortLiteral (value) => $"$(value)US" | Token.IntLiteral (value) => $"$(value)" | Token.UIntLiteral (value) => $"$(value)U" | Token.LongLiteral (value) => $"$(value)L" | Token.ULongLiteral (value) => $"$(value)UL" | Token.FloatLiteral (value) => def str = value.ToString (CultureInfo.InvariantCulture); $"$(str)f" | Token.DoubleLiteral (value) => def str = value.ToString (CultureInfo.InvariantCulture); $"$(str)" | Token.DecimalLiteral (value) => def str = value.ToString (CultureInfo.InvariantCulture); $"$(str)M" | Token.Comment (value) => def value = value.TrimEnd (array [' ', '\n']); def height_loop (i, sum) { if (i < value.Length) if (value [i] == '\n') height_loop (i + 1, sum + 1) else height_loop (i + 1, sum) else sum } if (height_loop (0, 1) > 1) $"/* $(value) */" else $"// $(value)\n" | Token.EndOfFile => "" | x => Util.ice ("this token should not come from lexer: " + x.ToString ()); } unless ((tok matches Token.EndOfFile) || (defines.Get ("OMMIT") matches Some (true))) { mutable cur_loc = tok.Location; if (cur_loc.Line != last_loc.EndLine) { repeat (cur_loc.Line - last_loc.EndLine) print ("\n"); repeat (cur_loc.Column) print (" "); } else repeat (cur_loc.Column - last_loc.EndColumn) print (" "); // print (tok.Location.ToString ()); /// dump current token string print (token_str); when (tok matches Token.Comment) print (" "); // remember current location as the previous one last_loc = cur_loc; } tok } } module Dumper { Main (args : array [string]) : void { Message.InitOutput (System.Console.Out); if (args.Length < 1) printf ("usage: dumper.exe filename.n DEF1 DEF2 ...\n"); else { Options.Sources = [args [0]]; Options.XmlDoc = true; LexerFile.store_comments = true; Options.ProgressBar = false; Passes.LexingPipeline = LexerDumper; Passes.ScanningPipeline = fun (_) { print ("\n\n"); System.Environment.Exit (0); }; for (mutable i = 1; i < args.Length; ++i) LexerDumper.command_defines.Set (args [i], true); print ("
\n");
Passes.Run ();
}
}
}