使用 Antlr 获取标识符和函数名称

2024-01-11

我正在尝试使用和理解 AntLR,这对我来说是新的。我的目的是读取用 C 编写的源代码文件并从中提取标识符(变量和函数名称)。

在我的 C 语法中(文件C.g4) 考虑:

identifierList
    :   Identifier
    |   identifierList Comma Identifier
    ;
Identifier
    :   IdentifierNondigit
        (   IdentifierNondigit
        |   Digit
        )*
    ;

生成解析器和侦听器后,我创建了自己的标识符列表侦听器。

请注意,MyCListener 类扩展了 CBaseListener:

public class MyCListener extends CBaseListener {


@Override
public void enterIdentifierList(CParser.IdentifierListContext ctx) {
    List<ParseTree> children = ctx.children;
    for (ParseTree parseTree : children) {
        System.out.println(parseTree.getText());
    }

}

然后我在主课上有这个:

 String fileurl = "C:/example.c";

 CLexer lexer;
 try {
       lexer = new CLexer(new ANTLRFileStream(fileurl));
       CommonTokenStream tokens = new CommonTokenStream(lexer);
       CParser parser = new CParser(tokens);

       CParser.IdentifierListContext identifierContext = parser.identifierList();
       ParseTreeWalker walker = new ParseTreeWalker();
       MyCListener listener = new MyCListener();
       walker.walk(listener, identifierContext);

 } catch (IOException ex) {
       Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
 }

其中 example.c 是:

int main() {

// this is C

 int i=0; // i is int
 /* double j=0.0;
    C
 */
}

我究竟做错了什么? 也许我没有正确编写MyCListener,或者identifierList不是我需要监听的...真的不知道。抱歉,我什至不明白我的输出,为什么会有词法错误?:

line 3:4 mismatched input '(' expecting {<EOF>, ','}
main
(
)
{
int
i
=
0
;
}

正如你所看到的,我对此感到非常困惑。有人可以帮助我吗?请...


有了这一行:

CParser.IdentifierListContext identifierContext = parser.identifierList();

你试图将你的整个输入解析为identifierList。但您的输入不仅仅如此。

假设您正在使用C.g4来自 ANTLR4 Github 存储库 https://github.com/antlr/grammars-v4/blob/master/c/C.g4,尝试让解析器从语法的入口点开始(这是规则compilationUnit):

MyCListener listener = new MyCListener();
ParseTreeWalker.DEFAULT.walk(listener, parser.compilationUnit());

EDIT

这是一个快速演示:

public class Main {

    public static void main(String[] args) throws Exception {

        final List<String> identifiers = new ArrayList<String>();

        String source = "int main() {\n" +
                "\n" +
                "// this is C\n" +
                "\n" +
                " int i=0; // i is int\n" +
                " /* double j=0.0;\n" +
                "    C\n" +
                " */\n" +
                "}";

        CLexer lexer = new CLexer(new ANTLRInputStream(source));
        CParser parser = new CParser(new CommonTokenStream(lexer));

        ParseTreeWalker.DEFAULT.walk(new CBaseListener(){

            @Override
            public void enterDirectDeclarator(@NotNull CParser.DirectDeclaratorContext ctx) {
                if (ctx.Identifier() != null) {
                    identifiers.add(ctx.Identifier().getText());
                }
            }

            // Perhaps override other rules that use `Identifier`

        }, parser.compilationUnit());

        System.out.println("identifiers -> " + identifiers);
    }
}

这将打印:

identifiers -> [main, i]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Antlr 获取标识符和函数名称 的相关文章

随机推荐

  • Tensorboard 无法获取运行的第一个事件时间戳

    我正在尝试可视化我在远程服务器上训练的培训课程 我使用 scp 将文件复制到本地 iMac 中 我尝试通过运行张量板来可视化数据 它运行张量板网站 但我无法获得可视化效果 每个图表都有一个零点 我在终端上收到此警告 WARNING tens
  • 如何抑制“git rebase --continue”的编辑器?

    我经常重新调整交互式基础以对历史记录进行微小的更改 例如删除空白行或编辑一行 在大多数情况下 这些更改是基于一些同行评审 首先我这样做 git rebase interactive 83bbeb27fcb1b5e164318fa17c55b
  • 如何在Java中将英文数字转换为中文

    我必须将英文数字转换为中文数字 但中文的数字系统与英语不同 有什么办法可以在运行时将英文数字转换为中文吗 建议使用而不是自己滚动ICU4J http site icu project org 数字格式 http icu project or
  • 命名路由 _path 与 _url

    Rails 提供命名路线 http api rubyonrails org classes ActionDispatch Routing html 可以使用路径或 url 调用路由助手 例如来自文档 and provide these na
  • 当 Fiddler 可以解密时为什么要使用 HTTPS [重复]

