我在使用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')
答案 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,好像它紧跟在'
之后。