如何使用ANTLR4多次重写令牌流



我使用出色的ANTLR4库实现了简单的预处理器。程序本身在几个迭代中运行——在每个迭代中,未来的输出都会略有修改。

目前我使用TokenStreamRewriter及其方法deleteinsertAfterreplacegetText

不幸的是,我无法重写之前重写过的令牌(得到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的观点。我们需要一个重写树

相关内容

  • 没有找到相关文章

最新更新