Rust语法解析库erg_parser的使用,高效解析Erg代码并生成AST抽象语法树

Rust语法解析库erg_parser的使用,高效解析Erg代码并生成AST抽象语法树

使用erg_parser作为Python库

erg_parser可以通过pyo3/maturin构建为Python库。

示例

import erg_parser

module = erg_parser.parse("x = 1")
for chunk in module:
    if isinstance(chunk, erg_parser.expr.Def):
        assert chunk.sig.inspect() == "x"

调试安装(使用venv)

python -m venv .venv
source .venv/bin/activate
maturin develop --features pylib_parser

正式安装

maturin build -i python --release --features pylib_parser
pip install <output wheel>

完整Rust使用示例

以下是一个完整的Rust示例,展示如何使用erg_parser库解析Erg代码并生成AST:

use erg_parser::ast::Module;
use erg_parser::lex::Lexer;
use erg_parser::parse::Parser;

fn main() {
    // 要解析的Erg代码
    let code = r#"
x = 1
y = x + 2
fn add(a, b) = a + b
"#;

    // 创建词法分析器
    let lexer = Lexer::new(code.to_string());
    
    // 创建语法分析器
    let mut parser = Parser::new(lexer);
    
    // 解析代码生成AST
    let module: Module = parser.parse().unwrap();
    
    // 打印AST
    println!("AST: {:#?}", module);
    
    // 遍历AST节点
    for chunk in module.iter() {
        match chunk {
            erg_parser::ast::Chunk::Def(def) => {
                println!("Found definition: {}", def.sig);
            }
            erg_parser::ast::Chunk::FnDef(fn_def) => {
                println!("Found function definition: {}", fn_def.sig);
            }
            _ => {}
        }
    }
}

这个示例展示了:

  1. 如何初始化词法分析器(Lexer)和语法分析器(Parser)
  2. 如何解析Erg代码生成AST模块
  3. 如何遍历AST节点并处理不同类型的语法结构
  4. 如何访问定义和函数签名信息

要使用这个示例,你需要在Cargo.toml中添加erg_parser依赖:

[dependencies]
erg_parser = "0.6.52"

1 回复

Rust语法解析库erg_parser的使用:高效解析Erg代码并生成AST抽象语法树

简介

erg_parser是一个用Rust编写的语法解析库,专门用于解析Erg编程语言的代码并生成抽象语法树(AST)。它提供了高效的解析能力,能够处理Erg语言的语法结构,并将其转换为可操作的AST表示形式。

主要特性

  • 高性能的Erg语言解析器
  • 生成详细的抽象语法树(AST)
  • 支持错误恢复和错误报告
  • 易于集成到其他Rust项目中
  • 提供丰富的AST遍历和操作功能

安装

在Cargo.toml中添加依赖:

[dependencies]
erg_parser = "0.1"  # 请检查最新版本号

基本使用方法

1. 解析Erg代码生成AST

use erg_parser::parse_erg_code;

fn main() {
    let erg_code = r#"
        x = 1
        y = x + 2
        print! y
    "#;
    
    match parse_erg_code(erg_code) {
        Ok(ast) => {
            println!("成功解析Erg代码,生成的AST:");
            println!("{:#?}", ast);
        }
        Err(e) => {
            eprintln!("解析错误: {}", e);
        }
    }
}

2. 遍历AST节点

use erg_parser::{parse_erg_code, AstVisitor};

struct MyVisitor;

impl AstVisitor for MyVisitor {
    fn visit_assignment(&mut self, name: &str, value: &Expr) {
        println!("发现赋值语句: {} = {:?}", name, value);
    }
    
    fn visit_binary_expr(&mut self, op: &str, left: &Expr, right: &Expr) {
        println!("发现二元表达式: {} {} {}", left, op, right);
    }
}

fn main() {
    let erg_code = "x = 1 + 2 * 3";
    let ast = parse_erg_code(erg_code).unwrap();
    
    let mut visitor = MyVisitor;
    ast.visit(&mut visitor);
}

3. 修改AST

use erg_parser::{parse_erg_code, Expr, AstMutVisitor};

struct Optimizer;

impl AstMutVisitor for Optimizer {
    fn visit_binary_expr(&mut self, op: &str, left: &mut Expr, right: &mut Expr) {
        // 简化常数表达式,例如将1 + 2替换为3
        if let (Expr::Number(l), Expr::Number(r)) = (left, right) {
            if let Some(result) = match op {
                "+" => Some(l + r),
                "-" => Some(l - r),
                "*" => Some(l * r),
                "/" => Some(l / r),
                _ => None,
            } {
                *left = Expr::Number(result);
                *right = Expr::Number(0); // 占位符,实际使用时需要更优雅的处理
            }
        }
    }
}

fn main() {
    let mut ast = parse_erg_code("x = 1 + 2 * 3").unwrap();
    
    let mut optimizer = Optimizer;
    ast.visit_mut(&mut optimizer);
    
    println!("优化后的AST: {:#?}", ast);
}

高级用法

1. 自定义语法扩展

use erg_parser::{Parser, GrammarBuilder};

