Я пытаюсь определить переменные в стиле PHP в Irony следующим образом:
variable.Rule = "$" + identifier;
Отлично работает, за исключением того, что вам разрешено ставить пробелы между ] $
и идентификатор
. Я хочу предотвратить это. Как?
Нужно ли мне создавать новый настраиваемый терминал? Если да, смогу ли я воспользоваться магией IdentifierTerminal
?
Покопавшись в IdentifierTerminal
, я вижу, что на самом деле есть флаг для «NameIncludesPrefix», но он используется только в одном месте. Похоже, префикс хранится в этом объекте CompoundTokenDetails
... который я не знаю, как использовать. Править: Ничего подобного, это был тупик. Эти флаги предназначены для добавления модификаторов к поведению переменной.
Это вроде работает ...
class VariableTerminal : Terminal
{
public VariableTerminal(string name) : base(name)
{
}
public override IList<string> GetFirsts()
{
return new[] { "$" };
}
public override Token TryMatch(ParsingContext context, ISourceStream source)
{
if (source.PreviewChar != '$') return null;
do
{
source.PreviewPosition++;
} while (!source.EOF() && char.IsLetter(source.PreviewChar));
var token = source.CreateToken(OutputTerminal);
return token;
}
}
Я не совсем уверен, что такое OuputTerminal
… Я думаю, это какое-то динамическое свойство, основанное на текущей позиции предварительного просмотра? Я думаю, что способ синтаксического анализа в Irony немного странный ...
В любом случае, проблема в том, что, когда я использую этот VariableTerminal
, вместо того, как я делал это раньше с ] "$" + IdentifierTerminal "
, когда есть синтаксическая ошибка, например, в этом коде:
p cat
Терминал идентификатора, используемый для сообщения
Ожидаемая синтаксическая ошибка: {реальная строка $ true false ...
Но вместо этого переменная выдает эту ошибку:
Недействительный символ: 'c'
Первая ошибка, я думаю, была более полезной. Я действительно не понимаю, почему он выдает другую ошибку ... как я могу заставить его сказать это вместо этого?