我使用出色的ANTLR4库实现了简单的预处理器。程序本身在几个迭代中运行——在每个迭代中,未来的输出都会略有修改。
目前我使用TokenStreamRewriter及其方法delete
、insertAfter
、replace
和getText
。
不幸的是,我无法重写之前重写过的令牌(得到IllegalArgumentException
)。这不是一个bug,但根据源代码,无论如何都无法实现多次替换。
我认为存在一个适当的解决方案,因为这似乎是一个常见的问题。有人能告诉我吗?我宁愿使用一些现有的、经过测试的解决方案,也不愿重新实现重写器本身。
也许重写器不是合适的工具。
感谢的帮助
晚上好现在是针对相同问题的动态代码。首先,您必须在侦听器类中使Token流和重写器可见这是我的VB6Mylistener类的构造函数的代码
class VB6MYListener : public VB6ParserListener {
public: string FicName;
int numero ; // numero de la regle
wstring BaseFile;
CommonTokenStream* TOK ;
TokenStreamRewriter* Rewriter ;
// Fonctions pour la traduction avec le listener void functions
created by ANTLR4 ( contextes )
VB6MYListener( CommonTokenStream* tok , wstring baseFile, TokenStreamRewriter* rewriter , string Name)
{
TOK = tok; // Flux de tokens
BaseFile = baseFile; // Fichier entree en VB6
Rewriter = rewriter;
FicName = Name; // Nom du fichier courant pour suivi
}
在这里,我与听众进行了交叉。令牌流是TOK可见的所有功能无效
std::string retourchaine;
std::vector<std::string> TAB{};
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop>getTokenIndex(); i++)
{
TAB.push_back(TOK->get(i)->getText()); // HERE TOK
}
for (auto element : TAB)
{
if (element == "=") { element = ":="; }
if (element != "As" && element != "Private" && element != "Public")
{
std::cout << element << std::endl;
retourchaine += element ; // retour de la chaine au contexte
}
}
retourchaine = retourchaine + " ;";
Rewriter->replace(ctx->start, ctx->stop, retourchaine );
`
我使用的一种变通方法,因为我需要在令牌中进行替换,而当在一个上下文中有多个替换时,Tokenrewriter
无法正确执行作业。
在每个上下文中,我都可以使令牌流可见,并使用数组复制上下文中的所有令牌,并创建一个带有替换的字符串,然后使用Rewriter->replace( ctx->start , ctx->stop , tokentext ) ;
这里的一些代码用于上下文:
string TAB[265];
string tokentext = "";
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop->getTokenIndex(); i++)
{
TAB[i] = TOK->get(i)->getText();
// if (TOK->get(i)->getText() != "As" && TOK->get(i)->getText() != "Private" && TOK->get(i)->getText() != "Public")
//if (TOK->get(i)->getText() == "=")
//{
if (TAB[i] == "=") { TAB[i] = ":="; }
// if (TAB[i] == "=") { TAB[i] = "="; } // autres changements
if (TAB[i] != "As" && TAB[i] != "Private" && TAB[i] != "Public") { tokentext += TAB[i]; }
cout << "nombre de tokens du contexte" << endl;
cout << i << endl;
}
tokentext = tokentext + " ;";
cout << tokentext << endl;
Rewriter->replace(ctx->start, ctx->stop, tokentext);
这是我用来使工作健壮的基本代码。希望这会有用。
我认为重写令牌流不是一个好主意,因为您不能处理树的一般情况。ANTLR的TokenStreamRewriter工具非常有用。如果使用侦听器,则无法更改AST树和ANTLR创建的上下文。您必须使用Bufferedwriter来重写您在翻译的最终文件中本地更改的上下文。感谢Ewa Hechsman和她在github上的程序,从Pascal到Python。我认为这是专业项目的真正解决方案。所以我同意Ira Baxter的观点。我们需要一个重写树