0

来自莱克斯,

假设lex结构的定义是:

... definitions ...
%%
... rules ...
%%
... subroutines ...

在一个示例文件中,我首先从定义部分中看到以下行:

  %x PP PRAGMA

然后在规则部分,我看到:

<PP>[ \t\r]*                { }
<PRAGMA>.                   { }
^[ \t]*#[ \t]*version       { BEGIN PP; return VERSION_TOK; }

所以,我的问题来了(我理解 lex 的一般概念):

  1. 什么是 PP PRAGMA?我应该如何理解 %x?
  2. 对于规则部分:是什么意思?他们不应该是象征,对吧?
  3. BEGIN PP 是什么意思?
4

1 回答 1

2

<PP>并且<PRAGMA>是“开始条件”。事实上,它们是“排他的”开始条件,因为它们是用%x. (%s将声明“包容性”开始条件。)

我不知道为什么它们被称为开始条件;“开始”这个词有点令人困惑。您可以将它们视为词汇状态,但这也会有点令人困惑,因为“状态”通常意味着不同的东西。

在词法分析过程中的任何时刻,lex都有一个活跃的“开始条件”。大多数时候,(预定义的默认)启动条件 INITIAL 处于活动状态;在您没有声明任何开始条件的情况下总是如此。您可以使用宏“输入”开始条件BEGIN(CONDITION)

规则开始<CONDITION>仅在 CONDITION 是活动开始条件时使用。一条规则在尖括号内可以有多个条件名称,或者它可以有<*>(表示所有条件)或根本没有条件。只要活动条件是“包含”,就会使用未指定条件的规则。如果活动条件是“排他的”,则仅使用专门命名条件的规则(包括<*>通配符规则)。

条件实际上是整数常量,当前条件是 YY_START 的值。例如,您可以将它们保存起来并在以后恢复它们,尽管lex提供了一个方便的条件堆栈以使其更容易。

我相信BEGIN的正常定义是:

#define BEGIN YY_START =

这就是为什么您不必在条件名称周围加上括号(如在 BEGIN PP 中),但我个人认为这是不好的风格,因为至少一些 lex-alikes 实际上将 BEGIN 定义为带有参数的宏。

顺便说一句,开始条件真的很方便。

于 2012-10-11T05:32:34.043 回答