102 lines
2.4 KiB
C#
102 lines
2.4 KiB
C#
namespace DevDisciples.Parsing;
|
|
|
|
public class ParserContext<TToken> : ParsableStream<Lexer<TToken>.Token> where TToken : Enum
|
|
{
|
|
private readonly TToken _endOfSource;
|
|
|
|
protected ParserContext(Memory<Lexer<TToken>.Token> tokens, TToken endOfSource) : base(tokens)
|
|
{
|
|
_endOfSource = endOfSource;
|
|
}
|
|
|
|
public bool Check(TToken type, int offset = 0)
|
|
{
|
|
if (Ended()) return false;
|
|
if (Equals(Peek(offset).Type, _endOfSource)) return false;
|
|
return Equals(Peek(offset).Type, type);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks whether the passed sequence can be matched against the current parsing context.
|
|
/// </summary>
|
|
/// <param name="sequence"></param>
|
|
/// <returns></returns>
|
|
public bool CheckSequence(params TToken[] sequence)
|
|
{
|
|
for (var i = 0; i < sequence.Length; i++)
|
|
{
|
|
if (!Check(sequence[i], i))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool Ended()
|
|
{
|
|
return base.Ended() || Equals(Current.Type, _endOfSource);
|
|
}
|
|
|
|
public bool Match(TToken token)
|
|
{
|
|
var matched = Check(token);
|
|
if (matched) Advance();
|
|
return matched;
|
|
}
|
|
|
|
public bool MatchAny(params TToken[] types)
|
|
{
|
|
for (var i = 0; i < types.Length; i++)
|
|
{
|
|
if (Check(types[i]))
|
|
{
|
|
Advance();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool MatchSequence(params TToken[] sequence)
|
|
{
|
|
for (var i = 0; i < sequence.Length; i++)
|
|
{
|
|
if (!Check(sequence[i], i))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < sequence.Length; i++)
|
|
{
|
|
Advance();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public Lexer<TToken>.Token Previous()
|
|
{
|
|
return Peek(-1);
|
|
}
|
|
|
|
public Lexer<TToken>.Token Consume(TToken type, string message)
|
|
{
|
|
if (Check(type)) return Advance();
|
|
throw Error(message);
|
|
}
|
|
|
|
public Exception Error(string message)
|
|
{
|
|
return new SyntaxException(Report.FormatMessage(Current, message));
|
|
}
|
|
|
|
public Exception Error(Lexer<TToken>.Token token, string message)
|
|
{
|
|
return new SyntaxException(Report.FormatMessage(token, message));
|
|
}
|
|
}
|