You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go高级解析器开发求助:提取核心代码块与函数体

Go代码核心块解析器优化方案

针对你开发Go高级解析器时遇到的导入解析、函数体边界识别、原始格式保留等问题,结合你基于participle的实现,给出以下针对性改进建议:

1. 修复函数体捕获逻辑的边界问题

当前FuncBody.Parse方法存在起始位置未跳过外层{、未处理EOF场景的问题,修改后确保正确识别嵌套{}并完整保留原始格式:

func (f *FuncBody) Parse(lex *lexer.PeekingLexer) error {
    count := 1 // 初始为1,已匹配到外层{
    start := lex.RawCursor()

    for {
        tok := lex.Peek()
        if tok.Kind == lexer.EOF {
            return fmt.Errorf("unclosed function body")
        }

        switch tok.Value {
        case "{":
            count++
        case "}":
            count--
            if count == 0 {
                // 截取到当前}之前的内容
                end := lex.RawCursor()
                tokens := lex.Range(start, end)
                for _, t := range tokens {
                    f.Body += t.Value
                }
                lex.Next() // 跳过当前的}
                return nil
            }
        }
        lex.Next()
    }
}

同时调整FuncDef的解析标签,让外层{由解析器匹配,函数体只捕获内部内容:

type FuncDef struct {
    Name      string         `parser:"@Ident '('"`
    Args      []FuncArg      `parser:"(@@ (',' @@)* )? ')'"`
    ReturnDef *FuncReturnDef `parser:"@@?"`
    Body      *FuncBody      `parser:"'{' @@"` // 去掉末尾的'}',由FuncBody处理闭合
}

2. 完善导入语句的解析规则

当前解析逻辑无法区分单行导入和块级导入,修改结构支持两种导入形式:

type GoFile struct {
    PackageName string       `parser:"'package' @Ident"`
    Imports     []ImportStmt `parser:"@@*"` // 支持多个单行/块级导入
    Decls       []Declaration`parser:"@@*"`
}

type ImportStmt struct {
    Single *ImportDef `parser:"'import' @@"`
    Block  []ImportDef `parser:"| 'import' '(' @@+ ')'"`
}

type ImportDef struct {
    Alias string `parser:"@Ident?"`
    Path  string `parser:"@String"`
}

3. 补全类型定义的解析

恢复并扩展TypeDef结构,支持结构体、接口、基本类型等常见类型声明:

type Declaration struct {
    Func *FuncDef `parser:"'func' @@"`
    Type *TypeDef `parser:"| 'type' @@"`
}

type TypeDef struct {
    Name string       `parser:"@Ident"`
    Def  TypeDefinition `parser:"@@"`
}

type TypeDefinition struct {
    BasicType string     `parser:"@Ident"`
    Struct    *StructDef `parser:"| 'struct' '{' @@* '}'"`
    Interface *InterfaceDef `parser:"| 'interface' '{' @@* '}'"`
    // 可扩展指针、切片、映射等复合类型
}

type StructDef struct {
    Fields []StructField `parser:"@@*"`
}

type StructField struct {
    Name string `parser:"@Ident"`
    Type string `parser:"@Ident"`
}

type InterfaceDef struct {
    Methods []InterfaceMethod `parser:"@@*"`
}

type InterfaceMethod struct {
    Name string `parser:"@Ident '(' ')'"`
    Ret  string `parser:"@Ident?"`
}

4. 修复函数参数与返回值的解析缺陷

当前无法处理复合类型和多返回值,调整解析规则支持更复杂的函数签名:

type FuncArg struct {
    Name string `parser:"@Ident?"` // 支持匿名参数
    Type string `parser:"@(Ident | 'chan' '<'? '>'? Ident | '[]' Ident | '*' Ident)"`
}

type FuncReturnDef struct {
    SingleType string        `parser:"@Ident"`
    MultiTypes []string      `parser:"| '(' (@Ident (',' @Ident)*) ')'"`
    NamedReturns []NamedReturn `parser:"| '(' (@Ident @Ident (',' @Ident @Ident)*) ')'"`
}

type NamedReturn struct {
    Name string `parser:"@Ident"`
    Type string `parser:"@Ident"`
}

5. 保留原始空白符与换行的优化

移除participle.Elide("Whitespace", "EOL")避免丢失格式,在需要忽略空白的解析点手动添加(Whitespace)*规则,例如:

type GoFile struct {
    PackageName string       `parser:"'package' (Whitespace)* @Ident"`
    Imports     []ImportStmt `parser:"@@*"`
    Decls       []Declaration`parser:"@@*"`
}

确保词法分析器保留Whitespace和EOL类型,让函数体捕获完整的原始格式内容。

测试补充

针对多返回值、复合类型参数、嵌套函数体等场景补充测试用例,覆盖边界情况:

{
    name: "function with named returns",
    src: `package main
func Split(s string) (first, second string) { 
    first = s[:1]
    second = s[1:]
    return
}`,
    wantPackage: "main",
    wantDecls: []Declaration{
        {
            Func: &FuncDef{
                Name: "Split",
                Args: []FuncArg{{Name: "s", Type: "string"}},
                ReturnDef: &FuncReturnDef{
                    NamedReturns: []NamedReturn{{Name: "first", Type: "string"}, {Name: "second", Type: "string"}},
                },
                Body: &FuncBody{Body: ` 
    first = s[:1]
    second = s[1:]
    return
`},
            },
        },
    },
}

内容的提问来源于stack exchange,提问作者Julia Carmack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:04:59