如何使用ANTLR生成的语法文件?

2024-01-26

我认为这是一个愚蠢的问题,但我刚刚开始使用 ANTLR。我将他们教程中的“SimpleCalc”语法放在一起,并以 C 作为目标语言生成它。我得到了 SimpleCalcParser.c/.h 和 SimpleCalcLexer.c/.h 作为输出,并且我能够编译它们并成功构建。但现在,我如何实际使用生成的代码?我无法在文档中找到任何有用的内容。

下面是我的 main() 函数。这也是来自教程。

 #include "SimpleCalcLexer.h"

 int main(int argc, char * argv[])
 {

    pANTLR3_INPUT_STREAM           input;
    pSimpleCalcLexer               lex;
    pANTLR3_COMMON_TOKEN_STREAM    tokens;
    pSimpleCalcParser              parser;

    input  = antlr3AsciiFileStreamNew          ((pANTLR3_UINT8)argv[1]);
    lex    = SimpleCalcLexerNew                (input);
    tokens = antlr3CommonTokenStreamSourceNew  (ANTLR3_SIZE_HINT, TOKENSOURCE(lex));
    parser = SimpleCalcParserNew               (tokens);

    parser  ->expr(parser);

    // Must manually clean up
    //
    parser ->free(parser);
    tokens ->free(tokens);
    lex    ->free(lex);
    input  ->close(input);

    return 0;
 }

编辑:根据第一个响应,我应该说我运行了这样的程序:“./testantlr test.txt”,其中 test.txt 包含“4+1”。没有输出。

例如,从这里我将如何访问生成的语法树中的“4”,或打印出整个语法树?基本上,我如何访问 ANTLR 生成的语法树中的内容?


当我第一次尝试它时,我也面临着同样的困惑。这是一个非常明显的问题/问题,这使得它在教程中似乎没有明确和直接地解决,这使得它变得更加奇怪。

我发现摆脱困惑的方法是“returns”关键字:

token returns [TreeNode value]
    :    WORD { $value = new TreeNode( "word", $WORD.Text ); }
    |    INT { $value = new TreeNode( "int", $INT.Text ); }
    ;

WORD:    ('a'..'z'|'A'..'Z')+;
INT :    ('0'..'9')+;

TreeNode是我制作的一个类。棘手的地方是如何使用一系列(例如多个标记)来做到这一点。我想出的解决方案是递归:

expr returns [Accumulator value]
    :   a=token  (WS+ b=expr)?
    {
        if( b != null )
        {
            $value = new Accumulator( "expr", a.value, b.value );
        } else
        {
            $value = new Accumulator( "expr", a.value );
        }
    }
    ;

Accumulator 是我制作的一个类,它有两个不同的构造函数。一个构造函数封装单个令牌,另一个构造函数封装单个令牌和另一个 Accumulator 实例。请注意,规则本身是递归定义的,并且b.value是一个累加器实例。为什么?因为 b 是一个 expr,并且 expr 的定义有returns [Accumulator value].

最终生成的树是一个累加器实例,它对所有令牌进行了分组。要实际使用该树,您需要进行一些设置,然后调用与解析内容的规则同名的方法:

Antlr.Runtime.ANTLRStringStream stringstream =  new Antlr.Runtime.ANTLRStringStream( script );
TokenLexer lexer = new TokenLexer( stringstream );
Antlr.Runtime.CommonTokenStream tokenstream = new Antlr.Runtime.CommonTokenStream( lexer );
TokenParser parser = new TokenParser( tokenstream );

Accumulator grandtree = parser.expr().value;

希望这对遇到这种困惑的人有所帮助。


Update

由于系统允许您将目标语言代码散布在看似任意模式的位置,因此有一种更直接的方法可以将项目收集到列表中。成语是:

sequence returns [String k]
    :   (e=atom { $k = $e.k; })
        (e=atom { $k += ", " + $e.k; })*
        { $k = "sequence (" + $k + ")"; } ;

