来自Lex,
假设lex结构的定义是:
... definitions ...
%%
... rules ...
%%
... subroutines ...
在其中一个示例文件中,我首先看到定义PART:
中的以下行 %x PP PRAGMA
然后在RULE PART中,我看到了:
<PP>[ \t\r]* { }
<PRAGMA>. { }
^[ \t]*#[ \t]*version { BEGIN PP; return VERSION_TOK; }
所以,这是我的问题(我理解lex的一般概念):
答案 0 :(得分:2)
<PP>
和<PRAGMA>
是“开始条件”。实际上,它们是“独占”的开始条件,因为它们是用%x
声明的。 (%s
会声明“包容性”的开始条件。)
我不知道为什么他们被称为开始条件; “开始”这个词有点令人困惑。您可以将它们视为词汇状态,但这也会有点混乱,因为“状态”通常意味着不同的东西。
在词法分析期间的任何时刻,lex
都有一个活跃的“开始条件”。大多数情况下,(预定义的默认)启动条件INITIAL处于活动状态;你总是没有声明任何开始条件的情况。您可以使用宏BEGIN(CONDITION)
“输入”开始条件。
仅在CONDITION为活动开始条件时才使用开始<CONDITION>
的规则。规则可以在尖括号内部具有多个条件名称,或者它可以具有<*>
(表示所有条件),或者它根本没有条件。只要活动条件为“包含”,就会使用未指定条件的规则。如果活动条件是“独占”,则仅使用专门命名条件的规则(包括<*>
通配符规则)。
条件实际上是整数常量,当前条件是YY_START的值。您可以将它们保存起来并稍后恢复它们,例如,尽管lex
提供了一个方便的条件堆栈,以便更容易。
我认为BEGIN的正常定义是:
#define BEGIN YY_START =
这就是为什么你不必在条件名称周围添加括号(如在BEGIN PP中),但我个人认为这是不好的风格,因为至少有一些lex-alikes实际上将BEGIN定义为一个参与的宏。
顺便说一下,开始条件非常方便。