`

使用Scala Parser解析JSON

 
阅读更多

本文来自: http://fair-jm.iteye.com 转截请注明出处

 

最近几天看了些文章(Learn by Example: Scala Parser CombinatorsAn Introduction To Scala Parser Combinators )学习了scala中的Parser的一些使用 这边以一个解析JSON的例子来记录一些笔记

 

首先是一些连接符(翻译自第一篇文章):

  • | 选择连接符,当左边或右边的Parser成功时成功。
  • ~ 序列连接符,当左右的Parser都成功时成功
  • ~> 和~类似 不同的是左边的结果不会包含在最后的结果中
  • <~ 和~类似 右边的结果不会包含在最后的结果中
  • ^^ 转换连接符,当左边的操作成功时可以通过这个连接符操作结果
  • rep repeat的意思 重复

 

如果说看起来比较难懂的话 在使用之后就会觉得容易理解得多

我没有学过编译原理(选修课没选惭愧...听到别人说一星期两节课要上两章就退缩了...) 对一些专用术语不是很理解 这边的Parser使用更加像是使用正则表达式(这主要也有继承了RegexParser的因素在)

 

首先看JSON的组成 从ECMA-404的文档中可以看到:



 主要有 object array number string bool(true|false) null 这几个元素构成

 

为了编码方便 我让类继承自JavaTokenParsers:

class JsonParser extends JavaTokenParsers

 对以上一些元素进行了定义(和ECMA-404的规范有些许差别 其实很多地方需要重写正则表达式的...)

//来自JavaTokenParser的floatingPointNumber parser
  def jNum: Parser[Double] = floatingPointNumber ^^ (_.toDouble) 

//stringLiteral 也来自JavaTokenParser 这边解析出来的结果会是例如"string"的形式 我们需要把双引号给去掉
  def jStr: Parser[String] = stringLiteral ^^ (s => s.substring(1, s.length() - 1)) 

//正则表达式会被隐式转换为Parser 
  def jBool: Parser[Boolean] = "(true|false)".r ^^ (_.toBoolean)

  def jNull: Parser[Null] = "null".r ^^ (t => null)

 

接下去还差对object和array的定义

在ECMA-404中他们的定义如下:



 

 其中他们内的value是可以包括所有类型的(包括object和array)

可能有多个 这样需要用到rep连接符

 

具体的编码不是很困难 scala的模式匹配用起来比较舒服:

这边将JsonArray转化为List的形式 将JsonObject转换为Map的形式:

  def term = jsonArray | jsonObject | jNum | jBool | jNull | jStr
  def jsonArray: Parser[List[Any]] = "[" ~> rep(term <~ ",?".r) <~ "]" ^^ (l => l)

//String也会被隐式转化为Parser的形式
  def jsonObject: Parser[Map[String, Any]] = "{" ~> rep((ident ~ ":" ~ jNum |
    ident ~ ":" ~ jBool | ident ~ ":" ~ jNull | ident ~ ":" ~ jsonObject | ident ~ ":" ~ jsonArray | ident ~ ":" ~ jStr) <~ ",?".r) <~ "}" ^^ {
    os =>
      var map = Map[String, Any]()
      os.foreach(o =>
        o match {
          case k ~ ":" ~ v => map = map ++ Map(k -> v)
        })
      map

  }

 

 

最后来实验一下:



 虽然number的形式有点问题(我用了JavaTokenParser中的一个Parser) 但总体结果还是正确的 使用起来也是相当简单

 

对于解析JSON来说 用scala提供的Parser并不困难 本文并未对其中的原理有任何描述 可以看上面参考的第二篇文章 里面有比较详尽的分析 

 

希望对初学scala的Parser的人有所帮助^_^

 

  • 大小: 31.2 KB
  • 大小: 23.6 KB
  • 大小: 17.2 KB
  • 大小: 27.3 KB
0
0
分享到:
评论

相关推荐

    Scala解析Json字符串的实例详解

    本文将详细介绍如何使用`json-smart`库来解析JSON字符串。`json-smart`是一个轻量级的Java库,它提供了高效的JSON解析和生成功能,且在Scala中也能很好地工作。 首先,为了使用`json-smart`,我们需要将其添加到...

    scala-parser-combinators:Scala的基于简单组合器的解析。 以前是Scala标准库的一部分,现在是一个单独的社区维护模块

    例如,可以创建一个解析JSON的解析器,或者解析XML文档。通过这种方式,可以避免编写低级的词法分析和语法分析代码,而是专注于表达语言的语法规则。 总的来说,`scala-parser-combinators`是一个强大且灵活的库,...

    argonaut:scala中的纯功能JSON解析器和库

    **argonaut:Scala中的纯功能JSON解析器与库** 在Scala编程环境中,处理JSON数据是一项常见的任务,而`argonaut`就是为此设计的一个强大的库。它以纯函数式的方式提供了JSON解析、编码和操作的功能,这使得代码更...

    用于查询JSON对象的SQL微方言实现。纯粹用Scala编写。- mmalek06 / JsonSql

    1. **JSON解析**:如何在Scala中解析JSON数据,可能使用了诸如Play JSON、Circe、spray-json等流行的Scala JSON库。 2. **SQL方言**:设计和实现SQL的微型方言,以便处理JSON查询。这可能涉及到自定义的SQL语法扩展...

    PHP解析器:基于Scala的解析器,用于最新PHP版本

    选择Scala作为PHP解析器的基础,可能是因为其强大的类型系统、高效的并发处理能力以及对XML和JSON的良好支持,这些特性对于处理复杂的语法解析任务非常有利。 PHP解析器的实现通常涉及以下几个关键技术点: 1. **...

    shex-s:ShEx的Scala实现

    ShEx紧凑语法解析器是使用以下基于该的Antlr语法(以前的版本使用Scala Parser Combinators)实现的 JSON编码和解码使用此处定义的Json结构,并使用Circe实现 相容性测试 我们还通过了ShEx测试套件。 更多信息 ...

    Functional Programming in Scala

    第九章《Parser combinators》探讨了使用解析器组合器来构建复杂的解析逻辑。解析器组合器允许程序员以声明式的方式组合简单的解析规则,形成强大的解析引擎,适用于解析各种格式的数据,如JSON、XML等。 ### 函数...

    org.jresearch.commons.gwt.utils.shared-1.0.45.zip

    circe的核心组件包括解析器(Parser)、编码器(Encoder)和解码器(Decoder),这些组件允许开发者将JSON数据转换为Scala值,反之亦然。 circe的"core"模块包含了基本的JSON类型和操作,而其他模块如"circe-generic...

    FastParsers:快速解析器组合器

    快速解析器 FastParsers 是一个 Scala 解析器库,它使用宏将易于编写的解析器组合器转换为高效的递归下降回溯解析器。 生成的解析器比快 20 倍左右,即使它的接口保持不变。例子这是一个基本 JSON 解析器的示例 val ...

    jsonpath:RFC6901的实现并支持scala DSL

    String path parser和Scala DSL句法字符串路径解析器: 以下是受支持的运算符的列表: 操作员描述例子/ 路径分割/foo : 数组切片(像python一样) /-1:-3 (后3个元素) , 名称或索引的集合/foo,bar或/foo/1,-1,2 *...

    葱:Scala中的LL(1)解析器组合器

    :此示例展示了如何使用Scallion构建基本的JSON解析器。 :此示例显示了如何与解析器一起免费获得漂亮的打印机。 :此示例说明如何使用operators组合器轻松处理具有各种关联性和优先级的运算符。 :此示例展示了...

    limbn:Jawn用于解析jay-sawn(JSON)

    总览Jawn包含四个部分: 快速,通用的JSON解析器( jawn-parser ) 一个小的,有点贫血的AST( jawn-ast ) 解析到第三方AST的支持程序包一些有用的实用程序( jawn-util实用程序) 目前,Jawn在速度最快的Java JSON...

    atto:友好的小解析器

    atto相比于其他的Scala解析库,如parboiled或scala-parser-combinators,有以下特点: - **更高效的性能**: atto使用了优化的CPS(Continuation-Passing Style)转换,减少了堆栈消耗,提高了运行速度。 - **更简洁...

    ciris:Scala的功能配置

    Ciris是Scala编程语言中的一个强大且灵活的配置库,它专注于提供安全、类型安全以及易于使用的配置解决方案。在本文中,我们将深入探讨Ciris的核心概念、特性以及如何在实际项目中有效地利用它。 **一、Ciris的核心...

    JsonParserGenerator:(已放弃)我们有一个更好的方法来生成 JSON、protobuf、SQLite 数据库模式。 但我们没有时间开源

    它基本上与 ig-json-parser 做同样的事情。 但... 区别在于: 不要使用注释来生成解析器。 但使用 Scala 原始值,如: lazy val Tag = ObjectType ( " Tag " , Seq ( Field ( " value " , " value " , StringType )...

    escalima:用于scalaJavaScript解析器,基于esprima

    埃斯卡利马Escalima是的Scala包装器,用于将JavaScript解析为ast。 它可以在JVM以及ScalaJS中使用。 esprima返回的ast既可以作为json字符串接收,也可以作为整洁的scala类包装结构接收。文档化。例子 val parser = ...

    circe-circus:基于Circe的微型库

    `Json`对象是Circe中表示JSON数据的抽象类,包含了丰富的操作方法,如访问、修改、解析等。 **circe-circus的功能增强** 1. **自动生成解码器和编码器**: circe-circus提供了一种自动化的方式,能够根据Scala的...

    rdf4j-util-2.1.2.zip

    5. **Parser and Serializer**:解析和序列化RDF数据,支持各种格式如Turtle、N-Triples、JSON-LD等。 在版本2.1.2中,可能包含以下改进和更新: 1. **性能优化**:可能对查询处理速度、数据导入导出速度等方面进行...

    astexplorer:一种Web工具,用于探索由各种解析器生成的AST

    AST浏览器 将代码粘贴或拖放到编辑器中,并在上检查生成的AST。... 复制AST或将包含AST的文件到窗口中将解析AST并使用更新代码。 否则,文本编辑器的内容将替换为文件的内容(即,您可以拖放JS文件)。 在多个

    SparkSql技术

    SqlParser负责将SQL字符串解析成Abstract Syntax Tree (AST)。这个AST随后会被转换为LogicalPlan。 **3.3 Analyzer** Analyzer组件负责对逻辑计划进行语义分析,确保查询的有效性和一致性。它会检查逻辑计划中的表...

Global site tag (gtag.js) - Google Analytics