func (p *parser) parseExprOrType() ast.Expr { pp := parse.New(sourceExpr) for { pos, tok, str := p.scanner.Scan() if r := tokenTable[tok]; r != nil { if !pp.Parse(&parse.Token{ID: int(tok), Value: []byte(str), Pos: int(pos)}, r) { break } } if tok == token.EOF { break } } if len(pp.Results()) != 1 { p.errors.Add(p.file.Position(0), "gombi parse error") return nil } return p.parseGoExpr(pp.Results()[0]) }
func (p *parser) parseFile() *ast.File { pp := parse.New(sourceFile) skipScan := false for { prev := p.pos if skipScan { skipScan = false } else { p.pos, p.tok, p.lit = p.scanner.Scan() } if r := tokenTable[p.tok]; r != nil { if !pp.Parse(&parse.Token{ID: int(p.tok), Value: []byte(p.lit), Pos: int(p.pos)}, r) { break } } p.leadComment = nil p.lineComment = nil switch p.tok { case token.COMMENT: var comment *ast.CommentGroup var endline int if p.file.Line(p.pos) == p.file.Line(prev) { // The comment is on same line as the previous token; it // cannot be a lead comment but may be a line comment. comment, endline = p.consumeCommentGroup(0) if p.file.Line(p.pos) != endline { // The next token is on a different line, thus // the last comment group is a line comment. p.lineComment = comment } } // consume successor comments, if any endline = -1 for p.tok == token.COMMENT { comment, endline = p.consumeCommentGroup(1) } if endline+1 == p.file.Line(p.pos) { // The next token is following on the line immediately after the // comment group, thus the last comment group is a lead comment. p.leadComment = comment } skipScan = true case token.EOF: break } } if len(pp.Results()) != 1 { if len(pp.Results()) > 1 { fmt.Println("Ambiguous", len(pp.Results())) } else { fmt.Println("no result") } p.errors.Add(p.file.Position(0), "") return nil } return p.parseSourceFile(pp.Results()[0]) }