// File.Push 接收扫描到的 Token, func (b *File) Push(pos scanner.Pos, tok token.Token, code string) error { var flag Flag switch tok { case token.NL: flag = FText last := b.Last.Token() if last == token.NL { tok = token.EMPTYLINE // 转 break } if last == token.INDENTATION || last == token.EMPTYLINE { text := b.Last.(*Text) text.Source += code text.Tok = token.EMPTYLINE // 合并 return nil } last = b.Active.Token() if last == token.RIGHT || last == token.IDENT || last.As(token.Literal) { err := b.Active.Final() if err != nil { return err } flag |= FFinal } // 识别 Python 缩进风格 case token.RIGHT: case token.COMMENT, token.COMMENTS: flag = FText if b.Last.Token() == token.EMPTYLINE || b.Last.Token() == token.PLACEHOLDER { tok = token.PLACEHOLDER // 转 break } // 先不使用合并 tok = token.COMMENT case token.PLACEHOLDER, token.INDENTATION: // 统一处理右括号闭合 flag = FText default: if tok > token.PLACEHOLDER || b.Active.Kind(FFile|FBlock|FText) != 0 { return errors.New("ast: Oop! invalid " + tok.String()) } if b.expect != nil { // expect 尝试生成 Text 节点, 并且 tok 不变 if _, pass := b.expect.Eat(tok); pass { flag = FText b.expect = nil break } b.expect = nil } base := Base{ Tok: tok, Pos: pos, Source: code, } b.Active.resolve(&base) if base.Flag == 0 { return errors.New("ast: Oop! invalid " + tok.String()) } return b.add(base) case token.EOF: // 最后的闭合检查 } if flag == 0 { return errors.New("ast: Oop! invalid " + tok.String()) } return b.add(Base{ Flag: flag, Tok: tok, Pos: pos, Source: code, }) }