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 p.ignoreSpaces()
219 if p.tok != '\n' && p.tok != '#' {
220 d = p.scanner.TokenText()
221 p.accept(scanner.Ident)
224 p.ignoreSpaces()
225 expression = p.parseExpression('#')
228 p.errorf("expected ifdef/ifndef/ifeq/ifneq, found %s", d)
232 expression, endPos = p.parseDefine()
234 p.ignoreSpaces()
235 expression = p.parseExpression('#')
238 p.nodes = append(p.nodes, &Directive{
247 func (p *parser) parseDefine() (*MakeString, Pos) {
248 value := SimpleMakeString("", p.pos())
252 switch p.tok {
254 value.appendString(p.scanner.TokenText())
255 if p.scanner.TokenText() == "endef" {
256 p.accept(scanner.Ident)
259 p.accept(scanner.Ident)
261 p.parseEscape()
262 switch p.tok {
266 p.errorf("expected escaped character, found %s",
267 scanner.TokenString(p.tok))
270 value.appendString(`\` + string(p.tok))
272 p.accept(p.tok)
279 p.errorf("unexpected EOF while looking for endef")
282 value.appendString(p.scanner.TokenText())
283 p.accept(p.tok)
287 return value, p.pos()
290 func (p *parser) parseEscape() {
291 p.scanner.Mode = 0
292 p.accept('\\')
293 p.scanner.Mode = scanner.ScanIdents
296 func (p *parser) parseExpression(end ...rune) *MakeString {
297 value := SimpleMakeString("", p.pos())
309 if endParen && parens > 0 && p.tok == ')' {
312 p.accept(')')
317 if p.tok == r {
322 switch p.tok {
326 value.appendString(p.scanner.TokenText())
327 p.accept(scanner.Ident)
329 p.parseEscape()
330 switch p.tok {
334 p.errorf("expected escaped character, found %s",
335 scanner.TokenString(p.tok))
338 value.appendString(`\` + string(p.tok))
340 p.accept(p.tok)
343 variable = p.parseVariable()
356 p.accept('(')
358 value.appendString(p.scanner.TokenText())
359 p.accept(p.tok)
364 p.errorf("expected closing paren %s", value.Dump())
369 func (p *parser) parseVariable() Variable {
370 pos := p.pos()
371 p.accept('$')
373 switch p.tok {
375 return p.parseBracketedVariable('(', ')', pos)
377 return p.parseBracketedVariable('{', '}', pos)
380 p.accept(p.tok)
382 p.errorf("expected variable name, found %s",
383 scanner.TokenString(p.tok))
385 name = p.parseExpression(variableNameEndRunes...)
388 return p.nameToVariable(name)
391 func (p *parser) parseBracketedVariable(start, end rune, pos Pos) Variable {
392 p.accept(start)
393 name := p.parseExpression(end)
394 p.accept(end)
395 return p.nameToVariable(name)
398 func (p *parser) nameToVariable(name *MakeString) Variable {
404 func (p *parser) parseRule(target *MakeString) {
405 prerequisites, newLine := p.parseRulePrerequisites(target)
408 recipePos := p.pos()
412 if p.tok == '\t' {
413 p.accept('\t')
416 } else if p.tok == '\n' {
417 p.accept('\n')
419 } else if p.parseDirective() {
428 switch p.tok {
430 p.parseEscape()
431 recipe += string(p.tok)
432 p.accept(p.tok)
436 p.accept('\n')
440 recipe += p.scanner.TokenText()
441 p.accept(p.tok)
446 p.nodes = append(p.nodes, &Rule{
455 func (p *parser) parseRulePrerequisites(target *MakeString) (*MakeString, bool) {
458 p.ignoreSpaces()
460 prerequisites := p.parseExpression('#', '\n', ';', ':', '=')
462 switch p.tok {
464 p.accept('\n')
467 p.parseComment()
470 p.accept(';')
472 p.accept(':')
473 if p.tok == '=' {
474 p.parseAssignment(":=", target, prerequisites)
477 more := p.parseExpression('#', '\n', ';')
481 p.parseAssignment("=", target, prerequisites)
486 p.errorf("unexpected token %s after rule prerequisites", scanner.TokenString(p.tok))
492 func (p *parser) parseComment() {
493 pos := p.pos()
494 p.accept('#')
498 switch p.tok {
500 p.parseEscape()
501 comment += "\\" + p.scanner.TokenText()
502 p.accept(p.tok)
504 p.accept('\n')
509 comment += p.scanner.TokenText()
510 p.accept(p.tok)
514 p.comments = append(p.comments, &Comment{
520 func (p *parser) parseAssignment(t string, target *MakeString, ident *MakeString) {
524 p.accept('=')
525 value := p.parseExpression('#')
534 p.nodes = append(p.nodes, &Assignment{
644 func (p *parser) ignoreSpaces() int {
646 for p.tok == ' ' || p.tok == '\t' {
647 p.accept(p.tok)
653 func (p *parser) ignoreWhitespace() {
654 for isWhitespace(p.tok) {
655 p.accept(p.tok)