Lines Matching refs:p
42 func (p *parser) Parse() ([]Node, []error) {
52 p.parseLines()
53 p.accept(scanner.EOF)
54 p.nodes = append(p.nodes, p.comments...)
55 sort.Sort(byPosition(p.nodes))
57 return p.nodes, p.errors
70 p := &parser{}
71 p.lines = []int{0}
72 p.scanner.Init(r)
73 p.scanner.Error = func(sc *scanner.Scanner, msg string) {
74 p.errorf(msg)
76 p.scanner.Whitespace = 0
77 p.scanner.IsIdentRune = func(ch rune, i int) bool {
82 p.scanner.Mode = scanner.ScanIdents
83 p.scanner.Filename = filename
84 p.next()
85 return p
88 func (p *parser) Unpack(pos Pos) scanner.Position {
90 line := sort.Search(len(p.lines), func(i int) bool { return p.lines[i] > offset }) - 1
92 Filename: p.scanner.Filename,
94 Column: offset - p.lines[line] + 1,
99 func (p *parser) pos() Pos {
100 pos := p.scanner.Position
102 pos = p.scanner.Pos()
107 func (p *parser) errorf(format string, args ...interface{}) {
110 Pos: p.scanner.Position,
112 p.errors = append(p.errors, err)
113 if len(p.errors) >= maxErrors {
118 func (p *parser) accept(toks ...rune) bool {
120 if p.tok != tok {
121 p.errorf("expected %s, found %s", scanner.TokenString(tok),
122 scanner.TokenString(p.tok))
125 p.next()
130 func (p *parser) next() {
131 if p.tok != scanner.EOF {
132 p.tok = p.scanner.Scan()
133 for p.tok == '\r' {
134 p.tok = p.scanner.Scan()
137 if p.tok == '\n' {
138 p.lines = append(p.lines, p.scanner.Position.Offset+1)
142 func (p *parser) parseLines() {
144 p.ignoreWhitespace()
146 if p.parseDirective() {
150 ident := p.parseExpression('=', '?', ':', '#', '\n')
152 p.ignoreSpaces()
154 switch p.tok {
156 p.accept('?')
157 if p.tok == '=' {
158 p.parseAssignment("?=", nil, ident)
160 p.errorf("expected = after ?")
163 p.accept('+')
164 if p.tok == '=' {
165 p.parseAssignment("+=", nil, ident)
167 p.errorf("expected = after +")
170 p.accept(':')
171 switch p.tok {
173 p.parseAssignment(":=", nil, ident)
175 p.parseRule(ident)
178 p.parseAssignment("=", nil, ident)
182 p.nodes = append(p.nodes, &v)
184 p.errorf("expected directive, rule, or assignment after ident " + ident.Dump())
186 switch p.tok {
190 p.accept('\n')
192 p.parseComment()
195 p.errorf("expected assignment or rule definition, found %s\n",
196 p.scanner.TokenText())
202 func (p *parser) parseDirective() bool {
203 if p.tok != scanner.Ident || !isDirective(p.scanner.TokenText()) {
207 d := p.scanner.TokenText()
208 pos := p.pos()
209 p.accept(scanner.Ident)
218 expression, endPos = p.parseDefine()
220 p.ignoreSpaces()
221 expression = p.parseExpression()
224 p.nodes = append(p.nodes, &Directive{
233 func (p *parser) parseDefine() (*MakeString, Pos) {
234 value := SimpleMakeString("", p.pos())
238 switch p.tok {
240 value.appendString(p.scanner.TokenText())
241 if p.scanner.TokenText() == "endef" {
242 p.accept(scanner.Ident)
245 p.accept(scanner.Ident)
247 p.parseEscape()
248 switch p.tok {
252 p.errorf("expected escaped character, found %s",
253 scanner.TokenString(p.tok))
256 value.appendString(`\` + string(p.tok))
258 p.accept(p.tok)
265 p.errorf("unexpected EOF while looking for endef")
268 value.appendString(p.scanner.TokenText())
269 p.accept(p.tok)
273 return value, p.pos()
276 func (p *parser) parseEscape() {
277 p.scanner.Mode = 0
278 p.accept('\\')
279 p.scanner.Mode = scanner.ScanIdents
282 func (p *parser) parseExpression(end ...rune) *MakeString {
283 value := SimpleMakeString("", p.pos())
295 if endParen && parens > 0 && p.tok == ')' {
298 p.accept(')')
303 if p.tok == r {
308 switch p.tok {
312 value.appendString(p.scanner.TokenText())
313 p.accept(scanner.Ident)
315 p.parseEscape()
316 switch p.tok {
320 p.errorf("expected escaped character, found %s",
321 scanner.TokenString(p.tok))
324 value.appendString(`\` + string(p.tok))
326 p.accept(p.tok)
328 p.parseComment()
332 variable = p.parseVariable()
345 p.accept('(')
347 value.appendString(p.scanner.TokenText())
348 p.accept(p.tok)
353 p.errorf("expected closing paren %s", value.Dump())
358 func (p *parser) parseVariable() Variable {
359 pos := p.pos()
360 p.accept('$')
362 switch p.tok {
364 return p.parseBracketedVariable('(', ')', pos)
366 return p.parseBracketedVariable('{', '}', pos)
369 p.accept(p.tok)
371 p.errorf("expected variable name, found %s",
372 scanner.TokenString(p.tok))
374 name = p.parseExpression(variableNameEndRunes...)
377 return p.nameToVariable(name)
380 func (p *parser) parseBracketedVariable(start, end rune, pos Pos) Variable {
381 p.accept(start)
382 name := p.parseExpression(end)
383 p.accept(end)
384 return p.nameToVariable(name)
387 func (p *parser) nameToVariable(name *MakeString) Variable {
393 func (p *parser) parseRule(target *MakeString) {
394 prerequisites, newLine := p.parseRulePrerequisites(target)
397 recipePos := p.pos()
401 if p.tok == '\t' {
402 p.accept('\t')
405 } else if p.parseDirective() {
414 switch p.tok {
416 p.parseEscape()
417 recipe += string(p.tok)
418 p.accept(p.tok)
422 p.accept('\n')
426 recipe += p.scanner.TokenText()
427 p.accept(p.tok)
432 p.nodes = append(p.nodes, &Rule{
441 func (p *parser) parseRulePrerequisites(target *MakeString) (*MakeString, bool) {
444 p.ignoreSpaces()
446 prerequisites := p.parseExpression('#', '\n', ';', ':', '=')
448 switch p.tok {
450 p.accept('\n')
453 p.parseComment()
456 p.accept(';')
458 p.accept(':')
459 if p.tok == '=' {
460 p.parseAssignment(":=", target, prerequisites)
463 more := p.parseExpression('#', '\n', ';')
467 p.parseAssignment("=", target, prerequisites)
472 p.errorf("unexpected token %s after rule prerequisites", scanner.TokenString(p.tok))
478 func (p *parser) parseComment() {
479 pos := p.pos()
480 p.accept('#')
484 switch p.tok {
486 p.parseEscape()
487 if p.tok == '\n' {
490 p.accept(p.tok)
493 comment += "\\" + p.scanner.TokenText()
494 p.accept(p.tok)
496 p.accept('\n')
501 comment += p.scanner.TokenText()
502 p.accept(p.tok)
506 p.comments = append(p.comments, &Comment{
512 func (p *parser) parseAssignment(t string, target *MakeString, ident *MakeString) {
516 p.accept('=')
517 value := p.parseExpression()
526 p.nodes = append(p.nodes, &Assignment{
634 func (p *parser) ignoreSpaces() int {
636 for p.tok == ' ' || p.tok == '\t' {
637 p.accept(p.tok)
643 func (p *parser) ignoreWhitespace() {
644 for isWhitespace(p.tok) {
645 p.accept(p.tok)