    这个问题在这里已经有答案了 我刚刚发现 Fiddler 可以解密 HTTPS 流量 例如 我使用 HTTPS 在本地主机上部署了一个网站 在 Fiddler 中检查数据包时 我能够查看所有信息 因为它有解密选项 我的问题是 当 Fiddle
  • Java Spring Jackson json库返回unicode而不是文本

    我正在使用这个教程 http www mkyong com spring mvc spring 3 mvc and json example http www mkyong com spring mvc spring 3 mvc and j
  • SAP GUI 脚本 - 按钮按下失败

    我在运行 SAP GUI 的 Excel 文件中使用宏 有一个步骤 当我单击 SAP 中的按钮时 会弹出另一个窗口 为此 我编写了这样的代码 session findbyid wnd 0 XX btnXX press session fin
  • 使用模块在 Eclipse 中创建 Google App Engine 项目

    我一直在按照 cloud google com 上的建议使用 Eclipse 和 Maven 编写 GAE 应用程序 最近 我需要使用 后端 或一组不同的实例来处理特定任务 我发现 后端 已被弃用 取而代之的是 模块 在过去的几天里 我一直
  • C - for 循环的缩写,仅执行一次

    我在 Mac 上用 ANSI C 编写了命令行实用程序 其中包含为单链表创建冒泡排序数组的函数 我声明了循环变量 int a 0 int b 0 我以缩写风格编写了循环的冒泡排序 即 将变量初始化留空 for a lt size a for
  • 使用 Google 地图轨迹 API

    我必须开发一个车辆跟踪系统 我已经完成了 Google Map API 和 Google Map Tracks API 教程 IE Google 地图 API 网络 https developers google com maps docu
  • 在 Java 中如何将一个数组的值设置为另一个数组的值?

    假设您有两个数组 int a 2 3 4 int b 4 5 6 如何将数组 a 设置为数组 b 并使它们保持不同的不同对象 就像我想到这样做 a b 但这不起作用 因为它只是创建 a 引用数组b 那么 将两个数组设置为相等 同时保持它们独
  • 从序列图创建代码

    有没有办法从序列图生成代码 我能找到的只是逆向工程 即 从生成的代码中您可以获得序列图 有没有办法做其他事情 从图表到源代码生成 UML 类图已经实现了这一点 相同的链接http msdn microsoft com en us libra
  • 创建 App Engine 后端时找不到 gcm.jar 错误 => 建议安装已弃用的库

    使用 Android Developer Studio 我尝试从菜单中为现有 Android 项目创建 App Engine 后端 工具 gt Google Cloud 工具 gt 生成 App Engine 后端 错误消息是 找不到 gc
  • 如何将一些文件从一个 git 存储库移动到另一个(不是克隆),保留历史记录

    我们的 Git 存储库最初是一个庞大的 SVN 存储库的一部分 其中每个项目都有自己的树 如下所示 project1 branches tags trunk project2 branches tags trunk 显然 使用以下命令将文件
  • 在 PHP 中从序列化数组中获取一个值

    您认为从数组中获取单个值的最有效方法是什么 我知道它是什么 我知道它在哪里 目前我正在这样做 array unserialize storedArray var array keyOne 想知道是否有更好的方法 你做得很好 我想不出比你所做
  • 使用 UNION INSERT INTO SELECT 奇怪的顺序

    我有一个典型的非标准化表 tempTable 具有多个编号的列 rep1 rep2 所以我编写了一个脚本将非标准化数据插入到标准化表中 myTable insert into myTable select idRep rep FROM se
  • VBA 中的文本文件:打开/查找替换/另存为/关闭文件

    这是我希望做的伪代码 Open text File Find XXXXX and Replace with YYYY Save text File As Close text file 这就是我到目前为止所拥有的 Private Sub C
  • 在姓氏搜索中添加撇号

    我创建了一个过程 它将按姓氏返回申请人列表 我在搜索姓氏中带有撇号的申请人时遇到问题 例如 O Connor 您能帮忙找到这些申请人吗 以下是我的搜索代码 if Rtrim FirstName lt gt begin If Len Firs
  • 如何更改 R 中栅格图层的分辨率

    我正在使用 R 中的几个高分辨率栅格图层 对于我正在运行的某些分析来说 详细程度过高 因此我想通过降低分辨率来加快速度 坐标系为 UTM 因此单位为米 分辨率显示为 30 30 x y 所以看来这里的分辨率是30m 有人可以告诉我如何将分辨
  • 使用 Antlr 获取标识符和函数名称

    我正在尝试使用和理解 AntLR 这对我来说是新的 我的目的是读取用 C 编写的源代码文件并从中提取标识符 变量和函数名称 在我的 C 语法中 文件C g4 考虑 identifierList Identifier identifierLi