BITFALL/Assets/GSpawn - Level Designer/Scripts/Parsing/Parser.cs

176 lines
4.0 KiB
C#
Raw Normal View History

2024-01-27 04:09:57 +08:00
#if UNITY_EDITOR
using UnityEngine;
using System.Collections.Generic;
namespace GSpawn
{
public abstract class Parser
{
private Lexer _lexer;
private int _cursorPos;
private List<string> _errors = new List<string>();
public bool reachedEnd { get { return _cursorPos >= _lexer.numTokens - 1; } }
public bool parse(Lexer lexer)
{
if (lexer.numTokens == 0)
{
Debug.LogError("Invalid token stream.");
return false;
}
_lexer = lexer;
parseImpl(lexer);
if (_errors.Count != 0)
{
foreach (var err in _errors)
Debug.LogError(err);
return false;
}
return true;
}
protected abstract void parseImpl(Lexer lexer);
protected abstract void syncOnError();
protected LexerToken peek()
{
return _lexer.getToken(_cursorPos);
}
protected int peekId()
{
return _lexer.getTokenId(_cursorPos);
}
protected string peekLexeme()
{
return _lexer.getTokenLexeme(_cursorPos);
}
protected LexerToken peekNext()
{
return _lexer.getToken(_cursorPos + 1);
}
protected int peekNextId()
{
return _lexer.getTokenId(_cursorPos + 1);
}
protected LexerToken peek(int offset)
{
return _lexer.getToken(_cursorPos + offset);
}
protected int peekId(int offset)
{
return _lexer.getTokenId(_cursorPos + offset);
}
protected LexerToken peekPrevious()
{
return _lexer.getToken(_cursorPos - 1);
}
protected int peekPreviousId()
{
return _lexer.getTokenId(_cursorPos - 1);
}
protected int advance()
{
if (reachedEnd) return _lexer.getEofId();
return _lexer.getTokenId(_cursorPos++);
}
protected int advance(int numTokens)
{
int id = _lexer.getEofId();
for (int i = 0; i < numTokens; ++i)
id = advance();
return id;
}
protected bool match(int id)
{
if (peekId() != id) return false;
advance();
return true;
}
protected bool matchExpect(int id, string errMsg)
{
if (peekId() != id)
{
reportErrorAndSync(errMsg, peek().line);
syncOnError();
return false;
}
advance();
return true;
}
protected bool checkExpectAny(string errMsg, params int[] ids)
{
foreach (var id in ids)
{
if (peekId() == id) return true;
}
reportErrorAndSync(errMsg, peek().line);
syncOnError();
return false;
}
protected bool matchAny(params int[] ids)
{
foreach (var id in ids)
{
if (peekId() == id)
{
advance();
return true;
}
}
return false;
}
protected bool matchAll(params int[] ids)
{
int numIds = ids.Length;
for (int i = 0; i < numIds; ++i)
{
if (peekId(i) != ids[i]) return false;
}
advance(numIds);
return true;
}
protected void reportErrorAndSync(string msg, int line)
{
_errors.Add("[" + line + "] Error: " + msg);
syncOnError();
}
protected string expectedIntLiteralMsg()
{
return "Expected int literal.";
}
protected string expectedPositiveIntLiteralMsg()
{
return "Expected positive int literal.";
}
}
}
#endif