-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathParserInput.cs
85 lines (70 loc) · 2.88 KB
/
ParserInput.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using System.Collections.Generic;
namespace Ara3D.Parakeet
{
/// <summary>
/// Wraps the input string to a parser, providing utility
/// functions find the column and row (line) from a character index.
/// </summary>
public class ParserInput
{
/// <summary>
/// When debug build is true, this will output the parsing steps to the console.
/// </summary>
public bool Debugging { get; }
public string File { get; }
public string Text { get; }
public IReadOnlyList<int> LineToChar { get; }
public IReadOnlyList<int> CharToLine { get; }
public ParserInput(string s, string file = "", bool debugging = false)
{
File = file;
Text = s;
Debugging = debugging;
var curLine = 0;
var lineToChar = new List<int>();
var charToLine = new List<int>();
lineToChar.Add(0);
for (var i=0; i < s.Length; i++)
{
charToLine.Add(curLine);
if (s[i] == '\n')
{
curLine++;
if (i < s.Length - 1)
lineToChar.Add(i + 1);
}
}
charToLine.Add(curLine);
LineToChar = lineToChar;
CharToLine = charToLine;
}
public int Length => Text.Length;
public int NumLines => LineToChar.Count;
public char this[int index] => Text[index];
public int GetLineLength(int lineIndex)
=> lineIndex >= LineToChar.Count - 1
? Text.Length - LineToChar[lineIndex]
: LineToChar[lineIndex+1] - 1 - LineToChar[lineIndex];
public string GetLine(int lineIndex)
=> Text.Substring(LineToChar[lineIndex], GetLineLength(lineIndex));
public int GetLineBegin(int charIndex)
=> LineToChar[GetLineIndex(charIndex)];
public int GetLineIndex(int charIndex)
=> charIndex >= Length ? LineToChar.Count - 1 : CharToLine[charIndex];
public int GetColumn(int charIndex)
=> charIndex - GetLineBegin(charIndex);
public int ClampLineNumber(int lineIndex)
=> lineIndex < 0 ? 0 : lineIndex >= NumLines ? NumLines - 1: lineIndex;
public int GetCharIndex(int lineIndex)
=> LineToChar[lineIndex];
public int GetCharIndex(int lineIndex, int columnIndex)
=> GetCharIndex(lineIndex) + Math.Min(GetLineLength(lineIndex), columnIndex);
public string GetIndicator(int charIndex)
=> new string(' ', GetColumn(charIndex)) + '^';
public static implicit operator ParserInput(string s)
=> new ParserInput(s);
public static ParserInput FromFile(string filePath)
=> new ParserInput(System.IO.File.ReadAllText(filePath), filePath);
}
}