摘要:本文以华为图引擎使用的cypher查询语言为例,将查询语句的解析结果(语法树)在jupyterLab上可视化。

本文分享自华为云社区《使用Jupyter可视化查询语句的语法树--以图查询语言Cypher为例》,作者: 蜉蝣与海。

“语法解析”和“词法解析”是计算机理解查询语句的重要一环。而词法和语法的解析依赖于一定的文法规则,对这些文法规则生成的语法树进行可视化,可以降低查询语言的理解成本。本文以华为图引擎使用的cypher查询语言为例,将查询语句的解析结果(语法树)在jupyterLab上可视化。案例中使用的工具不仅可以可视化cypher语言的语法树结构,对其他antlr生成的抽象语法树同样适用。

查询语言是用于从数据库或信息系统中查询数据的计算机语言,使用查询语言可以很方便地在数据库中完成各类数据管理以及查询操作。在关系数据库中常用的查询语言是SQL,在图数据库管理系统中,常用的查询语言有Cypher、Gremlin、SPARQL等。

当数据管理系统收到一条查询语句时,会对这条查询语句进行一些理解和解释,最终会翻译为一系列可以执行的步骤来处理数据。其中“语法解析”和“词法解析”是计算机理解查询语句的第一步。而词法和语法的解析依赖于一定的文法规则,对这些文法规则生成的语法树进行可视化,可以学习查询语言的各个语法成分,加深对查询语言的了解。

图 1 一条查询语句的执行流程

通常词法&语法解析器可以由一些工具进行生成,例如常见的flex/bison(c/c++), yacc(c/c++), antlr(java)、javacc(java)、Parboiled(scala)等。这些工具往往以规则文件作为输入,输出一个语法解析器。本文的最终目标是:通过一个已生成的语法解析器解析某条查询语句,对解析到的语法成分进行可视化。

在查询语言的选择上,考虑到华为图引擎GES对接了Cypher、Gremlin两大主流图查询语言,其中Cypher查询语言有公开的文法规则,所以以Cypher为例; 在生成工具方面,由于只有少数工具可以生成python的解析代码,这里使用antlr4作为语法解析器生成工具。

环境准备

注:本文对应的notebook链接为:https://developer.huaweicloud.com/develop/aigallery/notebook/detail?id=9ea7f844-2a05-49d0-b117-1260f65ef87d,相关代码可以直接在notebook上运行。

首先从OpenCypher官网下载cypher的文法规则,从Antlr的官网下载antlr工具包。

wget https://s3.amazonaws.com/artifacts.opencypher.org/M18/Cypher.g4
wget https://github.com/antlr/website-antlr4/blob/gh-pages/download/antlr-4.8-complete.jar
pip install antlr4-python3-runtime==4.8

这里简单介绍一下语法规则,一条语法规则定义了语句中的各个部分如何被解释,下面展示了Match子句的解释规则:一个Match子句,必须包含一个单词MATCH和一个Pattern(MATCH SP? oC_Pattern),MATCH和Pattern间可能有空格(SP),MATCH和Pattern的前部可能有一个OPTIONAL单词(( OPTIONAL SP )?),后部可能有一个Where语法成分(( SP? oC_Where )?)。关于antlr的细节,可以查看华为云相关博文介绍:Antlr4简明使用教程,推荐一款优秀的语法解析工具—Antlr4

oC_Match
: ( OPTIONAL SP )? MATCH SP? oC_Pattern ( SP? oC_Where )? ;

下面代码可以生成cypher查询语言python版本的语法解析器。

java -cp antlr-4.8-complete.jar org.antlr.v4.Tool -visitor -package cypher -Dlanguage=Python3 Cypher.g4

如果你正在使用notebook,且notebook环境中没有java,也可以通过下列代码下载已经生成好的语法解析器。

import moxing as mox
mox.file.copy('obs://obs-aigallery-zc/GES/ges4jupyter/beta/cypher-generated-parser.zip', 'cypher-generated-parser.zip')
!unzip cypher-generated-parser.zip

语法树生成 & 可视化

