Flex正则表达式文字字符

时间:2013-03-21 14:40:10

标签: regex cygwin expression flex-lexer

我在使用flex设置正则表达式以匹配类似C的文字字符时遇到了一些麻烦。

我需要根据语法和不正确的字符匹配正确的字符字符,例如具有未终止的字符文字。

2个规则,一个用于正确的一个,一个用于未终止的。

chrlit          (\')([^\\\'\n]|(\\.))(\')
untermchrlit    (\')([\\|\']|(.))*

我需要有关正则表达式的帮助,因为它们不能正常工作。以下是一些示例 应该如何工作:

'          -> unterminated char constant
'/'        -> CHRLIT('/')
'('        -> CHRLIT('(')
'a"b"c"de  -> unterminated char constant
'abc       -> unterminated char constant
'abc\      -> unterminated char constant
'\\'       -> CHRLIT('\\')
';'        -> CHRLIT(';')
''         -> unterminated char constant
'a'        -> CHRLIT('a')
'\'        -> unterminated char constant 
'\;'       -> CHRLIT('\;')
'\\\'      -> unterminated char constant
'\\\       -> unterminated char constant    
'\/'       -> CHRLIT('\/')
'a\'       -> unterminated char constant
'\\        -> unterminated char constant
'\t'       -> CHRLIT('\t')

1 个答案:

答案 0 :(得分:3)

问题在于,未终止的字符文字的模式也将匹配已终止的字符以及任何后续字符,除非字符文字位于行的末尾。与其尝试精确匹配未终止的字符文字,您可以让自己的生活变得更加简单,如果它遇到untermchrlit而不是{{1}的开头,则可以回到' }。 (因此,如果chrlit匹配所有可能终止的文字,它必须是未终止的。)(我还冒昧地从正则表达式中删除所有多余的括号和反斜杠,这使得它们对于它们的嘈杂程度降低了读出。)

chrlit

此解决方案的唯一问题是它将在未终止的chrlit '([^'\\\n]|\\.)' untermchrlit ' 之后立即继续扫描,这极有可能造成人为错误,特别是在确实存在匹配'的情况下,如'。在这里你真的想在第二个'too long'之后继续进行词法扫描(实际上,你可能想要将它标记为过长的字符文字,而不是未终止的字符文字)。要处理这种情况,您需要一组更复杂的模式。这是可能性:

'

我应该注意/* As before */ chrlit '([^'\\\n]|\\.)' /* Also as before, a catch-all case. */ untermchrlit ' /* Try to match single-quoted strings which are too short or too long */ emptychrlit '' /* The action for this regex *must* come after the action for chrlit */ longchrlit '([^'\\\n]|\\.)+' 这里也匹配longchrlit匹配的所有内容,但与OP中的模式不同,它不再匹配任何字符。重要的是按照评论的指示对动作进行排序,以便正确的文字将由chrlit进行匹配。 (如果您的订单错误,Flex应该发出警告。)

请记住,Flex始终匹配最长匹配,但如果多个规则与完全相同的令牌匹配,则Flex会选择第一个操作。

顺便说一下,至少在C中,以下 是一个有效的字符文字:

chrlit

那是因为紧跟新行的'a\ ' 已从输入中完全删除,因此第二个\被列为lexed,好像它紧跟在'之后。