我对词法分析器和解析器之间的任务分离感到有些困惑。
我正在尝试编写一个解析器,它使用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
,这直觉听起来更像是解析器的任务?
答案 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