Compiler construction Quex 0.69.4生成包含自身的包含文件,导致无限循环
我在使用Quex 0.65.7的继承代码库上工作。它可以编译,但在编译过程中需要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
-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”选项仍受支持。谢谢你提交错误报告。你的问题会很快得到解决。