Compiler construction Quex 0.69.4生成包含自身的包含文件,导致无限循环

Compiler construction Quex 0.69.4生成包含自身的包含文件,导致无限循环,compiler-construction,lexer,quex,Compiler Construction,Lexer,Quex,我在使用Quex 0.65.7的继承代码库上工作。它可以编译,但在编译过程中需要-fppermissive,这不是我愿意接受的。由于g++中需要-fpermissive选项的代码存在于Quex本身作为基础提供的文件中,因此我尝试使用Quex 0.69.4构建lexer,使用项目的Quex_0.69.4-0_all.deb文件安装。Lexer的定义非常简单。它位于文件lexer.qx中,完全粘贴在下面: header { #include <cstdlib> } de

我在使用Quex 0.65.7的继承代码库上工作。它可以编译,但在编译过程中需要
-fppermissive
,这不是我愿意接受的。由于g++中需要
-fpermissive
选项的代码存在于Quex本身作为基础提供的文件中,因此我尝试使用Quex 0.69.4构建lexer,使用项目的
Quex_0.69.4-0_all.deb
文件安装。Lexer的定义非常简单。它位于文件
lexer.qx
中,完全粘贴在下面:

header {
        #include <cstdlib>
}

define {
        P_IDENTIFIER          [_a-zA-Z][_a-zA-Z0-9]*
}

mode ONE_AND_ONLY
{
    <<EOF>>     => RULE_TOKEN_TERMINATION;

    [ \t\r\n]+  { }
    "/*"([^*]|[\r\n]|("*"+([^*/]|[\r\n])))*"*"+"/" { }
    "//"[^\n]*"\n"           { }
    "+"    => RULE_TOKEN_PLUS;
    "-"    => RULE_TOKEN_MINUS;
    "/"    => RULE_TOKEN_DIVIDE;
    "*"    => RULE_TOKEN_TIMES;
    ";"    => RULE_TOKEN_SEMICOLON;
    "("    => RULE_TOKEN_LEFTPAREN;
    ")"    => RULE_TOKEN_RIGHTPAREN;
    "||"   => RULE_TOKEN_LOGICALOR;
    "&&"   => RULE_TOKEN_LOGICALAND;
    "<="   => RULE_TOKEN_LESSEQUAL;
    ">="   => RULE_TOKEN_GREATEREQUAL;
    "<"    => RULE_TOKEN_LESS;
    ">"    => RULE_TOKEN_GREATER;
    "["    => RULE_TOKEN_LEFTSQBRACKET;
    "]"    => RULE_TOKEN_RIGHTSQBRACKET;
    "=="   => RULE_TOKEN_EQUAL;
    {P_IDENTIFIER} => RULE_TOKEN_IDENTIFIER(Lexeme);
    [0-9]+      => RULE_TOKEN_INTEGER(Lexeme);
}
#include "zs_expr_eng-token.hxx"
--foreign token id File
选项中提到的文件同样简单:

#define RULE_TOKEN_TERMINATION                      1
#define RULE_TOKEN_UNINITIALIZED                    2
#define RULE_TOKEN_SEMICOLON                        3
#define RULE_TOKEN_IDENTIFIER                       4
#define RULE_TOKEN_LEFTSQBRACKET                    5
#define RULE_TOKEN_RIGHTSQBRACKET                   6
#define RULE_TOKEN_LOGICALOR                        7
#define RULE_TOKEN_LOGICALAND                       8
#define RULE_TOKEN_LESSEQUAL                        9
#define RULE_TOKEN_GREATEREQUAL                    10
#define RULE_TOKEN_LESS                            11
#define RULE_TOKEN_GREATER                         12
#define RULE_TOKEN_EQUAL                           13
#define RULE_TOKEN_PLUS                            14
#define RULE_TOKEN_MINUS                           15
#define RULE_TOKEN_DIVIDE                          16
#define RULE_TOKEN_TIMES                           17
#define RULE_TOKEN_LEFTPAREN                       18
#define RULE_TOKEN_RIGHTPAREN                      19
#define RULE_TOKEN_INTEGER                         20
选项
--foreign id file show
的输出表明已读取并理解所有令牌:

command line: Token ids found in file '../../grammar/grammar.h' {
command line:      RULE_TOKEN_DIVIDE         => 'DIVIDE'
command line:      RULE_TOKEN_EQUAL          => 'EQUAL'
command line:      RULE_TOKEN_GREATER        => 'GREATER'
command line:      RULE_TOKEN_GREATEREQUAL   => 'GREATEREQUAL'
command line:      RULE_TOKEN_IDENTIFIER     => 'IDENTIFIER'
command line:      RULE_TOKEN_INTEGER        => 'INTEGER'
command line:      RULE_TOKEN_LEFTPAREN      => 'LEFTPAREN'
command line:      RULE_TOKEN_LEFTSQBRACKET  => 'LEFTSQBRACKET'
command line:      RULE_TOKEN_LESS           => 'LESS'
command line:      RULE_TOKEN_LESSEQUAL      => 'LESSEQUAL'
command line:      RULE_TOKEN_LOGICALAND     => 'LOGICALAND'
command line:      RULE_TOKEN_LOGICALOR      => 'LOGICALOR'
command line:      RULE_TOKEN_MINUS          => 'MINUS'
command line:      RULE_TOKEN_PLUS           => 'PLUS'
command line:      RULE_TOKEN_RIGHTPAREN     => 'RIGHTPAREN'
command line:      RULE_TOKEN_RIGHTSQBRACKET => 'RIGHTSQBRACKET'
command line:      RULE_TOKEN_SEMICOLON      => 'SEMICOLON'
command line:      RULE_TOKEN_TERMINATION    => 'TERMINATION'
command line:      RULE_TOKEN_TIMES          => 'TIMES'
command line:      RULE_TOKEN_UNINITIALIZED  => 'UNINITIALIZED'
command line: }
Lexer生成成功完成,但生成的文件中有
zs_expr_eng-token.hxx
,其内容粘贴如下:

header {
        #include <cstdlib>
}

define {
        P_IDENTIFIER          [_a-zA-Z][_a-zA-Z0-9]*
}

mode ONE_AND_ONLY
{
    <<EOF>>     => RULE_TOKEN_TERMINATION;

    [ \t\r\n]+  { }
    "/*"([^*]|[\r\n]|("*"+([^*/]|[\r\n])))*"*"+"/" { }
    "//"[^\n]*"\n"           { }
    "+"    => RULE_TOKEN_PLUS;
    "-"    => RULE_TOKEN_MINUS;
    "/"    => RULE_TOKEN_DIVIDE;
    "*"    => RULE_TOKEN_TIMES;
    ";"    => RULE_TOKEN_SEMICOLON;
    "("    => RULE_TOKEN_LEFTPAREN;
    ")"    => RULE_TOKEN_RIGHTPAREN;
    "||"   => RULE_TOKEN_LOGICALOR;
    "&&"   => RULE_TOKEN_LOGICALAND;
    "<="   => RULE_TOKEN_LESSEQUAL;
    ">="   => RULE_TOKEN_GREATEREQUAL;
    "<"    => RULE_TOKEN_LESS;
    ">"    => RULE_TOKEN_GREATER;
    "["    => RULE_TOKEN_LEFTSQBRACKET;
    "]"    => RULE_TOKEN_RIGHTSQBRACKET;
    "=="   => RULE_TOKEN_EQUAL;
    {P_IDENTIFIER} => RULE_TOKEN_IDENTIFIER(Lexeme);
    [0-9]+      => RULE_TOKEN_INTEGER(Lexeme);
}
#include "zs_expr_eng-token.hxx"
这并不是全部,还有7个新行字符-所以它基本上是空的,并且包括它自己,没有保护。这当然意味着编译器无法编译以下源代码:

Compiling prog.cpp
In file included from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                 from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
<many many maaaaany lines cut>
                  from lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1,
                  from lexer/package-arm-linux-gnueabihf/./lib/declarations:22,
                  from zs_expr_eng.hxx:49,
                  from grammar.y:13,
                  from prog.cpp:2:
 lexer/package-arm-linux-gnueabihf/zs_expr_eng-token.hxx:1:33: error: #include nested too deeply
  #include "zs_expr_eng-token.hxx"
                                  ^
编译prog.cpp
在lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1中包含的文件中,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1,
来自lexer/package-arm-linux-gnueabihf//lib/declarations:22,
来自zs_expr_english.hxx:49,
来自语法。y:13,
来自项目cpp:2:
lexer/package arm linux gnueabihf/zs_expr_eng-token.hxx:1:33:错误:#包含嵌套太深
#包括“zs_expr_eng-token.hxx”
^

有什么办法可以阻止它吗?我不认为这是常见的情况,因为它会破坏所有基于Quex的项目。

因此,这个版本(
0.69.4
)或更早版本引入了很多更改,并且也破坏了对不同文件扩展名的支持(
--fes
--file extension scheme
)或者至少在使用此选项时没有投诉。从调用中删除
--fes xx
选项到
quex
并根据需要更改文件名(同时将
quex::Token
更改为生成的类的名称)后,一切正常。至少现在是这样。

因此,这个版本(
0.69.4
)或更早版本似乎引入了很多更改,并且还中断了对不同文件扩展名的支持(
--fes
--file extension scheme
),或者至少在使用此选项时没有抱怨。从调用中删除
--fes xx
选项到
quex
并根据需要更改文件名(同时将
quex::Token
更改为生成的类的名称)后,一切正常。至少现在是这样。

A作为《Quex》的作者,我至少可以说这不是故意的行为。我需要调查一下。“--fes”选项仍受支持。谢谢你提交错误报告。你的问题会很快得到解决。作为Quex的作者,我至少可以说这不是故意的行为。我需要调查一下。“--fes”选项仍受支持。谢谢你提交错误报告。你的问题会很快得到解决。