ast.lua 1.0 KB

12345678910111213141516171819202122232425262728
  1. local lpeg = require 'lpeg'
  2. local P, R, S, V, C, Ct, Cmt, Cg = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cmt, lpeg.Cg
  3. -- Utility
  4. local space = S(' \t\r\n') ^ 0
  5. local comma = P(',') ^ -1
  6. -- "Terminals"
  7. local name = space * C(R('az', 'AZ') * (P('_') + R('09') + R('az', 'AZ')) ^ 0)
  8. local alias = space * name * P(':')
  9. local value = space * C(R('09') ^ 1) -- todo values are hard
  10. local argument = space * Ct(Cg(name, 'name') * P(':') * Cg(value, 'value')) * comma
  11. local arguments = P('(') * Ct(argument ^ 1) * P(')')
  12. local fragmentName = space * (name - 'on')
  13. local fragmentSpread = space * P('...') * fragmentName
  14. -- Nonterminals
  15. local graphQL = P {
  16. 'input',
  17. input = space * V('selectionSet') * -1,
  18. selectionSet = space * P('{') * space * Ct(V('selection') ^ 0) * space * P('}'),
  19. selection = space * (V('field') + fragmentSpread),
  20. field = Ct(space * Cg(alias ^ -1, 'alias') * Cg(name, 'name') * Cg(arguments ^ -1, 'arguments') * Cg(V('selectionSet'), 'children') ^ 0) * comma,
  21. }
  22. return function(str)
  23. return graphQL:match(str)
  24. end