antlr4数组实现:获取元素的值

2024-01-03

我正在尝试在 antlr4 中实现数组,但我不知道如何在初始化数组时获取数组的多个元素,如下所示:

int array[] = {1, 2};

我正在考虑将它们放入像这样的 HashMap 中,关键是索引:

public Map<Integer, Value> array_memory = new HashMap<Integer, Value>();

以下是我遵循的语法:

grammar GaleugParserNew;

/*
 * PARSER RULES
 */

declare_var 
: INTEGER ID '[' (INT)? ']' (ASSIGN '{' array_init '}')? SCOL 
;

array_init
: INT ',' array_init
| INT 
;


/*
* LEXER RULES
*/

SCOL : ';';

ASSIGN : '=';

INTEGER : 'int';

INT : [0-9]+;

我有一个变量可以计算声明_var 访问索引的 array_init 的次数。但我不知道如何访问具有多个元素的 array_init 。

这是我的 declare_var 访客:

@Override
public Value visitDeclareArray(GaleugParserNewParser.DeclareArrayContext ctx){
    String id = ctx.ID().getText(); //gets array name

    String size = ctx.INT().getText(); //get string version of array size
    int x = Integer.parseInt(size); //convert size(String) to int

    Value elem = this.visit(ctx.array_init());

    return Value.VOID;
}

这是我的 array_init 访问者:

@Override
public Value visitArray_init(GaleugParserNewParser.Array_initContext ctx){
    index += 1;
    return new Value(Double.valueOf(ctx.getText()));
}

如果您对如何访问 array_init 参考变量数量有任何建议,我想听听。谢谢你!


我正在考虑将它们放入像这样的 HashMap 中,关键是索引:

public Map<Integer, Value> array_memory = new HashMap<Integer, Value>();

Why? A List<Value>也会这样做,对吧?无需自己跟踪索引。

通过递归调用使事情变得更加复杂array_init rule:

array_init
 : INT ',' array_init
 | INT 
 ;

我会这样做:

array_init
 : INT ( ',' INT )*
 ;

然后你可以做这样的事情:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.TerminalNode;

import java.util.ArrayList;
import java.util.List;

public class Main {

  public static void main(String[] args) {

    String source = "int array[] = {1, 2};";

    GaleugParserNewLexer lexer = new GaleugParserNewLexer(CharStreams.fromString(source));
    GaleugParserNewParser parser = new GaleugParserNewParser(new CommonTokenStream(lexer));

    Value value = new EvalVisitor().visit(parser.declare_var());

    System.out.println(value);
  }
}

class Value {

  final Object value;

  public Value(Object value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return String.valueOf(this.value);
  }
}

class EvalVisitor extends GaleugParserNewBaseVisitor<Value> {

  @Override
  public Value visitDeclare_var(GaleugParserNewParser.Declare_varContext ctx) {
    List<Value> numbers = new ArrayList<>();
    if (ctx.array_init() != null) {
      for (TerminalNode tokenNode : ctx.array_init().INT()) {
        numbers.add(new Value(Integer.valueOf(tokenNode.getText())));
      }
    }
    return new Value(numbers);
  }
}

如果你运行这个Main类,以下内容将打印到您的控制台:

[1, 2]

EDIT

但是,如果我不是专门寻找 INT,而是想在包含我的语言中的所有数据类型的语法中寻找任何标记,该怎么办?我应该使用什么来代替 TerminalNode?

就像 1-2-3 一样简单,定义语法如下:

array_init
 : expr ( ',' expr )*
 ;

expr
 : '(' expr ')'          #nestedExpr
 | lhs=expr '+' rhs=expr #addExpr
 | INT                   #intExpr
 | ID                    #idExpr
 ;

然后做这样的事情:

