【问题标题】:Matching `\` in Flex在 Flex 中匹配 `\`
【发布时间】:2014-06-29 06:34:17
【问题描述】:

我正在尝试在 flex 中创建一个简单的状态机,它必须确保跨越多行的字符串必须具有 \ 用于换行。具体来说:

"this is \
ok"

"this is not
ok"

第一个有效。第二个不是。

我有以下状态机:

expectstring     BEGIN(expectstr);
<expectstr>[^\n]     {num_lines++;}
<expectstr>\         {flag = true;}
<expectstr>\n        {printf("%s\n", flag ? "True" : False);}

但是当我尝试编译这个状态机时,flex 告诉我\ 的规则无法匹配。这是为什么呢?

我查看了this,但无法弄清楚。

【问题讨论】:

  • 反斜杠是转义字符。像这样使用它 \\
  • @Eduardo 仍然说规则无法匹配。
  • 反斜杠不是换行符。因此,首先出现的 not-a-newline 规则将匹配反斜杠。
  • @rici 这就是我所怀疑的。所以已经用[^\n\\] 替换了[^\n],但这也失败了。
  • @rici 经过深思熟虑,我将[^\n] 替换为[^\n|^\\],然后用&lt;expectstr&gt;\ ` which is working. But am I correct with [^\n | ^\]? Concretely, is my reasoning here that match everything that is not \n` 而不是 ``?

标签: c++ compiler-construction flex-lexer lexical-analysis


【解决方案1】:

在 flex 中,以下模式匹配换行符以外的任何内容:

.

你也可以这样写

[^\n]

但是.比较正常。

为了匹配反斜杠,你可以写

\\
"\\"
[\\]

同样,第一种方式是通常的方式。

重要的是要了解[...] 是一种表示一组字符的方式,并且大多数正则表达式运算符只是括号内的普通字符。同样,"..." 是一种表示字符序列的方式,大多数正则表达式运算符只是引号内的普通字符。

因此,

  • [a|b] 匹配一个字符,如果它是 a|b
  • "a|b" 匹配三字符序列 a | b
  • and|but 匹配三个字符序列 an 中的任何一个。

dbut 由于 flex 允许您匹配正则表达式,因此您实际上不需要手动构建状态机。只需使用适当的正则表达式。例如,以下将匹配以 " 开头和结尾的字符串,其中 \ 可用于转义自身以及换行符,其中换行符(除了逃脱的)是非法的。我认为这是你的目标。

\"([^"\n\\]|\\(.|\n))*\"

您应该确保您了解它的工作原理;互联网上有很多关于正则表达式的很好的解释(甚至更糟糕的解释,所以试着找一个知道他们在说什么的人写的)。总结如下:

\"     A literal double-quote
(...)* Any number of repetitions of:
  [^"\n\\]   Anything other than a double-quote, newline, or backslash
  |          Or
  \\         A literal backslash, followed by
  (...)      Grouping
    .          Anything other than a newline
    |          Or
    \n         a newline

【讨论】:

  • 很好的回答@rici。还有一件事:我在网上阅读的很多东西都没有专门处理对偶()。具体来说,上例中的分组究竟是什么?为什么不使用[] 而不是()
  • @user1343318:它们的意思完全不同。括号用于分组。括号定义了一个字符集。
猜你喜欢
  • 2015-05-09
  • 2017-05-28
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2013-12-12
  • 1970-01-01
  • 2014-06-26
相关资源
最近更新 更多