...
1 package parser
2
3 import (
4 "strconv"
5
6 "github.com/vektah/gqlparser/ast"
7 "github.com/vektah/gqlparser/gqlerror"
8 "github.com/vektah/gqlparser/lexer"
9 )
10
11 type parser struct {
12 lexer lexer.Lexer
13 err *gqlerror.Error
14
15 peeked bool
16 peekToken lexer.Token
17 peekError *gqlerror.Error
18
19 prev lexer.Token
20 }
21
22 func (p *parser) peekPos() *ast.Position {
23 if p.err != nil {
24 return nil
25 }
26
27 peek := p.peek()
28 return &peek.Pos
29 }
30
31 func (p *parser) peek() lexer.Token {
32 if p.err != nil {
33 return p.prev
34 }
35
36 if !p.peeked {
37 p.peekToken, p.peekError = p.lexer.ReadToken()
38 p.peeked = true
39 }
40
41 return p.peekToken
42 }
43
44 func (p *parser) error(tok lexer.Token, format string, args ...interface{}) {
45 if p.err != nil {
46 return
47 }
48 p.err = gqlerror.ErrorLocf(tok.Pos.Src.Name, tok.Pos.Line, tok.Pos.Column, format, args...)
49 }
50
51 func (p *parser) next() lexer.Token {
52 if p.err != nil {
53 return p.prev
54 }
55 if p.peeked {
56 p.peeked = false
57 p.prev, p.err = p.peekToken, p.peekError
58 } else {
59 p.prev, p.err = p.lexer.ReadToken()
60 }
61 return p.prev
62 }
63
64 func (p *parser) expectKeyword(value string) lexer.Token {
65 tok := p.peek()
66 if tok.Kind == lexer.Name && tok.Value == value {
67 return p.next()
68 }
69
70 p.error(tok, "Expected %s, found %s", strconv.Quote(value), tok.String())
71 return tok
72 }
73
74 func (p *parser) expect(kind lexer.Type) lexer.Token {
75 tok := p.peek()
76 if tok.Kind == kind {
77 return p.next()
78 }
79
80 p.error(tok, "Expected %s, found %s", kind, tok.Kind.String())
81 return tok
82 }
83
84 func (p *parser) skip(kind lexer.Type) bool {
85 if p.err != nil {
86 return false
87 }
88
89 tok := p.peek()
90
91 if tok.Kind != kind {
92 return false
93 }
94 p.next()
95 return true
96 }
97
98 func (p *parser) unexpectedError() {
99 p.unexpectedToken(p.peek())
100 }
101
102 func (p *parser) unexpectedToken(tok lexer.Token) {
103 p.error(tok, "Unexpected %s", tok.String())
104 }
105
106 func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) {
107 hasDef := p.skip(start)
108 if !hasDef {
109 return
110 }
111
112 for p.peek().Kind != end && p.err == nil {
113 cb()
114 }
115 p.next()
116 }
117
118 func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) {
119 hasDef := p.skip(start)
120 if !hasDef {
121 return
122 }
123
124 called := false
125 for p.peek().Kind != end && p.err == nil {
126 called = true
127 cb()
128 }
129
130 if !called {
131 p.error(p.peek(), "expected at least one definition, found %s", p.peek().Kind.String())
132 return
133 }
134
135 p.next()
136 }
137
View as plain text