对文法规则的可视化,网上已有诸多案例,例如OpenCypher官网提供了Cypher文法的可视化结果,可以进入查看。另外网上也有一部分网站,可以输入文法规则,返回可视化结果。例如在网站https://www.bottlecaps.de/convert/上, 可以输入包括antlr、bison、javacc在内的诸多文法规则,而后生成文法规则的可视化图表。例如将Cypher.g4文法文件输入这个网站,可以获得的文法规则截选如下。

这里给出了oC_Statement、oC_Query、oC_RegularQuery三条规则的解释,例如对oC_Statement而言,其可以由一个oC_Command或者一个oC_Query构成;而一个oC_RegularQuery,则可以由一个oC_SingleQuery,以及0到多个oC_Union构成。这些文法规则的可视化给出了文法的定义,却未提供可视化某条语句解析结果的能力。可视化语句的解析结果目前只能依赖antlr的插件,但是antlr未提供jupyter侧的可视化工具。下面本文试图在jupyter侧可视化一条查询语句的语法解析路径。

首先我们写一个解析查询语句的函数,用来生成语法解析器的解析结果。下列代码是一个经典的antlr解析语句的流程,通过构造词法解析器(lexer)、单词流(stream)、语法解析器(parser)来完成整个初始化过程,最终parser只需要调用文法中的规则名,即可使用规则来生成语法树结构。

from CypherLexer import CypherLexer
from CypherParser import CypherParser
from antlr4 import *
def get_ast(statement):
reader = InputStream(statement)
lexer = CypherLexer(reader)
stream = CommonTokenStream(lexer)
parser = CypherParser(stream)
return parser.oC_Statement()

而后输入一条查询语句,并调用ast函数,代码会返回解析后的对象。

ast_tree = get_ast('match (n) return n limit 10')

在获得语法树之后,可以从语法树中提取关键语法成分,而后进行可视化。相关代码已经封装为了工具包,可以直接下载使用。其中可视化工具使用的是vis.js。

import moxing as mox
mox.file.copy('obs://obs-aigallery-zc/GES/ges4jupyter/beta/viz_ast_parser.py', 'viz_ast_parser.py')
mox.file.copy('obs://obs-aigallery-zc/GES/ges4jupyter/beta/viz_ast_parser.html', 'viz_ast_parser.html')
from viz_ast_parser import *
def beautify_name(name):
return name.replace('OC_', '').replace('Context', '').replace('Impl', '')
vizAstParser = VizAstParser(beautify_name)
vizAstParser.vis_ast(get_ast('match (n) return n limit 10'))

 

通过可视化可以看到:即使是一条简单的语句也有丰富的语法结构,这样的层次结构,计算机也更容易理解和解析。

备注:

1.工具中的相关代码不仅可以用来可视化cypher语言的语法成分, 其他可以用antlr生成python解析器的语言,该工具也可以提供JupyterLab上的可视化支持。

2. 本文对应的notebook链接为:https://developer.huaweicloud.com/develop/aigallery/notebook/detail?id=9ea7f844-2a05-49d0-b117-1260f65ef87d,相关代码可以直接在notebook上运行。

点击关注,第一时间了解华为云新鲜技术~

