[我试图跳过gplex(flex / lex端口)中的令牌,并且使用yylex()导致堆栈溢出。有没有更好的跳过方法?

问题描述 投票:0回答:1

所以现在在我的词法分析器中,我试图跳过某些标记,例如注释和空格,只是我需要将它们添加到“跳过列表”中,而不是完全隐藏它们。

在我的扫描仪框架中

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,但完全没有记录]

此时我将采取任何措施。预先感谢!

c# lex
1个回答
0
投票

我根本不应该调用yylex()。感谢乔纳森和里奇的评论。

© www.soinside.com 2019 - 2024. All rights reserved.