Flex 正则表达式文字 char

and*_*pcg 2 regex cygwin expression flex-lexer

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

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

2 条规则,一条为正确规则,另一条为未终止规则。

chrlit          (\')([^\\\'\n]|(\\.))(\')
untermchrlit    (\')([\\|\']|(.))*
Run Code Online (Sandbox Code Playgroud)

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

'          -> 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')
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 5

问题是,未终止的字符文字的模式也将匹配终止的字符以及任何后续字符,除非字符文字位于行的末尾。您可以像这样让自己的生活变得更简单,而不是尝试精确匹配未终止的字符文字,untermchrlit如果遇到一个'which不是a的开头,则返回到chrlit。(因此,如果chrlit匹配所有可能的终止文字,它必须是未终止的。)(我还冒昧地从正则表达式中删除了所有多余的括号和反斜杠,这使得它们阅读起来不那么嘈杂。)

chrlit          '([^'\\\n]|\\.)'
untermchrlit    '
Run Code Online (Sandbox Code Playgroud)

该解决方案的唯一问题是,它将在未终止后立即继续扫描',这很可能会产生人为错误,特别是在确实存在匹配的情况下',如 中所示'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]|\\.)+'
Run Code Online (Sandbox Code Playgroud)

我应该注意,longchrlit这里也匹配所有chrlit匹配的内容,但与OP中的模式不同,它不匹配任何更多字符。重要的是,按照注释指示的顺序对操作进行排序,以便正确的文字将由 匹配chrlit。(不过,如果顺序错误,flex 应该发出警告。)

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

顺便说一句,至少在 C 语言中,以下有效的字符文字:

'a\
'
Run Code Online (Sandbox Code Playgroud)

这是因为\紧随其后的换行符已从输入中完全删除,因此第二个'词法分析就像它紧随a.