示例#1
0
文件: ast.go 项目: ZxxLang/zxx
// 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,
	})

}