A EBNF Definition for GraphQL

最近一直在忙着魔改 GraphQL 实现. 现有的 GraphQL 实现理论上无论是性能还是新特性跟进提升空间还有很多, 但是大部分实现都困于 GraphQL 本身的语法定义过于复杂或社区人手不足, 导致实现版本还停留在 GraphQL 的很早期的版本.

所以我开展了一个跟进 GraphQL 最新语法规范的项目, 目前还处于一个很初级的阶段. 而这个项目的第一步, 是需要重新梳理 GraphQL 的语法规则.

GraphQL 官方提供了一个详细的规范文档, 这个文档对于用来写 Lexer 和 Parser 足够了, 但为了方便理解, 我顺便根据这个文档整理了 GraphQL 语法的 EBNF 定义.

Preview:

/* SourceCharacter Expression */
SourceCharacter ::=  #x0009 | #x000A | #x000D | [#x0020-#xFFFF] /* /[\u0009\u000A\u000D\u0020-\uFFFF]/ */
/* Ignored Tokens Expression */
Ignored        ::= UnicodeBOM | WhiteSpace | LineTerminator | Comment | Comma
UnicodeBOM     ::= #xFEFF  /* Byte Order Mark (U+FEFF) */
WhiteSpace     ::= #x0009 | #x0020 /* ASCII: \t | Space, Horizontal Tab (U+0009), Space (U+0020) */
LineTerminator ::= #x000A | #x000D | #x000D#x000A   /* ASCII: \n | \r\n | \r, New Line (U+000A) | Carriage Return (U+000D) [Lookahead != New Line (U+000A)] | Carriage Return (U+000D)New Line (U+000A) */
Comment        ::= "#" CommentChar* LineTerminator
CommentChar    ::= SourceCharacter - LineTerminator
Comma          ::= ","
...

语法图:

railroad-diagram-sample

Github:

该项目旨在整理一份清晰的, 基于 W3C EBNF 规则的 EBNF 定义, 以及根据这个定义生成 GraphQL 语法图 (铁路图).

目前已经实现了 GraphQL 的最新标准 (June 2018), 未来会继续跟进最新的 Working Draft.

需要注意的是, 现有不同语言的 GraphQL 实现的语法规则可能都不尽相同, 有的实现了较新版本的规则, 有的版本则很旧. 如果需要使用 GraphQL 的新特性需要测试后再投入生产.

为什么不用 ISO-14977 定义的 EBNF 书写?

因为 ISO-14977 定义的 EBNF 有一些问题, 详情可以参考 dont-use-iso-14977-ebnf, W3C 定义的 EBNF 则不存在这些问题.