【问题标题】:How to write an ANTLR4 grammar for JSON objects如何为 JSON 对象编写 ANTLR4 语法
【发布时间】:2016-05-27 07:28:23
【问题描述】:

我很难弄清楚如何为抽象数据结构编写 ANTLR4 语法。例如,考虑一个 Python 程序,该程序读取和写入人员列表,其中一个人有姓名、电子邮件地址和电话号码。相同的抽象数据结构(一个 Python 字典列表)可以以多种格式存储,一个每行一个人的 csv 文件,一个带有对象列表的 JSON 文件,一个 XML 文件等,但我将首先JSON.

grammar People;
import JSON;

people: person+;
person: name email phone?;
name:   STRING;
email:  STRING;
phone:  STRING;

JSON 语法定义了七种value 类型,而 people 和 person 定义了我的抽象类型,但如何在不强制语法为 JSON 特定的情况下将它们链接在一起并不明显。

问题:假设有定义值类型array、obj和STRING的三种编解码器语法(JSON、CSV、XML),一个语法如何指定people是person的array,person是三个的obj命名为 STRINGS?

编辑:

为了澄清,我想读取一个 JSON 实例: [{"name": "Fred", "email": "fred@foo.com"}] 到一个由 ANTLR 语法定义的 Python 对象中,拒绝数据是有效的 JSON,但不是有效的 people 对象。并通过 import 使用不同的编解码器语法将该对象转换为 CSV 文件:“姓名、电子邮件、电话 \n Fred、fred@foo.com”。我还想使用相同的语法来生成验证人员列表的 JSON 实例的 JSON Schema 和验证人员列表的 XML 实例的 XSD 文件。

换句话说,我想知道 ANTLR 是否能够做与 ASN.1 相同的事情——独立于这些对象的序列化定义数据对象的结构。如果是这样,请了解 ANTLR 如何表示结构和编码/序列化之间的接口。

【问题讨论】:

  • 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。请参阅如何提问页面以帮助澄清此问题
  • 这是一个X/Y Problem,您正在尝试重新创建类似于 Jackson Mapper 库的东西。 ANTLR 不会帮助你。

标签: json antlr4 abstract-syntax-tree


【解决方案1】:

正如其他人所指出的,您真正寻找的似乎是一种用于将数据绑定到/来自对象的模型,类似于 Jackson 在 Java 中的工作方式。如果是这样,结构验证可以作为尝试将自描述(json、xml、csv 在某种程度上)中的结构绑定/映射到编程语言对象定义中的副作用而获得。 我假设 Python 中存在此类工具(假设这是您的平台)。

正如其他人所指出的,像 ANTLR 这样的基于语法的解析器似乎真的不是人们通常用来解决问题的东西。

除了数据绑定工具,另一类实用程序是模式语言和验证器,但问题是它们往往只适用于特定的数据格式,所以你会有 XML Schema、JSON Schema 等.可能可以用于其他类似的格式,但即使是看似相似的格式(XML、JSON),在逻辑数据模型上也往往存在显着差异。

【讨论】:

  • 我的目标是找到一种可以处理多种数据格式的架构定义语言,而不一定是可以完成问题中列出的翻译任务的工具。如果该语言存在,则可以开发工具。除了 ASN.1 之外,我唯一的可能是 ORM(Django 的 models.py 或从它派生的模式)。但是 python 模块或 SQL CREATE TABLE 命令文件不是通用模式语言。我希望 ANTLR 的语法可以适应这个目的,但可惜,没有。我喜欢 ASN.1,但很多人害怕它,所以我想要替代品。 ASN.1 是。
  • 理论上有几种模式语言可以工作; WebIDL 在某些时候看起来可能可用; Thrift IDL 有点通用。甚至可以考虑 protoc(来自 protobuf)甚至 Avro Schema。当然,有些人尝试使用 XML/JSON Schema 并取得了一些成功。然而,没有明显的跨语言选择。
【解决方案2】:

这不是 ANTLR 所做的

TL;DR

ANTLR 处理语法并生成代码以用目标语言解析该语法。

就是这样。


它不做序列化或反序列化或映射或其他任何事情。它只是做上面所说的。

它与解析表示紧密相关,而不是相反。 ANTLR 非常流行,如果它做了这种事情,就会有几十个例子来说明如何去做,并且会有一些你可以使用的无处不在的标准。这些不存在,因为这不是该工具的作用。

如果你想创建一些新的绑定语言,你可以用 ANTLR 来做,但是你将永远不会得到可以读取任何格式并映射它的 ANTLR 语法对于某些任意结构,这不是它的设计目的,它永远不会那样做,你正在尝试使用错误的工具来完成错误的工作。

ANTLR 是解析器编写器,您可以编写 JSON 解析器或 CSV 解析器或 XML 解析器,但您不能编写将所有这些转换为通用对象表示的语法文件。

您可以使用 ANTLR 解析 ANS.1,但它不会做任何其他事情。

JAXB 用于将 XML 与具有 可选 模式的对象进行反序列化/序列化。

Jackson 可以将 JSON、XML、CSV、YAML、Protocol Buffers 等与具有可选序列化特定模式的对象进行反序列化/序列化。

ASN.1 也不执行您的要求,它只是定义了一个独立于序列化的 schema,它 进行任何解析或验证。您将读取和处理 ASN.1 的工具与语言语法规范混为一谈。

这只是一个模式标准。一些独立的解析器解析特定的序列化方案,而不是一些命令式程序读取 ASN.1 并应用其规则。

JSON Schema 的存在是为了定义 JSON 文档, XML 模式和 DTD 在它存在之前定义 XML 文档。 CSV 有一个标题行。所有这些都只是语言语法的规范,出于某种原因,它们都没有真正做任何事情。

【讨论】:

  • 请引用导致您思考的文本:“您正在将读取和处理 ASN.1 的工具与规范混为一谈。”。我说:“我想知道 ANTLR 是否能够做与 ASN.1 相同的事情——独立于这些对象的序列化定义数据对象的结构”。 ANTLR是语法和工具,ASN.1是语法和工具。问题显然不是“语法可以处理数据”。对所提问题的简短回答是:“ANTLR(语法和工具)无法表达数据抽象”。
猜你喜欢
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
  • 2013-06-21
相关资源
最近更新 更多