fn main() {
    let mut grammar = GrammarBuilder::new()
        .with_erg_core_rules()  // 包含Erg核心语法规则
        .rule("custom_rule", r#""hello" "world""#)  // 添加自定义规则
        .build();
    
    let parser = Parser::new(grammar);
    let result = parser.parse("hello world");
    
    match result {
        Ok(ast) => println!("匹配自定义规则: {:?}", ast),
        Err(e) => eprintln!("解析错误: {}", e),
    }
}

2. 错误处理和恢复

use erg_parser::{parse_erg_code_with_recovery, ParseError};

fn main() {
    let erg_code = r#"
        x = 1
        y = x +  # 这里缺少右操作数
        z = 3
    "#;
    
    let (ast, errors) = parse_erg_code_with_recovery(erg_code);
    
    if !errors.is_empty() {
        println!("发现以下错误,但已尝试恢复:");
        for error in errors {
            match error {
                ParseError::SyntaxError { message, position } => {
                    println!("语法错误@{}: {}", position, message);
                }
                ParseError::LexicalError { message, position } => {
                    println!("词法错误@{}: {}", position, message);
                }
            }
        }
    }
    
    println!("恢复后的AST: {:#?}", ast);
}

性能提示

  1. 对于大型Erg代码文件,考虑使用增量解析
  2. 重用Parser实例以避免重复初始化开销
  3. 在不需要完整AST时,使用轻量级解析模式

总结

erg_parser为Rust开发者提供了强大的Erg语言解析能力,可以方便地集成到编译器、IDE插件、代码分析工具等项目中。通过其丰富的API,开发者可以轻松地解析、遍历和修改Erg代码的AST结构。

完整示例代码

下面是一个结合了上述所有功能的完整示例:

use erg_parser::{
    parse_erg_code, parse_erg_code_with_recovery, 
    AstVisitor, AstMutVisitor, Parser, GrammarBuilder,
    Expr, ParseError
};

// 1. 基本解析示例
fn basic_parsing_example() {
    println!("=== 基本解析示例 ===");
    let erg_code = r#"
        a = 10
        b = a * 2 + 5
        print! b
    "#;
    
    match parse_erg_code(erg_code) {
        Ok(ast) => println!("AST: {:#?}", ast),
        Err(e) => eprintln!("解析错误: {}", e),
    }
}

// 2. AST遍历示例
struct AnalysisVisitor;

impl AstVisitor for AnalysisVisitor {
    fn visit_assignment(&mut self, name: &str, value: &Expr) {
        println!("分析: 变量'{}'被赋值", name);
    }
    
    fn visit_binary_expr(&mut self, op: &str, left: &Expr, right: &Expr) {
        println!("分析: 发现 {} 操作符表达式", op);
    }
}

fn ast_traversal_example() {
    println!("\n=== AST遍历示例 ===");
    let erg_code = "result = (x + y) * z / 2";
    let ast = parse_erg_code(erg_code).unwrap();
    
    let mut visitor = AnalysisVisitor;
    ast.visit(&mut visitor);
}

// 3. AST优化示例
struct ConstantFolder;

impl AstMutVisitor for ConstantFolder {
    fn visit_binary_expr(&mut self, op: &str, left: &mut Expr, right: &mut Expr) {
        if let (Expr::Number(l), Expr::Number(r)) = (left, right) {
            if let Some(result) = match op {
                "+" => Some(l + r),
                "-" => Some(l - r),
                "*" => Some(l * r),
                "/" => if *r != 0 { Some(l / r) } else { None },
                _ => None,
            } {
                *left = Expr::Number(result);
                *right = Expr::Number(1); // 使用1作为占位符
            }
        }
    }
}

fn ast_optimization_example() {
    println!("\n=== AST优化示例 ===");
    let mut ast = parse_erg_code("x = (2 + 3) * (10 - 2)").unwrap();
    println!("优化前 AST: {:#?}", ast);
    
    let mut optimizer = ConstantFolder;
    ast.visit_mut(&mut optimizer);
    
    println!("优化后 AST: {:#?}", ast);
}

// 4. 自定义语法扩展示例
fn custom_grammar_example() {
    println!("\n=== 自定义语法扩展示例 ===");
    let mut grammar = GrammarBuilder::new()
        .with_erg_core_rules()
        .rule("greeting", r#""hello" name"#)
        .build();
    
    let parser = Parser::new(grammar);
    match parser.parse("hello world") {
        Ok(ast) => println!("自定义语法匹配成功: {:?}", ast),
        Err(e) => eprintln!("自定义语法错误: {}", e),
    }
}

// 5. 错误处理示例
fn error_handling_example() {
    println!("\n=== 错误处理示例 ===");
    let erg_code = r#"
        x = 1 +
        y = 2
        z = x * y
    "#;
    
    let (ast, errors) = parse_erg_code_with_recovery(erg_code);
    
    if !errors.is_empty() {
        println!("发现并恢复了以下错误:");
        for error in errors {
            println!("{}", error);
        }
    }
    
    println!("恢复后的AST可用于进一步分析: {:#?}", ast);
}

fn main() {
    basic_parsing_example();
    ast_traversal_example();
    ast_optimization_example();
    custom_grammar_example();
    error_handling_example();
}

这个完整示例展示了erg_parser库的主要功能:

  1. 基本代码解析和AST生成
  2. AST遍历和分析
  3. AST修改和优化
  4. 自定义语法扩展
  5. 错误处理和恢复

您可以根据需要选择使用其中的部分功能,或者像示例中那样组合使用它们来构建更复杂的Erg代码处理工具。

回到顶部