在解析正则表达式时,词法分析器和解析器之间的任务分离

时间:2013-04-12 12:39:53

标签: regex parsing lexer

我对词法分析器和解析器之间的任务分离感到有些困惑。

我正在尝试编写一个解析器,它使用Perl样式的正则表达式并构建语法树。我的问题是识别诸如{n,m}之类的量词,这意味着前面的组或字符或字符类应至少出现n,但不超过m次。

重点是,{2,5asdf}等不完整/无效的量词不是量词,而是一组常规字符。

问题是:给定输入/a{2,5}/,词法分析器应该返回诸如DELIMITER CHARACTER QUANTIFIER_START NUMBER COMMA NUMBER QUANTIFIER_END DELIMITER END之类的tokes列表(问题是QUANTIFIER_START可能不是“真正的”开始一个量词,取决于下面的内容),或者它应该尝试匹配完整的量词并返回QUANTIFIER,这直觉听起来更像是解析器的任务?

1 个答案:

答案 0 :(得分:1)

使用lexer和parser分开的工具,在lexing期间通常没有空间可以更改标记。词法分析器通常独立于解析器运行,如果可能的话,使lexing上下文敏感是hacky(你可能想要谷歌PEG,或无扫描器解析,其中没有真正的分离lexing和解析)。

但是,这一切都取决于您使用的工具。我使用ANTLR创建了一个PCRE解析器,如果解析失败则使用回溯。因此,如果在解析{2,5a之后它无法构造量词(a无效),解析器将回溯到"{"并从此char创建一个LITERAL令牌,然后会继续。以一点RAM为代价,我启用了memoization,导致解析器在大输入上仍然表现良好。

它将X{2,5asdf}解析为:

'- ALTERNATIVE
   |- ELEMENT
   |  '- LITERAL='X'
   |- ELEMENT
   |  '- LITERAL='{'
   |- ELEMENT
   |  '- LITERAL='2'
   |- ELEMENT
   |  '- LITERAL=','
   |- ELEMENT
   |  '- LITERAL='5'
   |- ELEMENT
   |  '- LITERAL='a'
   |- ELEMENT
   |  '- LITERAL='s'
   |- ELEMENT
   |  '- LITERAL='d'
   |- ELEMENT
   |  '- LITERAL='f'
   '- ELEMENT
      '- LITERAL='}'

X{2,5} as:

'- ALTERNATIVE
   '- ELEMENT
      |- LITERAL='X'
      '- QUANTIFIER
         |- NUMBER='2'
         |- NUMBER='5'
         '- GREEDY

您可以在此处使用解析器:http://pcreparser.appspot.com/

ANTLR语法可以在这里找到:https://github.com/bkiers/PCREParser/blob/master/src/grammar/PCRE.g