使用 lex 对转义序列进行正则表达式说明

Regex clarification on escape sequences with lex

我正在创建一个 lexer.l 文件,除一部分外,它按预期工作。我有规则:

[\(\*.*\*\)] {}

我想这样做,所以当我在文件中遇到 (* this is a test *) 时,我什么都不做。但是,当我 运行 lex lexer.l 时,我收到有关规则 \(\*\) 的警告,指出它们永远无法满足。所以我想我的问题是为什么 [\(\*.*\*\)] {} 会干扰 \( 和其他人?我怎样才能抓住(* this is a test *)

具有注释语法 (*…*) 的语言通常允许嵌套注释,嵌套注释不容易被 (f)lex 识别,因为嵌套需要 context-free 语法,词法扫描器只实现常规语言。

如果你的评论不嵌套(这样(* something (* else *)是一个评论,而不是更长评论的前缀),那么你可以使用正则表达式

[(][*][^*]*[*]+([^*)][^*]*[*]+)*[)]

如果确实需要嵌套注释,可以使用开始条件和堆栈(或模拟堆栈,如下所示):

%x SC_COMMENT

%%
  int comment_nesting = 0;

"(*"             { BEGIN(SC_COMMENT); }
<SC_COMMENT>{
  "(*"           { ++comment_nesting; }
  "*"+")"        { if (comment_nesting) --comment_nesting;
                   else BEGIN(INITIAL); }
  "*"+           ; 
  [^(*\n]+       ;
  [(]            ; 
  \n             ; 
}

该片段摘自 this answer,稍作调整,因为该答案可识别嵌套的 /*…*/ 评论。那里有更完整的代码解释。