两个基本的 ANTLR 问题

2024-05-07

我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出。我在 ANTLR 中选择的语言是 Python。

许多教程看起来非常复杂或详细阐述与我无关的事情;我真的只需要一些非常简单的功能。所以我有两个问题:

将值从一个规则“返回”到另一规则。

假设我有这样的规则:

赋值:name=IDENTIFIER ASSIGNMENT 表达式;

当识别到此规则时,我可以在 {} 中运行 Python 代码,并且可以通过执行以下操作将参数传递给 Python 代码以进行表达式:

赋值:名称=IDENTIFIER ASSIGNMENT 表达式[变量列表];

and then

表达式[变量列表]:等等

但是我如何将值“返回”到原来的规则呢?例如。如何计算表达式的值,然后将其发送回我的赋值规则以在 Python 中使用?

如何写出我的目标语言代码?

所以我有一些Python,它在识别规则时运行,然后我计算我想要该语句生成的程序集。但是我怎么说“将这串汇编指令写到我的目标文件中”呢?

任何与此类内容相关的优秀教程(属性语法、编译为 AST 以外的内容等)也会有所帮助。如果我的问题没有太多意义,请让我澄清;我很难理解 ANTLR。



将值从一个规则返回到另一规则

假设您想要解析简单的表达式并在运行时提供可在这些表达式中使用的变量映射。一个简单的语法,包括自定义 Python 代码,returns规则中的语句和参数vars语法的入口点可能如下所示:

grammar T;

options {
  language=Python;
}

@members {
  variables = {}
}

parse_with [vars] returns [value]
@init{self.variables = vars}
  :  expression EOF                            {value = $expression.value}
  ;

expression returns [value]
  :  addition                                  {value = $addition.value}
  ;

addition returns [value]
  :  e1=multiplication                         {value = $e1.value}
                       ( '+' e2=multiplication {value = value + $e2.value}
                       | '-' e2=multiplication {value = value - $e2.value}
                       )*
  ;

multiplication returns [value]
  :  e1=unary                                  {value = $e1.value}
              ( '*' e2=unary                   {value = value * $e2.value}
              | '/' e2=unary                   {value = value / $e2.value}
              )*
  ;

unary returns [value]
  :  '-' atom                                  {value = -1 * $atom.value}
  |  atom                                      {value = $atom.value}
  ;

atom returns [value]
  :  Number                                    {value = float($Number.text)}
  |  ID                                        {value = self.variables[$ID.text]}
  |  '(' expression ')'                        {value = $expression.value}
  ;

Number : '0'..'9'+ ('.' '0'..'9'+)?;
ID     : ('a'..'z' | 'A'..'Z')+;
Space  : ' ' {$channel=HIDDEN};

如果您现在使用 ANTLR v3.1.3(没有更高版本!)生成解析器:


java -cp antlr-3.1.3.jar org.antlr.Tool T.g  

并运行脚本:

#!/usr/bin/env python
import antlr3
from antlr3 import *
from TLexer import *
from TParser import *

input = 'a + (1.0 + 2) * 3'
lexer = TLexer(antlr3.ANTLRStringStream(input))
parser = TParser(antlr3.CommonTokenStream(lexer))
print '{0} = {1}'.format(input, parser.parse_with({'a':42}))

您将看到打印以下输出:


a + (1.0 + 2) * 3 = 51.0  

请注意,您可以定义多个“返回”类型:

parse
  :  foo              {print 'a={0} b={1} c={2}'.format($foo.a, $foo.b, $foo.c)}
  ;

foo returns [a, b, c]
  :  A B C            {a=$A.text; b=$B.text; b=$C.text}
  ;

如何写出目标语言代码

最简单的方法就是简单地把print自定义代码块内的语句并将输出通过管道传输到文件:

parse_with [vars]
@init{self.variables = vars}
  :  expression EOF                            {print 'OUT:', $expression.value}
  ;

然后像这样运行脚本:

./run.py > out.txt

这将创建一个文件“out.txt”,其中包含:OUT: 51.0。如果你的语法不是那么高,你可能会侥幸逃脱。但是,这可能会变得有点混乱,在这种情况下,您可以将解析器的输出设置为template:

options {
  output=template;
  language=Python;
}

并通过您自己定义的模板发出自定义代码。

