我正在尝试在Irony中定义 PHP 风格的变量,如下所示:
variable.Rule = "$" + identifier;
效果很好,除了你可以在$
和之间放置空格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 中的解析方式有点奇怪......
无论如何,问题在于当我使用 this 时VariableTerminal
,而不是我之前使用 with"$" + IdentifierTerminal"
时的做法,当出现语法错误时,例如在这段代码中:
p cat
标识符终端曾经说过
语法错误,预期:{ 真正的字符串 $ 真假 ...
但是变量给了我这个错误:
无效字符:'c'
我认为前一个错误更有用。我真的不明白为什么它会吐出一个不同的错误......我怎样才能让它这么说呢?