golang 解析json_创建Go Json解析器:包括电池

golang 解析json

这篇文章的灵感来自一个正在进行的项目。 我正在构建需要比较两个Json对象的服务。 问题是我需要能够替换键过滤出路径并将比较功能应用于特定节点。

显然,标准库比较功能(例如reflect.DeepEqual()将无法工作。 😧

解决方案是在Json对象的基础上构建AST抽象语法树 )。 树中的每个Node都表示一个stringintegerarrayobject

通过这样做,我将具有灵活性,可以更轻松地将算法应用于数据。

为了构建它,我们将从Lexer开始以生成令牌 。 然后转到解析器 ,它将获取令牌并将其与Json语法匹配。 最后,我们将添加AST挂钩以生成树。

最终目录结构:

.
main.go
/lexer
lexer.go
lexer_test.go
/token
token.go
/parser
parser.go
/ast
ast.go

如果要查看并运行最终结果:

cd $GOPATH/src/github.com/Lebonesco
git clone https://github.com/Lebonesco/json_parser.git
go run main.go ./examples/test.json

Lexer

词法分析器的工作是获取json数据并将其转换为tokens流。 这些令牌包括: INVALIDEOFCOMMACOLONLBRACERBRACELBRACKETRBRACKETSTRINGINTEGER

注意:词法分析器也称为扫描仪。

让我们从👇开始

cd $GOPATH/src/github.com/Lebonesco/json_parser
mkdir token
cd token
touch token.go

您可以自由定义tokens 。 您添加到token的数据越多,调试起来就越容易。

注意:我们将使用rune数组[]rune来存储token文字,以允许使用Unicode字符。

接下来,让我们进入我们的lexer 👍

mkdir lexer
cd lexer
touch lexer.go
touch lexer_test.go

lexer将跟踪我们在输入中的位置,并向前看必要的字符。

在功能方面,它将需要能够创建一个新token并在下一个token之前达到峰值。

注意:此扫描仪不支持布尔值,但可以轻松添加它们。

Lexer测试

在这里,我们将接收一个字符串,并确保它输出正确的令牌流。

要运行测试:

go test -v
=== RUN TestLexer
--- PASS: TestLexer (0.00s)
PASS
ok github.com/Lebonesco/json_parser/lexer 0.433s

您现在拥有一个工作的词法分析器了

解析器

这是我们获取流并将其与json语法匹配以生成AST节点的部分。

如果我们要用正则表达式定义json ,它将由下面定义的语法表示

JSON : value
Value : Object | Array | String | Integer | Bool | Null
Array : '[' [Value] {',' Value}']'
Object : '{' [Property] {',' Property} '}'
Property : String ':' Value

在以上语法中, [expression]表示表达式出现一次或多次,而{expression}表示{expression}出现零次或多次。

如果您提供正则表达式,则有类似gocc类的工具将生成词法分析器和/或解析器。 如果您要处理更复杂的事情,这是推荐的方法。

但是由于Json非常简单,我们将手工完成! 👐

让我们构造代表最终结果的AST nodes

mkdir ast
cd ast
touch ast.go

nodes相当简单。 如果像我的用例一样,我们更关心错误处理和跟踪node哈希,则可以存储更多数据。

注意:因为Go使用composition而不是inheritance我们需要将TokenLiteral()方法应用于每个node类型,以便将每个类型解释为Json节点。

现在进入解析器!

让我们将它们放在一起并编写驱动程序main.go

注意: json.MarshalIndent()可以很好地替代json.Marshal()以获得更漂亮的json输出。

跑步:

go run main.go ./exampes/test.json

全部完成😄

现在我们可以生成AST,现在可以轻松地向每个节点添加滚动哈希并执行所有其他自定义操作,例如:

  • 替代节点值
  • 滤除节点
  • 将特殊比较功能应用于节点

我将那些扩展留给读者。 随意在评论中删除指向您工作的链接。 我很想看看你的想法。 👍

感谢您抽出宝贵的时间阅读本文。

如果您觉得它有用或有趣,请告诉我me。

翻译自: https://hackernoon.com/create-a-go-json-parser-batteries-included-9d02d09fe508

golang 解析json

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值