See:

  • StringTemplate:5 分钟简介 http://www.antlr.org/wiki/display/ST/Five+minute+Introduction
  • 哪里可以获取Python ANTLR包来使用StringTemplate? https://stackoverflow.com/questions/5198902/where-to-get-python-antlr-package-to-use-stringtemplate
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两个基本的 ANTLR 问题 的相关文章

  • 解析lxml.etree._Element内容

    我从以下元素中解析出 table td align center valign top a href ConfigGroups aspx cfgID 451161 amp prjID 11778 amp grpID DTST target
  • 如何计算 numpy 数组中元素的特定范围

    我有一个像这样的数组 import numpy as np data np array 0 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
  • 对 numpy 数组的每 n 个元素求平均值

    我有一个 numpy 数组 我想创建一个新数组 它是每个连续三元组元素的平均值 因此 新数组的大小将是原始数组的三分之一 举个例子 np array 1 2 3 1 2 3 1 2 3 应该返回数组 np array 2 2 2 谁能建议一
  • 我应该使用 Pylons 还是 Pyramid?

    我本来打算从 Django 迁移到 Pylons 但后来我遇到了 Pyramid 塔架和金字塔有什么区别 我读了一些文字塔书 http pylonsbook com 目前涵盖 Pylons 0 9 7 并且想知道它是否是 Pylons 和
  • 字符串中数字的连续相加

    我是一名正在学习 python 的新程序员 并且在如何完成此任务方面遇到了困难 所以本质上我有一个从文件导入的数字字符串需要读取 并且需要将第一个数字的总和添加到第二个数字并将其转换为正确的 ascii 字符 因此 例如 如果我正在读取字符
  • 读取大文件并制作字典

    我有一个大文件 我需要读取它并从中制作字典 我希望这一切能够尽可能快 然而我的Python代码太慢了 这是一个显示问题的最小示例 首先制作一些假数据 paste lt seq 20000000 lt seq 2 20000001 gt la
  • 增加 sigmoid 预测输出值?

    我创建了一个用于文本分类的 Conv1D 模型 当在最后一个密集处使用 softmax sigmoid 时 它产生的结果为 softmax gt 0 98502016 0 0149798 sigmoid gt 0 03902826 0 00
  • 初始化整数变量以进行比较

    我正在学习麻省理工学院的开放课件课程计算机科学和 Python 编程简介 https ocw mit edu courses electrical engineering and computer science 6 0001 introd
  • Django 模板:输出带有所有小数位的浮点数

    我如何在 django 模板中输出这个数字 小数位数是可变的 我事先不知道 x 0 000015 1 x 输出是 1 5e 05 2 x stringformat f 输出是 0 000015 这不是本地化的 应该有逗号 我需要对输出进行本
  • setUp() 中的 if 条件忽略测试

    在unittest python库中 存在函数setUp and tearDown用于设置变量和其他测试前后的事情 如何运行或忽略 setUp 中条件的测试 您可以致电if cond self skipTest reason in setU
  • 获取SVG绘图的边界框

    我想提取 SVG 绘图的边界框 由于 Python 已经在系统上可用并且还用于执行其他任务 因此我不想使用 JavaScript 或任何其他语言 我的理解是是否可以计算单个元素的边界框 但我不知道如何计算 整个绘图的边界框只是所有元素的最小
  • Django Rest框架Json解析

    我想解析传入的POSTdjangoviews py 文件中的数据 发布数据 number 17386372 data banana apple grapes 这是我尝试读取上述传入数据的方法request views py class Fr
  • 禁用或限制 /o/applications(django rest 框架、oauth2)

    我目前正在使用 Django Rest 框架编写 REST API 并使用 oauth2 进行身份验证 使用 django oauth toolkit 我对他们俩都很满意 他们做的正是我想要的 然而 我有一个担忧 我正在将我的应用程序传递到
  • Django 自定义文件存储系统

    我有一个自定义存储 import os from django core files storage import Storage class AlwaysOverwriteFileSystemStorage Storage def get
  • 从值数组中计算 sympy 表达式

    我正在尝试 sympy 但遇到了一个无法解决的问题 使用 scipy 我可以编写一个表达式并计算 x 值数组 如下所示 import scipy xvals scipy arange 100 100 0 1 f lambda x x 2 f
  • 如何在我的 heroku 应用程序上安装软件包?

    我有一个使用 Shortuuid 的应用程序 https pypi python org pypi shortuuid 0 1 https pypi python org pypi shortuuid 0 1 当我使用 runapp py
  • 子进程调用,它们是并行完成的吗?

    我一直在谷歌搜索这个问题的答案 但似乎没有一个答案 谁能告诉我如果subprocess模块是否并行调用 Python 文档建议它可用于生成新进程 但没有提及它们是否并行 如果它们可以并行完成 您能否给我举一个例子或将我链接到一个例子 这取决
  • pyodbc 无法正确处理 unicode 数据

    我确实使用 pyodbc 成功连接了 MySQL 数据库 并且它可以很好地处理 ascii 编码的数据 但是当我打印使用 unicode utf8 编码的数据时 它引发了错误 UnicodeEncodeError ascii codec c
  • XGBoostError:[10:10:03] /workspace/src/tree/updater_gpu_hist.cu:1407:gpu_hist 中的异常:NCCL 失败

    PROJECT Nvidia 开发者项目 https developer nvidia com blog gradient boosting decision trees xgboost cuda 在 Google Colab 环境中 MY
  • gis计算点和多边形/边界之间的距离

    我想使用 python 计算一个点到一个国家边界之间的距离shapely 它应该工作得很好 point distance poly 例如在这里展示查找多边形形状上最近点的坐标 https stackoverflow com question

随机推荐