C# I';我试图跳过gplex(一个flex/lex端口)中的令牌,使用yylex()会导致堆栈溢出。有没有更好的跳过的方法?
所以现在在我的lexer中,我试图跳过某些标记,比如注释和空格,除非我需要将它们添加到我的“跳过列表”,而不是完全隐藏它们 在我的扫描仪框架中,我有C# I';我试图跳过gplex(一个flex/lex端口)中的令牌,使用yylex()会导致堆栈溢出。有没有更好的跳过的方法?,c#,lex,C#,Lex,所以现在在我的lexer中,我试图跳过某些标记,比如注释和空格,除非我需要将它们添加到我的“跳过列表”,而不是完全隐藏它们 在我的扫描仪框架中,我有 public int Skip(int sym) { Token t = _InitToken(); t.SymbolId=sym; t.Line = Current.Line; t.Column =Current.Column; t.Position=Current.Position; t.Valu
public int Skip(int sym) {
Token t = _InitToken();
t.SymbolId=sym;
t.Line = Current.Line;
t.Column =Current.Column;
t.Position=Current.Position;
t.Value = yytext;
t.Skipped = null;
_skipped.Add(t);
return yylex();
}
请记住,这是c#,但接口与lex/flex中的c接口没有太大区别
然后,我在扫描仪中使用上述功能,如下所示:
"/*" { if(!_TryReadUntilBlockEnd("*/")) return -1; return Skip(478); }
\/\/[^\n]* { return Skip(477); }
其中477
是我的符号id(生成lex文件,因此缺少常量)
所有\u TryReadUntilBlockEnd(“*/”)
所做的都将被读取,直到它找到一个尾随的*/,并使用它。这是一个经过良好测试的方法,在这个问题中可以忽略,除了解释我如何匹配评论的结尾。这将从gplex接收底层输入,并处理底层输入流本身的推进(如fget()
或C语言中的任何东西)。基本上,它在这里是中立的,而不是阅读整个评论<代码>跳过(478)是相关位,而不是此位
它在很多情况下都很好用。唯一的问题是我在解析C#的递归下降解析器中使用它,因此堆栈变得很重,当我有大量行注释时,堆栈溢出
如果可能的话,我可以找到一些方法来运行匹配,而无需再次调用lex操作,而不用调用yylex()
,这样我就可以将其重写为迭代,但我不知道如何进行,从生成的代码中看到的情况表明这是不可能的
另一种解决方法——这是我的首选方法——是在一个匹配中匹配多个C#line注释。这样我只会重复一次
但我想这是默认禁用的多行匹配表达式
如何在flex、lex或*gplex中启用多行匹配?或者上述问题还有其他解决方案吗*首选gplex 1.2.2,但它完全没有文档记录
在这一点上我愿意接受任何东西。提前谢谢 我根本不应该打电话给yylex()。感谢Jonathan和rici的评论。您不能替换
返回Skip(478)代码>与刚才的跳过(478)
并从Skip
函数中删除对yylex()
的递归调用。如果不返回,lexer将从它停止的地方继续,使用输入而不添加递归调用。同样,从returnskip(477)中删除return
代码>。您可能会决定Skip
成为一个返回void
的函数。您是否还在空白规则中递归调用yylex?如果没有,你为什么在这里做?如果是的话,你为什么觉得有必要?我不知道我上周才开始使用这个工具,同时一直在开发解析器生成器,所以我现在的知识很糟糕。我从手册中收集了我能做的,suchI测试了你的建议Jonathan和rici。这起了作用,加快了我的解析速度。非常感谢你们两位。