parser.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package parser
  10. import (
  11. "fmt"
  12. "devt.de/krotik/common/errorutil"
  13. )
  14. // Parser Rules
  15. // ============
  16. /*
  17. Maps of AST nodes corresponding to lexer tokens
  18. */
  19. var astNodeMapValues map[string]*ASTNode
  20. var astNodeMapTokens map[LexTokenID]*ASTNode
  21. var astNodeMapIgnoredValues map[string]*ASTNode
  22. func init() {
  23. astNodeMapValues = map[string]*ASTNode{
  24. "query": {NodeOperationDefinition, nil, nil, nil, 0, ndOperationDefinition, nil},
  25. "mutation": {NodeOperationDefinition, nil, nil, nil, 0, ndOperationDefinition, nil},
  26. "subscription": {NodeOperationDefinition, nil, nil, nil, 0, ndOperationDefinition, nil},
  27. "fragment": {NodeFragmentDefinition, nil, nil, nil, 0, ndFragmentDefinition, nil},
  28. "{": {NodeSelectionSet, nil, nil, nil, 0, ndSelectionSet, nil},
  29. "(": {NodeArguments, nil, nil, nil, 0, ndArgsOrVarDef, nil},
  30. "@": {NodeDirectives, nil, nil, nil, 0, ndDirectives, nil},
  31. "$": {NodeVariable, nil, nil, nil, 0, ndVariable, nil},
  32. "...": {NodeFragmentSpread, nil, nil, nil, 0, ndFragmentSpread, nil},
  33. "[": {NodeListValue, nil, nil, nil, 0, ndListValue, nil},
  34. // Tokens which are not part of the AST (can be retrieved by next but not be inserted by run)
  35. "}": {"", nil, nil, nil, 0, nil, nil},
  36. ":": {"", nil, nil, nil, 0, nil, nil},
  37. ")": {"", nil, nil, nil, 0, nil, nil},
  38. "=": {"", nil, nil, nil, 0, nil, nil},
  39. "]": {"", nil, nil, nil, 0, nil, nil},
  40. }
  41. astNodeMapTokens = map[LexTokenID]*ASTNode{
  42. TokenName: {NodeName, nil, nil, nil, 0, ndTerm, nil},
  43. TokenIntValue: {NodeValue, nil, nil, nil, 0, ndTerm, nil},
  44. TokenStringValue: {NodeValue, nil, nil, nil, 0, ndTerm, nil},
  45. TokenFloatValue: {NodeValue, nil, nil, nil, 0, ndTerm, nil},
  46. TokenEOF: {NodeEOF, nil, nil, nil, 0, ndTerm, nil},
  47. }
  48. }
  49. // Parser
  50. // ======
  51. /*
  52. Parser data structure
  53. */
  54. type parser struct {
  55. name string // Name to identify the input
  56. node *ASTNode // Current ast node
  57. tokens chan LexToken // Channel which contains lex tokens
  58. rp RuntimeProvider // Runtime provider which creates runtime components
  59. // Flags
  60. isVarDef bool // The next Arguments block is parsed as a VariableDefinition
  61. isValue bool // The next expression is parsed as a value
  62. }
  63. /*
  64. Parse parses a given input string and returns an AST.
  65. */
  66. func Parse(name string, input string) (*ASTNode, error) {
  67. return ParseWithRuntime(name, input, nil)
  68. }
  69. /*
  70. ParseWithRuntime parses a given input string and returns an AST decorated with
  71. runtime components.
  72. */
  73. func ParseWithRuntime(name string, input string, rp RuntimeProvider) (*ASTNode, error) {
  74. p := &parser{name, nil, Lex(name, input), rp, false, false}
  75. node, err := p.next()
  76. if err != nil {
  77. return nil, err
  78. }
  79. p.node = node
  80. doc := newAstNode(NodeDocument, p, node.Token)
  81. for err == nil && p.node.Name != NodeEOF {
  82. if node, err = p.run(0); err == nil {
  83. if node != nil && node.Name == NodeSelectionSet {
  84. // Handle query shorthand
  85. if len(doc.Children) == 0 {
  86. ed := newAstNode(NodeExecutableDefinition, p, node.Token)
  87. doc.Children = append(doc.Children, ed)
  88. od := newAstNode(NodeOperationDefinition, p, node.Token)
  89. ed.Children = append(ed.Children, od)
  90. od.Children = append(od.Children, node)
  91. } else {
  92. return nil, p.newParserError(ErrMultipleShorthand,
  93. node.Token.String(), *node.Token)
  94. }
  95. } else {
  96. ed := newAstNode(NodeExecutableDefinition, p, node.Token)
  97. doc.Children = append(doc.Children, ed)
  98. ed.Children = append(ed.Children, node)
  99. }
  100. }
  101. }
  102. if err == nil {
  103. return doc, nil
  104. }
  105. return nil, err
  106. }
  107. /*
  108. run is the main parser function.
  109. */
  110. func (p *parser) run(rightBinding int) (*ASTNode, error) {
  111. var err error
  112. var left *ASTNode
  113. n := p.node
  114. // Get the next ASTNode
  115. if p.node, err = p.next(); err == nil {
  116. // All nodes have a null denotation
  117. if n.nullDenotation == nil {
  118. return nil, p.newParserError(ErrImpossibleNullDenotation, p.node.Token.Val, *p.node.Token)
  119. }
  120. left, err = n.nullDenotation(p, n)
  121. }
  122. if err != nil {
  123. return nil, err
  124. }
  125. // At this point we would normally collect left denotations but this
  126. // parser has only null denotations
  127. errorutil.AssertTrue(rightBinding == p.node.binding, "Unexpected right binding")
  128. return left, nil
  129. }
  130. /*
  131. next retrieves the next lexer token and return it as ASTNode.
  132. */
  133. func (p *parser) next() (*ASTNode, error) {
  134. token, more := <-p.tokens
  135. if !more {
  136. // Unexpected end of input - the associated token is an empty error token
  137. return nil, p.newParserError(ErrUnexpectedEnd, "", token)
  138. } else if token.ID == TokenError {
  139. // There was a lexer error wrap it in a parser error
  140. return nil, p.newParserError(ErrLexicalError, token.Val, token)
  141. } else if node, ok := astNodeMapValues[token.Val]; ok &&
  142. (!p.isValue || token.ID == TokenPunctuator) && token.ID != TokenStringValue {
  143. // Parse complex expressions unless we parse a value (then just deal with punctuators)
  144. return node.instance(p, &token), nil
  145. } else if node, ok := astNodeMapTokens[token.ID]; ok {
  146. return node.instance(p, &token), nil
  147. }
  148. return nil, p.newParserError(ErrUnknownToken, fmt.Sprintf("id:%v (%v)", token.ID, token), token)
  149. }
  150. // Null denotation functions
  151. // =========================
  152. /*
  153. ndTerm is used for terminals.
  154. */
  155. func ndTerm(p *parser, self *ASTNode) (*ASTNode, error) {
  156. return self, nil
  157. }
  158. /*
  159. ndVariable is used for variables. (@spec 2.10)
  160. */
  161. func ndVariable(p *parser, self *ASTNode) (*ASTNode, error) {
  162. var err error
  163. if p.node.Token.ID == TokenName {
  164. // Append the query name and move on
  165. self.Token = p.node.Token
  166. p.node, err = p.next()
  167. }
  168. return self, err
  169. }
  170. /*
  171. ndListValue parses a list value. (@spec 2.9.7)
  172. */
  173. func ndListValue(p *parser, self *ASTNode) (*ASTNode, error) {
  174. var current *ASTNode
  175. var err error
  176. for p.node.Token.ID != TokenEOF && p.node.Token.Val != "]" {
  177. // Parse list values
  178. if current, err = parseValue(p); err == nil {
  179. self.Children = append(self.Children, current)
  180. } else {
  181. return nil, err
  182. }
  183. }
  184. return self, skipToken(p, "]")
  185. }
  186. /*
  187. ndInputObject parses an input object literal. (@spec 2.9.8)
  188. */
  189. func ndInputObject(p *parser, self *ASTNode) (*ASTNode, error) {
  190. var current *ASTNode
  191. var err error
  192. changeAstNode(self, NodeObjectValue, p)
  193. for p.node.Token.ID != TokenEOF && p.node.Token.Val != "}" {
  194. if current, err = p.run(0); err == nil {
  195. if current.Name != NodeName {
  196. err = p.newParserError(ErrNameExpected,
  197. current.Token.String(), *current.Token)
  198. } else {
  199. of := newAstNode(NodeObjectField, p, current.Token)
  200. self.Children = append(self.Children, of)
  201. if err = skipToken(p, ":"); err == nil {
  202. // Parse object value
  203. if current, err = parseValue(p); err == nil {
  204. of.Children = append(of.Children, current)
  205. }
  206. }
  207. }
  208. }
  209. if err != nil {
  210. return nil, err
  211. }
  212. }
  213. return self, skipToken(p, "}")
  214. }
  215. /*
  216. ndFragmentSpread is used for fragment spreads and inline fragments.
  217. (@spec 2.8, 2.8.2)
  218. */
  219. func ndFragmentSpread(p *parser, self *ASTNode) (*ASTNode, error) {
  220. var current, expectedNameNode *ASTNode
  221. var err error
  222. if p.node.Token.Val == "on" {
  223. // We might have an inline fragment
  224. onToken := p.node.Token
  225. p.node, err = p.next()
  226. if err == nil && p.node.Name == NodeName {
  227. // Append the fragment name
  228. changeAstNode(p.node, NodeTypeCondition, p)
  229. self.Children = append(self.Children, p.node)
  230. p.node, err = p.next()
  231. } else {
  232. self.Token = onToken
  233. }
  234. } else if p.node.Token.ID == TokenName {
  235. // Append the query name and move on
  236. self.Token = p.node.Token
  237. p.node, err = p.next()
  238. } else {
  239. expectedNameNode = p.node
  240. }
  241. if err == nil && p.node.Token.Val == "@" {
  242. // Parse directives
  243. if current, err = p.run(0); err == nil {
  244. self.Children = append(self.Children, current)
  245. }
  246. }
  247. if err == nil && p.node.Token.Val == "{" {
  248. // Parse selection set
  249. if current, err = p.run(0); err == nil {
  250. self.Children = append(self.Children, current)
  251. // If there is a selection set we must have an inline fragment
  252. changeAstNode(self, NodeInlineFragment, p)
  253. }
  254. } else if err == nil && expectedNameNode != nil {
  255. // Using the fragment spread operatior without specifying a name nor
  256. // a selection set is an error
  257. err = p.newParserError(ErrNameExpected,
  258. expectedNameNode.Token.String(), *expectedNameNode.Token)
  259. }
  260. return self, err
  261. }
  262. /*
  263. ndOperationDefinition parses an operation definition. Each operation is
  264. represented by an optional operation name and a selection set. (@spec 2.3)
  265. */
  266. func ndOperationDefinition(p *parser, self *ASTNode) (*ASTNode, error) {
  267. var err error
  268. var current = p.node
  269. ot := newAstNode(NodeOperationType, p, self.Token)
  270. self.Children = append(self.Children, ot)
  271. if p.node.Token.ID == TokenName {
  272. // Append the query name and move on
  273. self.Children = append(self.Children, p.node)
  274. p.node, err = p.next()
  275. }
  276. if err == nil && p.node.Token.Val == "(" {
  277. // Parse variable definition
  278. p.isVarDef = true
  279. if current, err = p.run(0); err == nil {
  280. self.Children = append(self.Children, current)
  281. }
  282. p.isVarDef = false
  283. }
  284. if err == nil && p.node.Token.Val == "@" {
  285. // Parse directive
  286. if current, err = p.run(0); err == nil {
  287. self.Children = append(self.Children, current)
  288. }
  289. }
  290. if err == nil && p.node.Token.Val == "{" {
  291. // Parse selection set
  292. if current, err = p.run(0); err == nil {
  293. self.Children = append(self.Children, current)
  294. }
  295. } else if err == nil {
  296. // Selection Set is mandatory
  297. err = p.newParserError(ErrSelectionSetExpected,
  298. current.Token.String(), *current.Token)
  299. }
  300. return self, err
  301. }
  302. /*
  303. ndFragmentDefinition parses a fragment definition. Each fragment is
  304. represented by an optional fragment name, a type condition and a selection set.
  305. (@spec 2.8)
  306. */
  307. func ndFragmentDefinition(p *parser, self *ASTNode) (*ASTNode, error) {
  308. var err error
  309. var current = p.node
  310. if p.node.Token.ID == TokenName {
  311. // Append the fragment name and move on
  312. changeAstNode(p.node, NodeFragmentName, p)
  313. self.Children = append(self.Children, p.node)
  314. p.node, err = p.next()
  315. } else {
  316. err = p.newParserError(ErrNameExpected,
  317. p.node.Token.String(), *p.node.Token)
  318. }
  319. if err == nil {
  320. if p.node.Token.Val != "on" {
  321. // Type conditions must start with on
  322. err = p.newParserError(ErrOnExpected,
  323. p.node.Token.String(), *p.node.Token)
  324. } else {
  325. p.node, err = p.next()
  326. if p.node.Token.ID == TokenName {
  327. // Append the fragment name
  328. changeAstNode(p.node, NodeTypeCondition, p)
  329. self.Children = append(self.Children, p.node)
  330. p.node, err = p.next()
  331. } else {
  332. err = p.newParserError(ErrNameExpected,
  333. p.node.Token.String(), *p.node.Token)
  334. }
  335. }
  336. }
  337. if err == nil && p.node.Token.Val == "@" {
  338. // Parse directive
  339. if current, err = p.run(0); err == nil {
  340. self.Children = append(self.Children, current)
  341. }
  342. }
  343. if err == nil && p.node.Token.Val == "{" {
  344. // Parse selection set
  345. if current, err = p.run(0); err == nil {
  346. self.Children = append(self.Children, current)
  347. }
  348. } else if err == nil {
  349. // Selection Set is mandatory
  350. err = p.newParserError(ErrSelectionSetExpected,
  351. p.node.Token.String(), *p.node.Token)
  352. }
  353. return self, err
  354. }
  355. /*
  356. ndSelectionSet parses a selection set. An operation selects the set of
  357. information it needs. (@spec 2.4)
  358. */
  359. func ndSelectionSet(p *parser, self *ASTNode) (*ASTNode, error) {
  360. var current *ASTNode
  361. var err error
  362. // Special case if we are parsing an input object literal (@spec 2.9.8)
  363. if p.isValue {
  364. return ndInputObject(p, self)
  365. }
  366. for p.node.Token.ID != TokenEOF && p.node.Token.Val != "}" {
  367. if p.node.Token.Val == "..." {
  368. // Add a simple fragment spread
  369. if current, err = p.run(0); err == nil {
  370. self.Children = append(self.Children, current)
  371. }
  372. } else {
  373. err = acceptFieldExpression(p, self)
  374. }
  375. if err != nil {
  376. return nil, err
  377. }
  378. }
  379. return self, skipToken(p, "}")
  380. }
  381. /*
  382. acceptFieldExpression parses a field expression. (@spec 2.5, 2.6, 2.7)
  383. */
  384. func acceptFieldExpression(p *parser, self *ASTNode) error {
  385. var err error
  386. // Field node gets the first token in the field expression
  387. fe := newAstNode(NodeField, p, p.node.Token)
  388. self.Children = append(self.Children, fe)
  389. current := p.node
  390. if p.node, err = p.next(); err == nil && p.node.Name != NodeEOF {
  391. if p.node.Token.Val == ":" {
  392. // Last node was an Alias not a name
  393. changeAstNode(current, NodeAlias, p)
  394. // Append Alias to Field children and move on
  395. fe.Children = append(fe.Children, current)
  396. if p.node, err = p.next(); err == nil && p.node.Name != NodeEOF {
  397. current = p.node
  398. p.node, err = p.next()
  399. }
  400. }
  401. if err == nil && p.node.Name != NodeEOF {
  402. // Next node must be a Name
  403. if current.Name == NodeName {
  404. // Append Name to Field children and move on
  405. fe.Children = append(fe.Children, current)
  406. } else {
  407. err = p.newParserError(ErrNameExpected,
  408. current.Token.String(), *current.Token)
  409. }
  410. if err == nil && p.node.Token.Val == "(" {
  411. // Parse arguments
  412. if current, err = p.run(0); err == nil {
  413. fe.Children = append(fe.Children, current)
  414. }
  415. }
  416. if err == nil && p.node.Token.Val == "@" {
  417. // Parse directives
  418. if current, err = p.run(0); err == nil {
  419. fe.Children = append(fe.Children, current)
  420. }
  421. }
  422. if err == nil && p.node.Token.Val == "{" {
  423. // Parse nested selection set
  424. if current, err = p.run(0); err == nil {
  425. fe.Children = append(fe.Children, current)
  426. }
  427. }
  428. }
  429. }
  430. return err
  431. }
  432. /*
  433. ndArgsOrVarDef parses an argument or variable definition expression. (@spec 2.6, 2.10)
  434. */
  435. func ndArgsOrVarDef(p *parser, self *ASTNode) (*ASTNode, error) {
  436. var err error
  437. var args, arg, current *ASTNode
  438. // Create a list token
  439. if p.isVarDef {
  440. args = newAstNode(NodeVariableDefinitions, p, p.node.Token)
  441. } else {
  442. args = newAstNode(NodeArguments, p, p.node.Token)
  443. }
  444. for err == nil && p.node.Token.ID != TokenEOF && p.node.Token.Val != ")" {
  445. if p.isVarDef {
  446. arg = newAstNode(NodeVariableDefinition, p, p.node.Token)
  447. } else {
  448. arg = newAstNode(NodeArgument, p, p.node.Token)
  449. }
  450. args.Children = append(args.Children, arg)
  451. if current, err = p.run(0); err == nil {
  452. if !p.isVarDef && current.Name != NodeName {
  453. err = p.newParserError(ErrNameExpected,
  454. current.Token.String(), *current.Token)
  455. } else if p.isVarDef && current.Name != NodeVariable {
  456. err = p.newParserError(ErrVariableExpected,
  457. current.Token.String(), *current.Token)
  458. } else {
  459. // Add name
  460. arg.Children = append(arg.Children, current)
  461. if err = skipToken(p, ":"); err == nil {
  462. // Add value
  463. if p.isVarDef {
  464. if current, err = p.run(0); err == nil {
  465. changeAstNode(current, NodeType, p)
  466. arg.Children = append(arg.Children, current)
  467. }
  468. } else {
  469. if current, err = parseValue(p); err == nil {
  470. arg.Children = append(arg.Children, current)
  471. }
  472. }
  473. if err == nil && p.isVarDef && p.node.Token.Val == "=" {
  474. skipToken(p, "=")
  475. // Parse default value
  476. if current, err = parseValue(p); err == nil {
  477. changeAstNode(current, NodeDefaultValue, p)
  478. arg.Children = append(arg.Children, current)
  479. }
  480. }
  481. }
  482. }
  483. }
  484. }
  485. // Must have a closing bracket
  486. if err == nil {
  487. return args, skipToken(p, ")")
  488. }
  489. return nil, err
  490. }
  491. /*
  492. parseValue parses a value and returns the result. (@spec 2.9)
  493. */
  494. func parseValue(p *parser) (*ASTNode, error) {
  495. p.isValue = true
  496. current, err := p.run(0)
  497. p.isValue = false
  498. if err == nil {
  499. if current.Token.Val == "true" ||
  500. current.Token.Val == "false" ||
  501. current.Token.Val == "null" ||
  502. current.Token.ID == TokenIntValue ||
  503. current.Token.ID == TokenFloatValue ||
  504. current.Token.ID == TokenStringValue {
  505. // Simple constant values
  506. changeAstNode(current, NodeValue, p)
  507. } else if current.Name == NodeName {
  508. // Enum values
  509. changeAstNode(current, NodeEnumValue, p)
  510. } else {
  511. // Everything else must be a variable or a complex data type
  512. errorutil.AssertTrue(current.Name == NodeVariable ||
  513. current.Name == NodeListValue ||
  514. current.Name == NodeObjectValue, fmt.Sprint("Unexpected value node:", current))
  515. }
  516. if err == nil {
  517. return current, err
  518. }
  519. }
  520. return nil, err
  521. }
  522. /*
  523. ndDirectives parses a directive expression. (@spec 2.12)
  524. */
  525. func ndDirectives(p *parser, self *ASTNode) (*ASTNode, error) {
  526. var err error
  527. var current = p.node
  528. dir := newAstNode(NodeDirective, p, p.node.Token)
  529. if err = acceptChild(p, dir, TokenName); err == nil {
  530. if current, err = p.run(0); err == nil {
  531. dir.Children = append(dir.Children, current)
  532. self.Children = append(self.Children, dir)
  533. if p.node.Token.Val == "@" {
  534. if p.node, err = p.next(); err == nil {
  535. return ndDirectives(p, self)
  536. }
  537. }
  538. }
  539. }
  540. return self, err
  541. }
  542. // Helper functions
  543. // ================
  544. /*
  545. skipToken skips over a token if it has one of the given valid values.
  546. */
  547. func skipToken(p *parser, validValues ...string) error {
  548. var err error
  549. canSkip := func(val string) bool {
  550. for _, i := range validValues {
  551. if i == val {
  552. return true
  553. }
  554. }
  555. return false
  556. }
  557. if !canSkip(p.node.Token.Val) {
  558. if p.node.Token.ID == TokenEOF {
  559. return p.newParserError(ErrUnexpectedEnd, "", *p.node.Token)
  560. }
  561. return p.newParserError(ErrUnexpectedToken, p.node.Token.Val, *p.node.Token)
  562. }
  563. // This should never return an error unless we skip over EOF or complex tokens
  564. // like values
  565. p.node, err = p.next()
  566. return err
  567. }
  568. /*
  569. acceptChild accepts the current token as a child.
  570. */
  571. func acceptChild(p *parser, self *ASTNode, id LexTokenID) error {
  572. var err error
  573. current := p.node
  574. if p.node, err = p.next(); err == nil {
  575. if current.Token.ID == id {
  576. self.Children = append(self.Children, current)
  577. } else {
  578. err = p.newParserError(ErrUnexpectedToken, current.Token.Val, *current.Token)
  579. }
  580. }
  581. return err
  582. }