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' {
220 d = p.scanner.TokenText()
221 p.accept(scanner.Ident)
224 p.ignoreSpaces()
225 expression = p.parseExpression()
227 p.errorf("expected ifdef/ifndef/ifeq/ifneq, found %s", d)
231 expression, endPos = p.parseDefine()
233 p.ignoreSpaces()
234 expression = p.parseExpression()
237 p.nodes = append(p.nodes, &Directive{
246 func (p *parser) parseDefine() (*MakeString, Pos) {
247 value := SimpleMakeString("", p.pos())
251 switch p.tok {
253 value.appendString(p.scanner.TokenText())
254 if p.scanner.TokenText() == "endef" {
255 p.accept(scanner.Ident)
258 p.accept(scanner.Ident)
260 p.parseEscape()
261 switch p.tok {
265 p.errorf("expected escaped character, found %s",
266 scanner.TokenString(p.tok))
269 value.appendString(`\` + string(p.tok))
271 p.accept(p.tok)
278 p.errorf("unexpected EOF while looking for endef")
281 value.appendString(p.scanner.TokenText())
282 p.accept(p.tok)
286 return value, p.pos()
289 func (p *parser) parseEscape() {
290 p.scanner.Mode = 0
291 p.accept('\\')
292 p.scanner.Mode = scanner.ScanIdents
295 func (p *parser) parseExpression(end ...rune) *MakeString {
296 value := SimpleMakeString("", p.pos())
308 if endParen && parens > 0 && p.tok == ')' {
311 p.accept(')')
316 if p.tok == r {
321 switch p.tok {
325 value.appendString(p.scanner.TokenText())
326 p.accept(scanner.Ident)
328 p.parseEscape()
329 switch p.tok {
333 p.errorf("expected escaped character, found %s",
334 scanner.TokenString(p.tok))
337 value.appendString(`\` + string(p.tok))
339 p.accept(p.tok)
341 p.parseComment()
345 variable = p.parseVariable()
358 p.accept('(')
360 value.appendString(p.scanner.TokenText())
361 p.accept(p.tok)
366 p.errorf("expected closing paren %s", value.Dump())
371 func (p *parser) parseVariable() Variable {
372 pos := p.pos()
373 p.accept('$')
375 switch p.tok {
377 return p.parseBracketedVariable('(', ')', pos)
379 return p.parseBracketedVariable('{', '}', pos)
382 p.accept(p.tok)
384 p.errorf("expected variable name, found %s",
385 scanner.TokenString(p.tok))
387 name = p.parseExpression(variableNameEndRunes...)
390 return p.nameToVariable(name)
393 func (p *parser) parseBracketedVariable(start, end rune, pos Pos) Variable {
394 p.accept(start)
395 name := p.parseExpression(end)
396 p.accept(end)
397 return p.nameToVariable(name)
400 func (p *parser) nameToVariable(name *MakeString) Variable {
406 func (p *parser) parseRule(target *MakeString) {
407 prerequisites, newLine := p.parseRulePrerequisites(target)
410 recipePos := p.pos()
414 if p.tok == '\t' {
415 p.accept('\t')
418 } else if p.parseDirective() {
427 switch p.tok {
429 p.parseEscape()
430 recipe += string(p.tok)
431 p.accept(p.tok)
435 p.accept('\n')
439 recipe += p.scanner.TokenText()
440 p.accept(p.tok)
445 p.nodes = append(p.nodes, &Rule{
454 func (p *parser) parseRulePrerequisites(target *MakeString) (*MakeString, bool) {
457 p.ignoreSpaces()
459 prerequisites := p.parseExpression('#', '\n', ';', ':', '=')
461 switch p.tok {
463 p.accept('\n')
466 p.parseComment()
469 p.accept(';')
471 p.accept(':')
472 if p.tok == '=' {
473 p.parseAssignment(":=", target, prerequisites)
476 more := p.parseExpression('#', '\n', ';')
480 p.parseAssignment("=", target, prerequisites)
485 p.errorf("unexpected token %s after rule prerequisites", scanner.TokenString(p.tok))
491 func (p *parser) parseComment() {
492 pos := p.pos()
493 p.accept('#')
497 switch p.tok {
499 p.parseEscape()
500 comment += "\\" + p.scanner.TokenText()
501 p.accept(p.tok)
503 p.accept('\n')
508 comment += p.scanner.TokenText()
509 p.accept(p.tok)
513 p.comments = append(p.comments, &Comment{
519 func (p *parser) parseAssignment(t string, target *MakeString, ident *MakeString) {
523 p.accept('=')
524 value := p.parseExpression()
533 p.nodes = append(p.nodes, &Assignment{
643 func (p *parser) ignoreSpaces() int {
645 for p.tok == ' ' || p.tok == '\t' {
646 p.accept(p.tok)
652 func (p *parser) ignoreWhitespace() {
653 for isWhitespace(p.tok) {
654 p.accept(p.tok)