Files
Mementos/Unity/Alternate Genre Jam/Assets/Ink/InkLibs/InkCompiler/InkParser/CommentEliminator.cs
2021-06-30 21:39:19 +10:00

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");
}
}