C# 讽刺:如何禁止2个令牌之间的空格?
我正试图以类似的方式定义PHP样式的变量: 很好,除了允许在C# 讽刺:如何禁止2个令牌之间的空格?,c#,grammar,irony,C#,Grammar,Irony,我正试图以类似的方式定义PHP样式的变量: 很好,除了允许在$和标识符之间放置空格之外。我想防止这种情况发生。怎么做 我必须创建一个新的定制终端吗?如果是这样,我还能利用IdentifierTerminal的魔力吗 在IdentifierTerminal中翻找,我看到实际上有一个“NameIncludePrefix”的标志,但它只在一个地方使用。前缀似乎存储在此CompoundTokenDetails对象中。。。我不知道怎么用编辑:别担心,这是一条死胡同。这些标志用于向变量的行为添加修改器
$
和标识符之间放置空格之外。我想防止这种情况发生。怎么做
我必须创建一个新的定制终端吗?如果是这样,我还能利用IdentifierTerminal
的魔力吗
在IdentifierTerminal
中翻找,我看到实际上有一个“NameIncludePrefix”的标志,但它只在一个地方使用。前缀似乎存储在此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;
}
}
用于表示以下内容的标识符终端:
语法错误,应为:{real string$true-false
但是变量却给了我这个错误:
无效字符:“c”
我认为前一个错误更有用。我真的不明白为什么它会抛出一个不同的错误……我怎么能让它这样说呢?不确定这一个是否有用:
因此,为两行共享它:
var identifier = new IdentifierTerminal("Identifier", IdFlags.NameIncludesPrefix);
identifier.AddPrefix(Strings.AllLatinLetters, IdFlags.None); //[a-zA-Z]([a-zA-Z0-9])
我认为您不会以完全相同的方式使用它们,但可能会使用类似的方式。对我来说,您想要的东西目前显然不受支持(在源代码中查看)。请参阅关于(非常大的空间)的讨论,它被标识为“#number”,不允许在两个空间之间留有空格
我认为使用非终端不是一种方式。语法的工作原理是,标记之间可以有空格。因此,您真正需要的是遵循页面底部-部分自定义终端中给出的建议,并扩展终端类以满足您的需要
或者,最简单的选择是引入标志,使前缀成为必需的。扩展IdentifierTerminal
类并重写TryMatch
方法
如果您在CompoundTerminalBase
类中查看此方法,TryMatch
方法的基本功能是:
ReadPrefix(如果找到或未找到前缀,则忽略更多)
ReadBody(如果未读取正文,则失败)
读后缀
ReadPrefix
方法设置details.Prefix
标志(如果找到前缀)。因此,在调用ReadPrefix
后,您可能需要检查新引入的标志是否具有强制前缀,如果已设置,则可以检查是否也设置了details.Prefix
标志,否则会发出错误
祝你好运:)
我同意Jan的观点,这应该在扫描器中处理,而不是在解析器中处理
在extraFirstChars中包含“$”是否符合您的要求
public IdentifierTerminal(string name, string extraChars, string extraFirstChars)
我不知道您使用的是哪种版本的讽刺,但在当前版本中,我能够使用AllFirstChars实现这一点:
var localVariable = new IdentifierTerminal(NodeType.LocalVariable);
localVariable.AllFirstChars = "$";
希望这能有所帮助不。前缀仍然是可选的。我希望它是必需的。这几乎是默罕默德一字不差地说的话……这并不像它看起来的那样。(自从我看到这个,我就一直在想一个“多么讽刺!”的笑话,但没有想到任何…)我还没有尝试过这个,但我会在它过期之前给你+250。看起来不错。让我知道它是怎么回事,尤其是如果你没有弄明白。接近…查看我的问题更新?也许你有其他建议?人力资源管理…也许这是新的。不记得看到过。如果我再回到这个项目,我必须尝试一下。
var identifier = new IdentifierTerminal("identifier", IdFlags.NameIncludesPrefix);
identifier.AddPrefix("$", IdFlags.None);
public IdentifierTerminal(string name, string extraChars, string extraFirstChars)
var localVariable = new IdentifierTerminal(NodeType.LocalVariable);
localVariable.AllFirstChars = "$";