mirror of
https://github.com/Ratstail91/Mementos.git
synced 2025-11-29 02:24:28 +11:00
94 lines
2.8 KiB
C#
94 lines
2.8 KiB
C#
|
|
namespace Ink
|
|
{
|
|
/// <summary>
|
|
/// Pre-pass before main ink parser runs. It actually performs two main tasks:
|
|
/// - comment elimination to simplify the parse rules in the main parser
|
|
/// - Conversion of Windows line endings (\r\n) to the simpler Unix style (\n), so
|
|
/// we don't have to worry about them later.
|
|
/// </summary>
|
|
public class CommentEliminator : StringParser
|
|
{
|
|
public CommentEliminator (string input) : base(input)
|
|
{
|
|
}
|
|
|
|
public string Process()
|
|
{
|
|
// Make both comments and non-comments optional to handle trivial empty file case (or *only* comments)
|
|
var stringList = Interleave<string>(Optional (CommentsAndNewlines), Optional(MainInk));
|
|
|
|
if (stringList != null) {
|
|
return string.Join("", stringList.ToArray());
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
string MainInk()
|
|
{
|
|
return ParseUntil (CommentsAndNewlines, _commentOrNewlineStartCharacter, null);
|
|
}
|
|
|
|
string CommentsAndNewlines()
|
|
{
|
|
var newlines = Interleave<string> (Optional (ParseNewline), Optional (ParseSingleComment));
|
|
|
|
if (newlines != null) {
|
|
return string.Join ("", newlines.ToArray());
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Valid comments always return either an empty string or pure newlines,
|
|
// which we want to keep so that line numbers stay the same
|
|
string ParseSingleComment()
|
|
{
|
|
return (string) OneOf (EndOfLineComment, BlockComment);
|
|
}
|
|
|
|
string EndOfLineComment()
|
|
{
|
|
if (ParseString ("//") == null) {
|
|
return null;
|
|
}
|
|
|
|
ParseUntilCharactersFromCharSet (_newlineCharacters);
|
|
|
|
return "";
|
|
}
|
|
|
|
string BlockComment()
|
|
{
|
|
if (ParseString ("/*") == null) {
|
|
return null;
|
|
}
|
|
|
|
int startLineIndex = lineIndex;
|
|
|
|
var commentResult = ParseUntil (String("*/"), _commentBlockEndCharacter, null);
|
|
|
|
if (!endOfInput) {
|
|
ParseString ("*/");
|
|
}
|
|
|
|
// Count the number of lines that were inside the block, and replicate them as newlines
|
|
// so that the line indexing still works from the original source
|
|
if (commentResult != null) {
|
|
return new string ('\n', lineIndex - startLineIndex);
|
|
}
|
|
|
|
// No comment at all
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
CharacterSet _commentOrNewlineStartCharacter = new CharacterSet ("/\r\n");
|
|
CharacterSet _commentBlockEndCharacter = new CharacterSet("*");
|
|
CharacterSet _newlineCharacters = new CharacterSet ("\n\r");
|
|
}
|
|
}
|
|
|