在 C# 中行走 ANTLR AST 的教程? [英] Tutorial for walking ANTLR ASTs in C#?

查看:25
本文介绍了在 C# 中行走 ANTLR AST 的教程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道在 C# 中行走 ANTLR 生成的 AST 的教程吗?我能找到的最接近的是 this,但这并不是很有帮助.

Is anyone aware of tutorials for walking ANTLR-generated ASTs in C#? The closest I was able to find is this, but it's not terribly helpful.

我的目标是遍历基于我正在研究的特定领域语言生成的树,并使用这些树输出生成的 C# 代码.

My goal is to walk through trees that I'm generating based on a domain-specific language that I'm working on, and to use the trees to output generated C# code.

基于 Java 的教程也会有所帮助——任何提供有关如何遍历 ANTLR AST 的清晰示例的内容.

A Java-based tutorial would be helpful, too -- anything that provides clear examples of how to traverse ANTLR ASTs.

推荐答案

我通过改编 Manuel Abadia 的文章.

这是我的版本,我碰巧用它来将解析的代码转换为 C#.这些是步骤:

Here's my version, which I happen to be using to convert parsed code to C#. These are the steps:

  1. 使用您的输入实例化 ANTLRStringStream 或子类(它可以是一个文件或字符串).
  2. 实例化您生成的词法分析器,传入该字符串流.
  3. 使用词法分析器实例化令牌流.
  4. 使用该令牌流实例化您的解析器.
  5. 从解析器中获取顶级值,并将其转换为 CommonTree.
  6. 遍历树:
  1. Instantiate an ANTLRStringStream or subclass with your input (it can be a file or string).
  2. Instantiate your generated lexer, passing in that string stream.
  3. Instantiate a token stream with the lexer.
  4. Instantiate your parser with that token stream.
  5. Get the top-level value from your parser, and turn it into a CommonTree.
  6. Traverse the tree:

要获取节点的文字文本,请使用 node.Text.要获取节点的令牌名称,请使用 node.Token.Text.

To get the literal text of a node, use node.Text. To get the token name of a node, use node.Token.Text.

请注意,node.Token.Text 只会为您提供令牌的实际名称,前提是它是一个没有相应字符串的虚构令牌.如果它是一个真正的令牌,那么 node.Token.Text 将返回它的字符串.

Note that node.Token.Text will only give you the actual name of your token if it's an imaginary token with no corresponding string. If it's a real token, then node.Token.Text will return its string.

例如,如果您的语法中有以下内容:

For example, if you had the following in your grammar:

tokens { PROGRAM, FUNCDEC }

EQUALS : '==';
ASSIGN : '=';

然后你会得到 "PROGRAM""FUNCDEC""==""=" 来自node.Token.Text的对应访问.

Then you'll get "PROGRAM", "FUNCDEC", "==", and "=" from the corresponding accesses of node.Token.Text.

您可以在下面看到我的部分示例,或者您可以浏览 完整版.

You can see part of my example below, or you can browse the full version.

public static string Convert(string input)
{
    ANTLRStringStream sStream = new ANTLRStringStream(input);
    MyGrammarLexer lexer = new MyGrammarLexer(sStream);

    CommonTokenStream tStream = new CommonTokenStream(lexer);

    MyGrammarParser parser = new MyGrammarParser (tStream);
    MyGrammarParser.program_return parserResult = parser.program();

    CommonTree ast = (CommonTree)parserResult.Tree;

    Print(ast);
    string output = header + body + footer;

    return output;
}

public static void PrintChildren(CT ast)
{
    PrintChildren(ast, " ", true);
}

public static void PrintChildren(CT ast, string delim, bool final)
{
    if (ast.Children == null)
    {
        return;
    }

    int num = ast.Children.Count;

    for (int i = 0; i < num; ++i)
    {
        CT d = (CT)(ast.Children[i]);
        Print(d);
        if (final || i < num - 1)
        {
            body += delim;
        }
    }
}

public static void Print(CommonTree ast)
{
    switch (ast.Token.Text)
    {
        case "PROGRAM":
            //body += header;
            PrintChildren(ast);
            //body += footer;
            break;
        case "GLOBALS":
            body += "\r\n\r\n// GLOBALS\r\n";
            PrintChildren(ast);
            break;
        case "GLOBAL":
            body += "public static ";
            PrintChildren(ast);
            body += ";\r\n";
            break;

      ....
    }
}

这篇关于在 C# 中行走 ANTLR AST 的教程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