import org.antlr.v4.runtime.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {

  public static void main(String[] args) {

    String source = "int array[] = { 123456789, (1 + 2), Q };";

    GaleugParserNewLexer lexer = new GaleugParserNewLexer(CharStreams.fromString(source));
    GaleugParserNewParser parser = new GaleugParserNewParser(new CommonTokenStream(lexer));

    Map<String, Value> memory = new HashMap<String, Value>(){{
      put("Q", new Value(42));
    }};

    Value value = new EvalVisitor(memory).visit(parser.declare_var());

    System.out.println(value);
  }
}

class Value {

  final Object value;

  public Value(Object value) {
    this.value = value;
  }

  int asInt() {
    return (Integer) value;
  }

  @Override
  public String toString() {
    return String.valueOf(this.value);
  }
}

class EvalVisitor extends GaleugParserNewBaseVisitor<Value> {

  final Map<String, Value> memory;

  EvalVisitor(Map<String, Value> memory) {
    this.memory = memory;
  }

  @Override
  public Value visitDeclare_var(GaleugParserNewParser.Declare_varContext ctx) {
    List<Value> numbers = new ArrayList<>();
    if (ctx.array_init() != null) {
      for (GaleugParserNewParser.ExprContext expr : ctx.array_init().expr()) {
        numbers.add(super.visit(expr));
      }
    }
    return new Value(numbers);
  }

  @Override
  public Value visitIntExpr(GaleugParserNewParser.IntExprContext ctx) {
    return new Value(Integer.valueOf(ctx.getText()));
  }

  @Override
  public Value visitAddExpr(GaleugParserNewParser.AddExprContext ctx) {
    return new Value(super.visit(ctx.lhs).asInt() + super.visit(ctx.rhs).asInt());
  }

  @Override
  public Value visitNestedExpr(GaleugParserNewParser.NestedExprContext ctx) {
    return super.visit(ctx.expr());
  }

  @Override
  public Value visitIdExpr(GaleugParserNewParser.IdExprContext ctx) {
    return this.memory.get(ctx.getText());
  }
}

这将打印:

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

antlr4数组实现:获取元素的值 的相关文章

