lex/flex 规则的格式 - Pattern 和 Action 应该在同一行吗?

Format of lex/flex rules - Should Pattern and Action be on the same line?

我没有找到任何关于 lex 规则相对于操作的格式的解释(或者我错过了)。 这是一个例子:

  %%
  ^([ \r\t])*[abcd][^=].* 
              {  
                 return TOKEN1;
              }
  %%

相对于:

  %%
  ^([ \r\t])*[abcd][^=].* {  
                 return TOKEN1;
              }
  %%

我知道 %% 必须在没有任何 space 的新行上开始。但是,我想知道动作部分。我发现有时它会抱怨 "warning, rule cannot be matched" 当动作和模式在不同的行上时,如上例所示。当他们被带到同一条线上时,这个警告就会出现。但是,我有一个类似的规则,即使在新行开始操作时也不会发出警告。

我正在与 Bison 一起使用,尽管这个事实与问题无关。

来自Flex manual

5.2 Format of the Rules Section

The rules section of the flex input contains a series of rules of the form:

pattern   action

where the pattern must be unindented and the action must begin on the same line.


如果你更喜欢Posix specification for lex,也有类似的要求:

The rules in lex source files are a table in which the left column contains regular expressions and the right column contains actions (C program fragments) to be executed when the expressions are recognized.

ERE action
ERE action...

The extended regular expression (ERE) portion of a row shall be separated from action by one or more <blank> characters.

<blank> 在基本定义卷中定义为 space 或制表符。


Posix 禁止没有动作的规则行,尽管 Flex 将允许它们,就好像动作是 ;。规则部分中的缩进行通常逐字插入到输出中,但除非缩进行出现在第一条规则之前,否则结果是未定义的。至少,Posix 只是说结果未定义。 Flex(以及我认为的大多数 lex 实现)将 at 行复制到生成的文件中,它们将落在 action case 子句末尾的 break; 语句之后。如果这些行是注释,那将不是问题,这并不罕见。但实际的可执行代码可能会触发“无法访问的代码”警告,假设您在启用警告的情况下进行编译。

但是,Flex 也允许开始条件块,并且在开始条件块内您可以缩进模式。在这种情况下,将操作单独放在一行上会使 Flex 将其视为一种模式而不是插入的代码。