所以现在在我的词法分析器中,我试图跳过某些标记,例如注释和空格,只是我需要将它们添加到“跳过列表”中,而不是完全隐藏它们。
在我的扫描仪框架中
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文件,因此缺少常量)
所有_TryReadUntilBlockEnd("*/")
所做的全部读取,直到找到结尾的* /为止。这是一种经过充分测试的方法,出于解释此问题的目的,可以忽略不计,除非作为我如何匹配评论结尾的解释。这从gplex接管了基础输入,并处理了基础输入流本身的前进(例如fget()
或C中我忘记的任何东西)。除了阅读整个评论之外,这里基本上是中性的。 Skip(478)
是相关的位,不是这个。
在许多情况下,它都可以正常工作。唯一的问题是我在解析C#的递归下降解析器中使用它,因此堆栈变得很重,并且当我有大量的行注释流时,它会溢出。
我可以通过找到某种运行比赛的方式来解决它,而不必再次调用lex动作,而不是调用yylex()
-如果可以的话,我可以将其重写为迭代方式,但是我不知道该怎么做,以及我想做什么从生成的代码中看到,这表明不可能。
我可以解决它的另一种方法-这是我的首选方法-在一次匹配中匹配多个C#行注释。这样,我只递归一次。
但是这是我认为默认情况下处于禁用状态的多行匹配表达式?
如何在flex,lex或* gplex中启用多行匹配?还是有解决上述问题的另一种方法? *首选gplex 1.2.2,但完全没有记录]
此时我将采取任何措施。预先感谢!
我根本不应该调用yylex()。感谢乔纳森和里奇的评论。