随机推荐

  • 应用于行的几何平均值

    我有这个数据框作为例子 Col1 Col2 Col3 Col4 1 2 3 2 2 我想添加名为 Gmean 的第四列 用于计算每行前 3 列的几何平均值 怎样才能完成呢 Thanks 一种方法是Scipy s geometric mean
  • 是否可以将 Riak CS 与 Apache Flink 一起使用?

    我要配置filesystem状态后端和zookeeper恢复模式 state backend filesystem state backend fs checkpointdir recovery mode zookeeper recover
  • 错误:在此 Practice4HomePage Widget Flutter(BLoc) 上方找不到正确的 Provider

    在flutter中学习bloc时出现错误 错误是 错误 无法在此 Practice4HomePage 小部件上方找到正确的提供程序 发生这种情况是因为您使用了BuildContext不包括提供者 你的选择 有以下几种常见场景 您在您的目录中
  • bash 脚本如何对后台任务执行相当于 Ctrl-C 的操作?

    有没有什么方法可以调用子进程 以便它及其所有子进程都收到中断 就像您按 Ctrl C 执行前台任务一样 我试图终止一个调用长时间运行的子进程的启动器脚本 我试过了kill SIGINT child 它不会向其后代发送中断 因此是无操作 并且
  • Django 信号重定向

    当用户登录时 我检查它是否属于特定组 如果是这样 我会重定向到特定页面 这是我的代码 apps py def OperatorRedirect sender user request kwargs from struttura employ
  • 删除正在进行 I/O 的文件:它是文件系统和/或操作系统功能吗?

    我正在编写一个 shell 脚本 它将在 Linux 上运行 但可以对位于已安装分区上的文件进行操作 可能有也可能没有 ext 文件系统 例如 它可以是 NTFS FAT32 或任何基于 inode 或非 inode 的系统 可以进一步重新
  • 如何在 Github Actions macos 运行程序中签署和公证 PKG

    Context 我正在构建一个 Github Actions 作业建造 签署和公证一个 PKG 文件 我正在使用一个Apple ID 帐户 工作流程需要用户名和密码 以及开发者 ID 安装者带私钥的证书 加密 两者都保存为机密 base64
  • 为什么忽略 SIGTRAP 不适用于 asm?

    我试图忽略 SIGTRAP 我有以下概念验证代码 include
  • RNN 中的梯度累积

    在运行大型 RNN 网络时 我遇到了一些内存问题 GPU 但我想保持我的批量大小合理 所以我想尝试梯度累积 在一次性预测输出的网络中 这似乎是不言而喻的 但在 RNN 中 您为每个输入步骤执行多次前向传递 因此 我担心我的实施无法按预期进行
  • 如何防止键盘在颤振中按提交键时消失?

    我正在制作一个颤振应用程序 用户可以在其中键入消息并点击键盘中的发送按钮来发送消息 问题是当我按下发送按钮时 消息被发送 但键盘会自动消失 我怎样才能防止这种情况发生 提前致谢 TextField autofocus true keyboa
  • Python/Pandas 中是否有函数可以获取两个日期时间之间的业务时间增量?

    我有一个带有两个日期时间列的 pandas 数据框 我想计算 业务分钟 中列之间的时间增量 使用 offsets 方法添加业务时间增量很容易 但我似乎找不到内置的东西可以返回工作日 小时 分钟 秒的时间增量 我对 Python 很陌生 所以
  • PHP JSON 将值数组放入 HTML 表中

    我正在从 API URL 提取 JSON 数据 我需要提取特定的键并将它们放入包含列和行的表中 6 列 x 20 行 KEYS 都是彼此重复的 val 内容 JSON 示例 response result Leads row no 1 FL
  • 从 ajax 调用返回一个值到父函数

    我有一个函数 我需要返回通过 ajax 调用获取的 url var heatmap new google maps ImageMapType getTileUrl function coord zoom var tileURL get ge
  • v[i++] 在 C 中未定义吗?

    我正在尝试编写一个通过 a 检查 a 的函数char a 并且经常最终使用类似的东西 if a i x i 现在我真的很想将其更改为a i 相反 但它似乎不起作用 问题 我在这里做错了什么吗 还是有一个干净的替代方案来避免i 注意 目前函数
  • Nodejs 异步/等待延迟

    我对这段代码有问题 var request require request promise class Test constructor async Start var response await this getResponse awa
  • 如何在 Scala 中向 TrieMap[Long,List[Long]] 添加数据

    我有这个 val vertexIdListPartitions TrieMap Long List Long TrieMap 我需要添加List 3 at vertexIdListPartitions 3 我尝试这样做 vertexIdLi
  • 统计所有直接或间接向经理汇报的下属

    我在一项任务上遇到了问题 我需要统计直接或间接向特定经理汇报的所有下属 不同的 我有一个Employee像这样的表 EMPLOYEE ID Int MANAGER ID Int EMPLOYEE NAME varchar 200 Examp
  • 在代码中创建 Excel SpreadsheetML。 (没有 Excel!)

    在 Excel 2003 及更高版本中 可以使用 SpreadsheetML 格式生成仅包含 XML 样式表和 XML 数据文件的 Excel 电子表格 我在一些项目中使用过它并且效果很好 尽管这并不容易做到 我从 Microsoft 下载
  • 带交换的 Powershell——如何将所有详细输出附加到文件

    我正在尝试在我的脚本中添加一些日志记录 任何建议将不胜感激 首先 我想在出现问题时添加错误日志 例如 当找不到用户时 会抛出以下错误 无法执行该操作 因为在 HQ DC 6 domain com 上找不到对象 asdfa 类别信息 未指定
  • antlr4数组实现:获取元素的值

    我正在尝试在 antlr4 中实现数组 但我不知道如何在初始化数组时获取数组的多个元素 如下所示 int array 1 2 我正在考虑将它们放入像这样的 HashMap 中 关键是索引 public Map