如何禁用对文件中一段文本的解析?

How to disable parsing for a piece of text in a file?

我的文件结构是:

`pragma TOKEN1_NAME TOKEN1_VALUE
`pragma TOKEN2_NAME TOKEN2_VALUE
`pragma TOKEN3_NAME TOKEN3_VALUE
`pragma TOKEN4_NAME TOKEN4_VALUE
 VHDL_TEXT{

 // A valid VHDL text goes here.
}
`pragma TOKEN2_NAME TOKEN2_VALUE
 VHDL_TEXT{

 // VHDL text
}

我需要将 VHDL 文本按原样传递到输出 file.I 可以通过在 lex 文件末尾设置默认规则来实现:

Rule:  .    { append_to_buffer(*yytext); }

我的 Lex 文件中还有其他规则列表来处理标记。

我遇到的问题是如何处理VHDL文本中也包含一些可以被Lex规则识别的标记的情况?

换句话说,我想禁用检测进一步的有效令牌,我发现我感兴趣的文本并在它结束后再次开始检测。

正如 rici 间接指出的那样,您需要能够区分在有效的 VHDL 设计规范或部分中出现的尾随定界符“}”和出现的右大括号。

请参阅 IEEE Std 1076-2008,15.3 Lexical elements, separators, and delimiters 我们发现“{”和“}”在 VHDL 中未用作分隔符。

它们是其他特殊字符(15.2 字符集,使用 ISO/IEC 8859-1:1998),需要在可能出现图形字符的地方进行处理。

graphic_character ::=
    basic_graphic_character | lower_case_letter | other_special_character

这些包括扩展标识符 (15.4.3)、字符文字 (15.6)、字符串文字 (15.7)、位字符串文字 (15.8)、注释 (15.9) 和工具指令 (15.11)。

需要在产生式中识别这些词汇元素,否则将“}”识别为规则的分隔符。

目前只定义了一个工具指令(24.1 保护工具指令),其中两个大括号字符的使用将包含在 VHDL 词汇元素中。词汇元素中的所有其他用法都直接定界。 (并且您可以放弃工具指令支持,在 VHDL 中,它们基本上还调用单独的词法、句法和语义分析)。

本质上你需要运行一个 VHDL 词法分析器来遍历 'VHDL text' 你规则定界符右大括号会像拇指一样突出(作为例外,作为 VHDL 文本的结束定界符).

大约现在,如果可能的话,如果可以通过引用来处理 VHDL,您的生活会更轻松。您的机制与在 VHDL 中包含工具指令一样复杂(这可以像您的 VHDL 文本一样使用预处理器完成)。

这是对 FUZxxl 添加的 标签的回应。

当您需要处理的源文件中有本质上不同的语言,这些语言具有清晰的分界标记(如您的 VHDL_TEXT 标记),词法分析器可以轻松识别这些语言,这是最简单的事情是使用 flex 独占开始状态 (%x)。在你的情况下,你会做类似的事情:

%{
/* some global vars for holding aux state */
static int brace_depth;
static Buffer vhdl_text;
%}

%x VHDL

%%

.. normal lexer rules for your non-vhdl stuff

VHDL_TEXT[ \t]*{    { brace_depth = 1;
                      BufferClear(vhdl_text);
                      BEGIN(VHDL); }
<VHDL>"{"           { BufferAppend(vhdl_text, *yytext);
                      brace_depth++; }
<VHDL>"}"           { if (--brace_depth == 0) {
                          BEGIN(INITIAL);
                          yylval.buf = BufferExtract(vhdl_text);
                          return VHDL_TEXT; }
                      BufferAppend(vhdl_text, *yytext); }
<VHDL>--.*\n        { BufferAppendString(vhdl_text, yytext); }
<VHDL>\"[^"\n]\"    { BufferAppendString(vhdl_text, yytext); }
<VHDL>\[^\\n]\   { BufferAppendString(vhdl_text, yytext); }
<VHDL>.|\n          { BufferAppend(vhdl_text, *yytext); }

这会将 VHDL_TEXT {...} 和 return 中大括号之间的所有内容作为单个标记收集到您的解析器(正确匹配嵌套大括号,如果有是 VHDL 文本中的任何内容。)您可以通过添加如下规则在 VHDL 代码中执行类似宏替换的内容:

<VHDL>{IDENT}       { if (Macro *mac = lookup_macro_by_name(yytext)) {
                          BufferAppendString(vhdl_text, mac->replacement);
                      } else {
                          BufferAppendString(vhdl_text, yytext); } }

您可能还需要一个 <VHDL><<EOF>> 规则来检测 vhdl 文本中缺少的结尾 } 并给出适当的错误消息。