教你使用Jupyter可视化查询语句的语法树的更多相关文章

  1. 可视化查询(sp_helptext)——快速查询包含指定字符串的存储过程(附源码)

    前言 在开发中,随着业务逻辑的调整,修改存储过程是必不可免的. 那怎么定位到需要修改的存储过程呢?一个一个的点开查询?存储过程少的话还行,一旦存储过程过多,这样是很浪费时间的,一个不注意还会遗漏掉. ...

  2. ActiveReports 9 新功能:可视化查询设计器(VQD)介绍

    在最新发布的ActiveReports 9报表控件中添加了多项新功能,以帮助你在更短的时间里创建外观绚丽.功能强大的报表系统,本文将重点介绍可视化数据查询设计器,无需手动编写任何SQL语句,主要内容如 ...

  3. MYSQL——解题查询语句答题思路,再难的查询都不怕!

    select查询语句,作为测试人员,使用此语句是家常便饭,是必须掌握的部分,由开始学习mysql到网上搜索试题做,开始做题一塌糊涂,拿到题目就晕,无从下手,现在慢慢总结了一套自己做题的方式,很开森,嘿 ...

  4. Neo4j:图数据库GraphDB(一)入门和基本查询语句

    图数据库的代表:Neo4j 官网:  http://neo4j.com/ 引言:为什么使用图数据库 在很多新型项目中,应用图数据库已经是势在必行的趋势了,因为图数据库可以很好的表示各种节点与关系的概念 ...

  5. mysql命令查询语句&MTdata

    1.单表查询 select * from student; 采用*效率低,不推荐,多用列名 一.单表查询的语法: SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY ...

  6. mysql-数据库查询语句汇总

    目录 数据库查询语句 ***** 添加数据补充: 所有的select 关键字 where 条件 distinct 去除重复记录 指定字段 取别名 group by having order limit ...

  7. MySQL 表查询语句练习题

    MySQL 表查询语句练习题: 一.  设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表 ...

  8. Java开源协同办公项目:数据中心,自定义查询语句使用教程

    O2OA提供的数据管理中心,可以让用户通过配置的形式完成对数据的汇总,统计和数据分组展现,查询和搜索数据形成列表数据展现.也支持用户配置独立的数据表来适应特殊的业务的数据存储需求.本文主要介绍如何在O ...

  9. mysql常用的查询语句

    好记性不如烂笔头! 查询表中全部信息: select * from 表名 查询表中指定列的信息: select 列1,列2 from 表名 数据去重: select distinct 列... fro ...

  10. MySQL(十四)分析查询语句Explain 七千字总结

    分析查询语句:EXPLAIN 1概述 ​ 定位了查询慢的SQL之后,就可以使用EXPLAIN或者DESCRIBE工具做针对性的分析查询.两者使用方法相同,并且分析结果也是相同的. ​ MySQL中有专 ...

随机推荐

  1. dicker 常用命令(简洁版)

  2. Asp.Net Core webapi+net6 使用资源筛选器(过滤器) 做缓存

    写一个特性类,用来做标记 [AttributeUsage(AttributeTargets.Method)] //只对方法有效 public class ResourceFilterAttribute ...

  3. 题解 UVA10299

    前言 数学符号约定: \(a\).\(b\).\(m\).\(n\).\(x\).\(y\):任意一个正整数. \(p\):任意一个质数. \(d\):一个数的任意一个因子. \(\varphi(n) ...

  4. BABYRE

    一道SMC,第一次做 主函数的伪代码,judge函数是关键函数,不过啥都没有 发现 judge 方法是判断的主要逻辑,在第 15 行时调用判断. 但是静态分析时不能生成 judge 的伪代码. 原因是 ...

  5. HDL刷题:Edgedetect

    原题链接 一道想了好久的题目,在这种并行执行的程序里怎么才能保存前一个状态,看了题解后才发觉,非阻塞赋值啊,代码如下: module top_module ( input clk, input [7: ...

  6. (Good topic)字符串的最大公因子 (3.21leetcode每日打卡)

      对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 "T 能除尽 S". 返回最长字符串 X,要求满足 X 能除尽 s ...

  7. Ingress & Ingress Controller & API Gateway

    Ingress Ingress 内部服务如何暴露给集群外部访问 使用NodePort类型的service 将k8s集群中的服务暴露给集群外部访问,最简单的方式就是使用NodePort,类似在docke ...

  8. 深入浅出 PLT/GOT Hook与原理实践

    动态链接 计算机程序链接时分两种形式:静态链接和动态链接. 静态链接在链接时将所有目标文件中的代码.数据等Section都组装到可执行文件当中,并将代码中使用到的外部符号(函数.变量)都进行了重定位. ...

  9. GitHub Desktop安装与使用教程

    一.安装 1.下载 下载地址 2.安装 下载之后GitHub Desktop是没有安装步骤的,而是开始安装之后,稍等片刻就安装成功了. 然后登陆个人GitHub账号就可以进行一下操作了. 二.新建仓库 ...

  10. free内存参数介绍

    第一部分Mem行: total 内存总数: 15.7G used 已经使用的内存数: 15.6G free 空闲的内存数: 93M shared 当前已经废弃不用,总是0 buffers Buffer ...