一个字符串k被初始化为第一个原子的 k 值,后续原子得到+= to k。片段$e.k指的是atom returns [String k]其他地方定义的规则。如果没有这样的规则,您可以使用text财产(即$e.text,哪些代币有。我不确定非代币是否具有此属性。如果没有,你可以这样做:

nonToken returns [String whatever] : e=TOKEN { $whatever = $e.text; } ;

然后您可以在更高的规则中使用它,例如

e=nonToken { System.out.println($e.whatever); }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用ANTLR生成的语法文件? 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 确定 FieldInfo 是否是编译器生成的 backingfield

    标题几乎说明了一切 我怎么知道我是否正在获得编译器为 get 生成的 backingfield 设置 属性 我正在运行此代码来获取我的 FieldInfos Class MyType private int foo public int b
  • 是否可以在 Kotlin 中创建递归函数类型?

    我有代表流程中步骤的函数 每个函数还知道下一步 如果有的话 我希望能够做类似的事情 fun fooStep Step do something return barStep the next step is barStep 这些函数是从中央
  • 无法使用作为映射值传递的 Java SQL 语句对象访问临时表

    我的代码目前的工作原理与此类似 public void foo Statement st String sqlStr String tempTableName String aString foo tempTableName boolean
  • 如何独立测试模型的回调方法?

    我在模型中有一个方法 class Article lt ActiveRecord Base def do something end end 我还对该方法进行了单元测试 spec models article spec rb describ
  • 由志愿翻译人员本地化 Delphi 2009 应用程序的流程?

    我有一个免费的科学应用程序 近 100 个国家 地区的数千人正在使用该应用程序 许多人主动提出免费翻译 现在 D2009 使这变得更容易 通过集成和外部本地化工具 加上本机 Unicode 支持 我希望在几种语言中实现这一点 并稳步添加尽可
  • 当我想返回 ResultSet 时在哪里关闭 JDBC 连接

    看来ResultSet当我关闭时会自动关闭Connection 但我想归还ResultSet并在另一种方法中使用它 然后我不知道在哪里关闭Connection and PreparedStatement public ResultSet e
  • Python:类型错误:* 之后的参数必须是序列

    我有这段代码 我尝试在新线程中发送 UDP 数据报 import threading socket address localhost 9999 def send sock sock sendto Message address print
  • 找到具有相同索引节点的所有文件的最快方法是什么?

    我知道的唯一方法是 find home xdev samefile file1 但确实很慢 我想找到一个类似的工具locate 当你有很多文件时 真正的问题就出现了 我认为操作是 O n 没有来自的映射inode命名 唯一的方法是遍历整个文
  • 如何解决 Eclipse SVN 中的冲突

    在使用 Eclipse 进行编码并使用 SVN 作为团队存储库时 我在 Eclipse 中遇到冲突 假设我有冲突并且有 3 个自动生成的文件 解决冲突后 我找不到如何提交冲突解决方案并自动删除生成的文件的命令 在Eclipse之外的SVN中
  • 在 PHP 中附加 XML 节点

    大家好 有人可以帮我用 PHP 修改下面的 XML 文档吗 这个问题的主要原因是我想附加一个虚拟 XML 节点 其标签名称为Service到活动 gt gt 正文 gt gt 服务 gt gt 服务安装 下面是XML文档
  • 在单元测试中提取哈希种子

    我需要获取 python 用于复制的随机哈希种子failing单元测试 If Python哈希种子 https docs python org 3 using cmdline html envvar PYTHONHASHSEED被设置为非零
  • TS 2540:无法分配给样式,因为它是只读属性

    我正在创建一个textarea我的 TSX 标记中的元素 以及Vim 中的 TS 类型检查器 https github com neoclide coc nvim抱怨2540 Cannot assign to style because i
  • 仅第一个媒体查询工作

    使用媒体查询时 似乎只有第一组有效 我不知道为什么 如果我交换它们 那么仍然只有第一个有效 我尝试过从最大宽度更改为最小宽度 我尝试删除 and 条件 我尝试删除所有 Javascript 我尝试删除所有 CSS 只保留带有 body di
  • PowerShell Unicode 字符意外转换

    我有一个程序 它使用一些哈希表来解析信息 我遇到了一些关于外国字符的奇怪问题 下面是准确的表述 Props P1 Norte Americano e Ingl s Expressions E1 Props P1 Expressions E1
  • 什么是 Linux 本地定时器中断?

    一切都在标题中 欢迎任何优秀文档的链接 本地定时器中断是在 APIC 上实现的定时器 它仅中断特定的 CPU 而不是引发可由任何 CPU 处理的中断 Bovet 和 Cesati 的 Understanding the Linux Kern
  • 在 C# 中将 string.Empty 转换为(通用)T?

    我有一个实用方法 它从旧的返回强类型值 INI配置类型文件 带有签名 internal static T GetIniSetting
  • 使用 Google 登录,仅允许组织域帐户

    我正在尝试创建一个只能通过 Google 登录才能访问且只能使用 GSuite 组织域 的 Web 应用程序 我希望这样做 而不需要事先初始化允许哪些域 这意味着它允许在 Google 下注册的所有电子邮件地址 但不允许 gmail com
  • 发布到 azure 后,与 MVC4 捆绑不起作用

    您好 我正在尝试为我的应用程序捆绑我的脚本 我的调试正在工作 如果我使用 Web debug 发布 一切都会正常 但是当我使用 Web releases 发布时 我的脚本不会加载 一切都在本地运行 只有当我从 VS2012 发布到 Azur
  • Swift 3 - Firebase 推送通知,我该怎么办?

    我确实喜欢下面的 Swift 2 但它在 Swift 3 中不起作用 我该如何提供这个 如果有人解释一下那就太好了 didFinishLaunchingWithOptions let notificationSettings UIUserN
  • 如何使用ANTLR生成的语法文件?

    我认为这是一个愚蠢的问题 但我刚刚开始使用 ANTLR 我将他们教程中的 SimpleCalc 语法放在一起 并以 C 作为目标语言生成它 我得到了 SimpleCalcParser c h 和 SimpleCalcLexer c h 作为