代码拉取完成,页面将自动刷新
同步操作将从 秋来冬风/U语言 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package parser
import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"unsafe"
"gitee.com/u-language/u-language/ucom/ast2"
"gitee.com/u-language/u-language/ucom/check3"
"gitee.com/u-language/u-language/ucom/errcode"
"gitee.com/u-language/u-language/ucom/format"
"gitee.com/u-language/u-language/ucom/internal/time"
"gitee.com/u-language/u-language/ucom/internal/utils"
"gitee.com/u-language/u-language/ucom/lex2"
)
// ParserFileBuildMode2 从一个代码文件创建ast树
// - path是文件路径
// - errctx是错误处理上下文
// - IsCheck是控制是否进行语义检查
// - Thread是控制是否并发
func ParserFileBuildMode2(path string, errctx *errcode.ErrCtx, IsCheck bool, Thread bool) (*ast2.Tree, error) {
file, size, buf, err := openfileAndInfo(path) //获取文件描述符,文件大小,测试时还有全部内容
if err != nil {
return nil, err
}
var r *bufio.Reader
if test { //测试时,这些是为了在Benchmark时获得的数据是从去除换行符到抽象语法树生成完毕,不包括打开文件等操作
str := *(*string)(unsafe.Pointer(&buf))
sbuf := strbufpool.Get().(*strings.Reader)
defer strbufpool.Put(sbuf)
sbuf.Reset(str)
r = bufreadpool.Get().(*bufio.Reader)
defer bufreadpool.Put(r)
r.Reset(sbuf)
} else {
r = bufio.NewReaderSize(file, int(size))
}
var t time.Time
try_new_print_LexTime(&t)
FT := lex2.NewFileToken(path, r, errctx, false) //进行词法分析
try_Print_Time(&t)
if errctx.Errbol() { //如果词法分析有错误
return nil, format.ErrorAfterLex
}
try_new_print_AstTime(&t)
tree := ast2.NewTree(FT, path, errctx, Thread) //创建抽象语法树
err = loadAllImport2(filepath.Dir(path), tree.Sbt, *tree.ImportPackage, Thread, errctx, tree.ImporPath)
if err != nil {
return nil, err
}
try_Print_Time(&t)
try_print(tree)
if errctx.Errbol() { //如果语法分析有错误
return nil, nil
}
if IsCheck { //如果要进行语义检查
try_new_print_check(&t)
check3.CheckTree(tree)
try_Print_Time(&t)
}
return tree, nil
}
// ParserPackageBuildMode2 转换一个目录下所有扩展名为.u的源代码文件为抽象语法树
func ParserPackageBuildMode2(dir string, thread bool, errctx *errcode.ErrCtx, sbt *ast2.Sbt, ImportPackage map[string]*ast2.Package) (*ast2.Package, error) {
paths, err := utils.FindU(dir)
if err != nil {
return nil, err
}
if len(paths) == 0 {
return nil, fmt.Errorf("%s目录%w", dir, NoUFileErr)
}
p := ast2.NewPackage(dir, thread, errctx, sbt, ImportPackage)
var wg = utils.NewWaitGroup(thread)
var t time.Time
var result = make(chan error, len(paths))
for _, v := range paths { //将所有源文件进行词法分析后加入包中
v := v
wg.Go(func() {
defer wg.Done()
file, size, buf, err := openfileAndInfo(v)
if err != nil {
result <- fmt.Errorf("path=%s \t err=%w", v, err)
return
}
var r *bufio.Reader
if !test || notest { //如果非测试
r = bufio.NewReaderSize(file, int(size))
} else {
//测试时,这些是为了在Benchmark时获得的数据是从去除换行符到抽象语法树生成完毕,不包括打开文件等操作
str := *(*string)(unsafe.Pointer(&buf))
sbuf := strbufpool.Get().(*strings.Reader)
defer strbufpool.Put(sbuf)
sbuf.Reset(str)
r = bufreadpool.Get().(*bufio.Reader)
defer bufreadpool.Put(r)
r.Reset(sbuf)
}
if !test || notest { //如果非测试
defer file.Close()
}
FT := lex2.NewFileToken(v, r, errctx, false) //进行词法分析
if errctx.Errbol() { //如果词法分析有错误·
return
}
p.AddFile(FT)
})
}
wg.Wait()
select {
case err = <-result:
if err != nil {
return nil, err
}
default:
}
err = loadAllImport2(dir, p.Sbt, p.ImportPackage, thread, errctx, p.ImporPath)
if err != nil {
return nil, fmt.Errorf("%s中的%w", p.PackageName, err)
}
try_print(p)
//进行语义检查
try_new_print_check(&t)
check3.CheckPackage(p, errctx, thread)
try_Print_Time(&t)
return p, nil
}
// loadAllImport2 获取导入包的ast
// - dir是目录
// - ImportPackage 是自己及依赖导入的包
// - sbt 是符号表
// - thread 控制是否并发
// - errctx 是错误处理上下文
// - ImportPath 是所有的导入路径
func loadAllImport2(dir string, sbt *ast2.Sbt, ImportPackage map[string]*ast2.Package, thread bool, errctx *errcode.ErrCtx, ImporPath *ast2.Sbt) error {
var v []string
ImporPath.Range(func(key string, _ fmt.Stringer) bool {
v = append(v, key)
return true
})
var err error
for _, importPath := range v { //获取每个被导入的包
importPath = importPath[1 : len(importPath)-1] //去除字符串左右的"
importPath, err = importPathToAbs(dir, importPath)
if err != nil {
return err
}
p, ok := ImportPackage[importPath]
if ok { //如果已经被导入
continue
}
p, err = loadImport2(importPath, thread, errctx, sbt, ImportPackage)
if err != nil {
return err
}
ImportPackage[importPath] = p
if err := sbt.AddPackage(p); err != errcode.NoErr {
//TODO:更好的报错
errcode.Panic(importPath, 1, nil, err)
}
err = loadAllImport2(importPath, p.Sbt, ImportPackage, thread, errctx, p.ImporPath) //导入被导入包导入的包
if err != nil {
return fmt.Errorf("%s中的%w", p.PackageName, err)
}
}
return nil
}
func loadImport2(path string, thread bool, errctx *errcode.ErrCtx, sbt *ast2.Sbt, ImportPackage map[string]*ast2.Package) (p *ast2.Package, err error) {
p, err = ParserPackageBuildMode2(path, thread, errctx, sbt, ImportPackage)
if errors.Is(err, os.ErrNotExist) {
return nil, fmt.Errorf("%w %s", PathNotFound, path)
}
return
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。