2

我正在用 Ruby 编写一个递归下降解析器,它使用正则表达式来匹配终端。终端实际上​​是正则表达式,并与字符串中的当前位置匹配。

问题是终端正则表达式可以包含任何内容,包括匹配换行符的正则表达式。例如,匹配括号之间任何内容的终端/\([^\)]*\)/将消耗空格,包括我需要计算的换行符。我想出了几个解决方案,但它们都有我不特别喜欢的缺点:

  1. 每当匹配终端时,计算匹配中所有出现\n的次数。这实际上意味着每个字符串匹配两次而不是一次,

  2. 我可以不存储当前行,而是存储字符串的当前位置,仅在需要时通过遍历字符串来获取行号和列号。显然是有问题的,因为每次需要行号时都会遍历整个字符串。

  3. 除了允许正则表达式作为终端,我可以允许更简单的匹配器形式,类似于 ANTLR 允许的,然后手动匹配字符串,计算换行符。但是,这将需要大量的额外工作,并且会损失正则表达式所具有的匹配能力。

我倾向于第三种解决方案,但是我想看看是否有人处理过类似的问题并且有更好的解决方案可以为我省去麻烦。

4

1 回答 1

1

您可以使用解决方案 2,但使用源文件的“行索引”。

您进行第一个阶段以获取行开始位置的数组。然后,您可以通过二进制搜索获得 O(log n) 中某个位置的行号(n 是行数)。顺便说一句,它也可以让您在 O(1) 上获得您所知道的行中的位置pos - lines_start[line],这对于不平凡的代码行的错误报告非常宝贵。

于 2013-11-26T10:14:44.490 回答