ExprIntrp系列

发布于:2025-07-18 ⋅ 阅读:(22) ⋅ 点赞:(0)

ExprIntrp系列

1.ExprIntrp

ExprIntrp 是 OpenCASCADE 的表达式解释器模块,负责将文本表达式解析为 OpenCASCADE 的符号表达式树。以下是该模块的详细源码解析:

1.1.模件

核心类概览

在这里插入图片描述

文件结构
  • ExprIntrp_Generator.hxx:表达式生成器
  • ExprIntrp_Parser.hxx:解析器接口
  • ExprIntrp_yacc.hxx:语法分析器实现
  • ExprIntrp_lex.pxx:词法分析器实现
  • ExprIntrp_Stack.hxx:表达式栈
  • ExprIntrp_Recept.hxx:语法规则容器

1.2.核心类解析

1.2.1. ExprIntrp_Generator(表达式生成器)
关键方法
class ExprIntrp_Generator : public Standard_Transient {
public:
    // 创建生成器实例
    Standard_EXPORT static Handle(ExprIntrp_Generator) Create();
    // 处理表达式字符串
    Standard_EXPORT void Process(const TCollection_AsciiString& str);
    // 获取解析结果
    Standard_EXPORT Handle(Expr_GeneralExpression) GetResult() const;
    // 定义函数
    Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, const Standard_Integer nargs);
    // 定义变量
    Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name);
    // 定义常量
    Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, const Standard_Real value);
    // 内部表达式栈操作
    Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp);
    Standard_EXPORT Handle(Expr_GeneralExpression) Pop();
};
工作流程
  1. 初始化:创建生成器实例
  2. 定义符号:注册变量、常量、函数
  3. 处理表达式Process() 调用词法/语法分析
  4. 获取结果GetResult() 返回表达式树
1.2.2. ExprIntrp_Parser(解析器)
接口定义
class ExprIntrp_Parser {
public:
    // 单例访问
    Standard_EXPORT static ExprIntrp_Parser& Instance();
    // 解析表达式
    Standard_EXPORT void Parse(const TCollection_AsciiString& str);
    // 获取当前生成器
    Standard_EXPORT Handle(ExprIntrp_Generator) Generator() const;
    // 设置生成器
    Standard_EXPORT void SetGenerator(const Handle(ExprIntrp_Generator)& gen);
};
设计特点
  • 单例模式:全局唯一解析器实例
  • 插件式生成器:可替换不同生成器实现
  • 线程不安全:需外部同步
1.2.3. ExprIntrp_Stack(表达式栈)
核心实现
class ExprIntrp_Stack {
public:
    // 压入表达式
    void Push(const Handle(Expr_GeneralExpression)& exp);
    // 弹出表达式
    Handle(Expr_GeneralExpression) Pop();
    // 栈顶元素
    Handle(Expr_GeneralExpression) Top() const;
    // 栈大小
    Standard_Integer Size() const;
private:
    NCollection_List<Handle(Expr_GeneralExpression)> myStack;
};
在解析中的作用
  • 存储中间表达式结果
  • 处理运算符优先级
  • 管理括号嵌套层级

1.3.解析流程

词法分析 (ExprIntrp_lex)
%{
#include "ExprIntrp_yacc.hxx"
%}

%option noyywrap

DIGIT   [0-9]
INT     {DIGIT}+
FLOAT   {INT}("."{INT})?([eE][-+]?{INT})?
ID      [a-zA-Z_][a-zA-Z0-9_]*

%%

{FLOAT}     { yylval.real = atof(yytext); return TKN_NUMERIC; }
{ID}        { yylval.string = new TCollection_AsciiString(yytext); 
              return TKN_IDENTIFIER; }
"+"         { return TKN_PLUS; }
"-"         { return TKN_MINUS; }
"*"         { return TKN_MULTIPLY; }
"/"         { return TKN_DIVIDE; }
"^"         { return TKN_POWER; }
"("         { return TKN_LPAREN; }
")"         { return TKN_RPAREN; }
语法分析 (ExprIntrp_yacc)
%{
#include "ExprIntrp_Generator.hxx"
%}

%token TKN_NUMERIC TKN_IDENTIFIER
%token TKN_PLUS TKN_MINUS TKN_MULTIPLY TKN_DIVIDE TKN_POWER
%token TKN_LPAREN TKN_RPAREN

%left TKN_PLUS TKN_MINUS
%left TKN_MULTIPLY TKN_DIVIDE
%right TKN_POWER

%%

expression:
    term
    | expression TKN_PLUS term   { $$ = new Expr_Sum($1, $3); }
    | expression TKN_MINUS term  { $$ = new Expr_Difference($1, $3); }
    ;

term:
    factor
    | term TKN_MULTIPLY factor   { $$ = new Expr_Product($1, $3); }
    | term TKN_DIVIDE factor     { $$ = new Expr_Ratio($1, $3); }
    ;

factor:
    primary
    | primary TKN_POWER factor   { $$ = new Expr_Exponential($1, $3); }
    ;

primary:
    TKN_NUMERIC                  { $$ = new Expr_NumericValue($1); }
    | TKN_IDENTIFIER             { $$ = generator->GetNamed($1); }
    | TKN_LPAREN expression TKN_RPAREN { $$ = $2; }
    ;
解析过程
  1. 词法分析:将输入字符串转换为 token 流
  2. 语法分析:根据文法规则构建表达式树
  3. 语义处理:处理符号引用和类型检查
  4. 结果生成:返回完整的表达式树

1.4.关键特性

1.4.1. 运算符优先级处理
优先级 运算符 结合性
最高 ^ (幂运算) 右结合
*, / 左结合
最低 +, - 左结合
1.4.2. 内置函数支持
// 注册数学函数
generator->DefineFunction("sin", 1);   // sin(x)
generator->DefineFunction("cos", 1);   // cos(x)
generator->DefineFunction("sqrt", 1);  // sqrt(x)
// 函数调用解析
function_call:
    TKN_IDENTIFIER TKN_LPAREN arguments TKN_RPAREN {
        $$ = generator->CreateFunction($1, $3);
    }
    ;
1.4.3. 错误处理机制
// 语法错误回调
void ExprIntrp_Parser::Error(const char* msg) {
    // 收集错误位置
    Standard_Integer line, column;
    GetLocation(line, column);
    // 抛出异常
    throw ExprIntrp_SyntaxError(line, column, msg);
}
// 异常类
class ExprIntrp_SyntaxError : public Standard_Failure {
public:
    ExprIntrp_SyntaxError(Standard_Integer line, Standard_Integer col, const char* msg)
        : Standard_Failure(msg), myLine(line), myColumn(col) {}
    Standard_Integer Line() const { return myLine; }
    Standard_Integer Column() const { return myColumn; }
private:
    Standard_Integer myLine;
    Standard_Integer myColumn;
};

1.5.使用示例

基本表达式解析
// 创建解析器
ExprIntrp_Parser& parser = ExprIntrp_Parser::Instance();
// 创建生成器
Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create();
parser.SetGenerator(gen);
// 定义变量
gen->DefineVariable("x");
gen->DefineVariable("y");
// 解析表达式
parser.Parse("x^2 + 2*x*y + y^2");
// 获取表达式树
Handle(Expr_GeneralExpression) expr = gen->GetResult();
自定义函数使用
// 自定义函数实现
class CustomFunc : public Expr_UnaryFunction {
public:
    CustomFunc(const Handle(Expr_GeneralExpression)& arg)
        : Expr_UnaryFunction("custom", arg) {}
    Standard_Real Evaluate(...) const override {
        Standard_Real x = Operand()->Evaluate(vars, vals);
        return x * exp(-x);
    }
};
// 注册自定义函数
gen->DefineFunction("custom", 1);
// 覆盖函数创建逻辑
gen->OverrideFunctionCreator("custom", 
    [](const ExprIntrp_SequenceOfExpression& args) {
        if (args.Length() != 1) {
            throw ExprIntrp_InvalidFunction("custom requires 1 argument");
        }
        return new CustomFunc(args.Value(1));
    });

// 解析含自定义函数的表达式
parser.Parse("custom(sin(x))");

1.6.扩展机制

1.6.1. 自定义运算符
// 添加新运算符 "⊗" 表示张量积
gen->DefineInfixOperator("⊗", 
    [](const Handle(Expr_GeneralExpression)& left,
       const Handle(Expr_GeneralExpression)& right) {
        return new TensorProduct(left, right);
    }, 
    /*优先级*/ 3, /*结合性*/ left);

// 更新词法分析
%%
"⊗"         { return TKN_TENSOR_PRODUCT; }
1.6.2. 语法规则扩展
// 添加矩阵语法支持
matrix:
    TKN_LBRACKET matrix_rows TKN_RBRACKET
    { $$ = new Expr_Matrix($2); }
    ;

matrix_rows:
    matrix_row
    | matrix_rows TKN_SEMICOLON matrix_row
    { $$ = $1.Concatenate($3); }
    ;
1.6.3. 上下文感知解析
// 根据上下文切换解析模式
void ExprIntrp_Parser::SetContext(ParsingContext ctx) {
    switch(ctx) {
    case GeometricConstraints:
        LoadGrammar("geom_constraints.yacc");
        break;
    case PhysicalEquations:
        LoadGrammar("physics_equations.yacc");
        break;
    }
}

1.7.性能优化

1.7.1. 表达式缓存
class ExprIntrp_Generator {
private:
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralExpression)> myExpressionCache; 
public:
    Handle(Expr_GeneralExpression) ParseCached(const TCollection_AsciiString& expr) {
        if (myExpressionCache.IsBound(expr)) {
            return myExpressionCache(expr)->Copy();
        }
        Process(expr);
        Handle(Expr_GeneralExpression) result = GetResult();
        myExpressionCache.Bind(expr, result->Copy());
        return result;
    }
};
1.7.2. 增量解析
// 支持增量输入
void ExprIntrp_Parser::AppendInput(const TCollection_AsciiString& partial) {
    myLexer->AppendInput(partial);
    if (myLexer->HasCompleteToken()) {
        yyparse();
    }
}
1.7.3. 并行解析
// 线程安全的解析器池
class ExprIntrp_ParserPool {
public:
    Handle(ExprIntrp_Parser) AcquireParser() {
        std::lock_guard<std::mutex> lock(myMutex);
        if (myAvailable.empty()) {
            return new ExprIntrp_Parser();
        }
        auto parser = myAvailable.back();
        myAvailable.pop_back();
        return parser;
    }
    void ReleaseParser(Handle(ExprIntrp_Parser)& parser) {
        std::lock_guard<std::mutex> lock(myMutex);
        parser->Reset();
        myAvailable.push_back(parser);
    }
private:
    std::vector<Handle(ExprIntrp_Parser)> myAvailable;
    std::mutex myMutex;
};

1.8.典型应用场景

CAD 参数化建模
# 在 OpenCASCADE 的 Python 绑定中
import OCC.ExprIntrp
# 创建参数化圆柱体
radius_expr = OCC.ExprIntrp.Parse("base_radius + t * growth_rate")
height_expr = OCC.ExprIntrp.Parse("initial_height * exp(-decay_factor * t)")
for t in [0, 0.5, 1.0]:
    cylinder = make_cylinder(
        radius=radius_expr.Evaluate(t=t),
        height=height_expr.Evaluate(t=t)
    )
工程约束求解
// 创建约束系统
Handle(Expr_SystemRelation) system = new Expr_SystemRelation();
// 添加约束:x^2 + y^2 = r^2
parser.Parse("x^2 + y^2 - r^2 = 0");
system->Add(parser.Generator()->GetResult()->AsRelation());
// 添加约束:x + y = 10
parser.Parse("x + y - 10 = 0");
system->Add(parser.Generator()->GetResult()->AsRelation());
// 求解约束
Handle(Expr_Solver) solver = new Expr_Solver(system);
solver->Solve();
物理仿真方程
// 解析热传导方程
parser.Parse("k * (d^2T/dx^2 + d^2T/dy^2) + Q = rho * Cp * dT/dt");
// 获取偏微分方程表达式
Handle(Expr_PDE) heatEquation = parser.Generator()->GetResult()->AsPDE();
// 设置边界条件
heatEquation->SetBoundaryCondition("x=0", "T=300");
heatEquation->SetBoundaryCondition("x=L", "dT/dx=0");
// 数值求解
Handle(FEM_Solver) femSolver = new FEM_Solver(heatEquation);
femSolver->Solve();

1.9.模块局限性

1.9.1. 语法限制
  • 不支持自定义运算符优先级
  • 缺乏完整的类型系统
  • 函数重载支持有限
1.9.2. 性能瓶颈
  • 递归下降解析器对长表达式效率低
  • 缺乏 JIT 编译优化
  • 无表达式预编译机制
1.9.3. 扩展复杂性
  • 修改语法需重新生成解析器
  • 自定义函数集成不够直观
  • 错误消息不够友好

1.10.总结

ExprIntrp 模块是 OpenCASCADE 的表达式解析核心引擎,其设计特点包括:

  1. 分层架构
    • 词法分析 (lex)
    • 语法分析 (yacc)
    • 语义处理 (Generator)
    • 表达式构建 (Stack)
  2. 关键能力
    • 文本到表达式树的转换
    • 运算符优先级处理
    • 自定义函数集成
    • 错误定位与报告
  3. 应用价值
    • CAD 参数化设计
    • 工程约束求解
    • 物理方程建模
    • 优化问题定义
  4. 扩展机制
    • 自定义运算符
    • 语法规则扩展
    • 上下文感知解析
    • 多领域方言支持
  5. 优化方向
    • 表达式缓存
    • 增量解析
    • 并行处理
    • JIT 编译优化

ExprIntrp 作为 OpenCASCADE 数学框架的关键组成部分,桥接了文本表达与符号计算之间的鸿沟,为复杂工程系统的建模与分析提供了强大的基础支持。

2.ExprIntrp_Analysis

ExprIntrp_Analysis 是 OpenCASCADE 表达式解释器模块的核心状态管理类,负责维护解析过程中的上下文和符号表。以下是对其源码的详细解析:

2.1.类定义与职责

头文件位置
ExprIntrp_Analysis.hxx
类声明
class ExprIntrp_Analysis : public Standard_Transient {
    DEFINE_STANDARD_RTTIEXT(ExprIntrp_Analysis, Standard_Transient)
public:
    // 构造函数
    Standard_EXPORT ExprIntrp_Analysis();
    // 栈操作
    Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp);
    Standard_EXPORT Handle(Expr_GeneralExpression) Pop();
    Standard_EXPORT Handle(Expr_GeneralExpression) Top() const;
    // 结果管理
    Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp);
    Standard_EXPORT const Handle(Expr_GeneralExpression)& Result() const;
    Standard_EXPORT void SetRelation(const Handle(Expr_GeneralRelation)& rel);
    Standard_EXPORT const Handle(Expr_GeneralRelation)& Relation() const;
    // 符号表管理
    Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name);
    Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name);
    Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, Standard_Real value);
    // 符号查询
    Standard_EXPORT Standard_Boolean IsFunction(const TCollection_AsciiString& name) const;
    Standard_EXPORT Standard_Boolean IsVariable(const TCollection_AsciiString& name) const;
    Standard_EXPORT Standard_Boolean IsConstant(const TCollection_AsciiString& name) const;
    Standard_EXPORT Standard_Real GetConstant(const TCollection_AsciiString& name) const;
    // 状态重置
    Standard_EXPORT void Reset();
private:
    ExprIntrp_Stack myStack;  // 表达式栈
    Handle(Expr_GeneralExpression) myResultExp; // 表达式结果
    Handle(Expr_GeneralRelation) myResultRel;   // 关系结果
    // 符号表
    NCollection_DataMap<TCollection_AsciiString, Standard_Integer> myFunctions;
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_NamedUnknown)> myVariables;
    NCollection_DataMap<TCollection_AsciiString, Standard_Real> myConstants;
};

2.2.核心组件解析

2.2.1. 表达式栈 (ExprIntrp_Stack)
class ExprIntrp_Stack {
public:
    void Push(const Handle(Expr_GeneralExpression)& exp);
    Handle(Expr_GeneralExpression) Pop();
    Standard_Boolean IsEmpty() const;
private:
    NCollection_List<Handle(Expr_GeneralExpression)> myStack;
};
  • LIFO结构:后进先出的栈结构
  • 中间结果存储:保存解析过程中的部分表达式
  • 运算符处理:协助处理运算符优先级和结合性
2.2.2. 符号表系统
函数表 (myFunctions)
NCollection_DataMap<TCollection_AsciiString, Standard_Integer> myFunctions;
  • :函数名称(如 “sin”、“customFunc”)
  • :参数数量(如 sin→1,max→2)
  • 注册方式DefineFunction("sin", 1)
变量表 (myVariables)
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_NamedUnknown)> myVariables;
  • :变量名称(如 “x”、“radius”)
  • :对应的 Expr_NamedUnknown 实例
  • 特点:相同名称的变量返回相同实例(单例行为)
常量表 (myConstants)
NCollection_DataMap<TCollection_AsciiString, Standard_Real> myConstants;
  • :常量名称(如 “PI”、“E”)
  • :数值(如 PI→3.14159)
  • 预定义常量:通常包含数学常数
2.2.3. 结果管理
// 设置表达式结果
void SetResult(const Handle(Expr_GeneralExpression)& exp);
// 设置关系结果
void SetRelation(const Handle(Expr_GeneralRelation)& rel);
// 获取结果
const Handle(Expr_GeneralExpression)& Result() const;
const Handle(Expr_GeneralRelation)& Relation() const;
  • 双结果系统:支持表达式和关系两种解析结果
  • 互斥存储:一次解析只能设置一种结果类型
  • 使用场景
    • 表达式:2*x + 3
    • 关系:x^2 + y^2 = r^2

2.3.工作流程

解析过程中的交互

在这里插入图片描述

典型解析步骤

  1. 初始化:创建 ExprIntrp_Analysis 实例
  2. 注册符号:定义变量、函数、常量
  3. 开始解析Generator 使用分析实例
  4. 栈操作:解析过程中推入/弹出中间表达式
  5. 结果设置:解析完成时设置最终结果
  6. 获取结果:从分析实例提取解析结果

2.4.关键方法实现

2.4.1. 符号定义
void DefineVariable(const TCollection_AsciiString& name) {
    if (myVariables.IsBound(name)) {
        ExprIntrp::RaiseVariableAlreadyDefined(name);
    }
    myVariables.Bind(name, new Expr_NamedUnknown(name));
}
void DefineConstant(const TCollection_AsciiString& name, Standard_Real value) {
    if (myConstants.IsBound(name)) {
        ExprIntrp::RaiseConstantAlreadyDefined(name);
    }
    myConstants.Bind(name, value);
}
2.4.2. 符号查询
Standard_Boolean IsVariable(const TCollection_AsciiString& name) const {
    return myVariables.IsBound(name) || myConstants.IsBound(name);
}
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
    if (myVariables.IsBound(name)) {
        return myVariables(name);
    }
    if (myConstants.IsBound(name)) {
        return new Expr_NumericValue(myConstants(name));
    }
    ExprIntrp::RaiseUndefinedVariable(name);
    return nullptr; // never reached
}
2.4.3. 栈操作
void Push(const Handle(Expr_GeneralExpression)& exp) {
    if (exp.IsNull()) {
        Standard_NullObject::Raise("ExprIntrp_Analysis::Push");
    }
    myStack.Push(exp);
}
Handle(Expr_GeneralExpression) Pop() {
    if (myStack.IsEmpty()) {
        ExprIntrp::RaiseStackIsEmpty();
    }
    return myStack.Pop();
}

2.5.设计特点

2.5.1. 状态集中管理
  • 统一存储:所有解析状态(栈、符号表、结果)集中管理
  • 隔离解析器:使解析器实现无状态,易于复用
  • 上下文保存:支持多解析上下文切换
2.5.2. 符号表高效查找
  • 哈希映射:使用 NCollection_DataMap 实现 O(1) 复杂度查找
  • 名称规范化:存储前统一转换为小写(可选)
  • 作用域管理:单作用域设计(无嵌套作用域)
2.5.3. 错误处理机制
// 错误代码定义
enum ExprIntrp_ErrorCode {
    UndefinedVariable,
    FunctionNotDefined,
    StackUnderflow,
    // ...
};
// 统一错误处理
void ExprIntrp::RaiseError(ExprIntrp_ErrorCode code, const TCollection_AsciiString& info = "") {
    switch(code) {
    case UndefinedVariable:
        throw ExprIntrp_UndefinedVariable(info);
    case FunctionNotDefined:
        throw ExprIntrp_FunctionNotDefined(info);
    // ...
    }
}
2.5.4. 线程安全考虑
  • 非线程安全:设计为单线程使用
  • 多实例支持:每个线程可创建独立分析实例
  • 共享符号表:可通过复制构造函数共享预定义符号

2.6.使用模式

基本用法
// 创建分析上下文
Handle(ExprIntrp_Analysis) analysis = new ExprIntrp_Analysis();
// 注册符号
analysis->DefineVariable("x");
analysis->DefineConstant("PI", 3.1415926535);
analysis->DefineFunction("sin", 1);
// 创建生成器并关联分析上下文
Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create();
gen->SetAnalysis(analysis);
// 解析表达式
gen->Process("sin(PI * x)");
// 获取结果
Handle(Expr_GeneralExpression) expr = analysis->Result();
高级用法:多上下文管理
// 创建全局上下文(共享符号)
Handle(ExprIntrp_Analysis) globalCtx = new ExprIntrp_Analysis();
globalCtx->DefineConstant("E", 2.71828);
globalCtx->DefineFunction("log", 1);
// 创建专用上下文(继承全局符号)
Handle(ExprIntrp_Analysis) localCtx = new ExprIntrp_Analysis(*globalCtx);
localCtx->DefineVariable("t");
// 解析专用表达式
gen->SetAnalysis(localCtx);
gen->Process("log(E) * t");

2.7.扩展机制

2.7.1. 自定义符号处理器
class CustomSymbolHandler : public Standard_Transient {
public:
    virtual Handle(Expr_GeneralExpression) HandleSymbol(const TCollection_AsciiString& name, ExprIntrp_Analysis& analysis) = 0;
};
// 在分析类中扩展
void ExprIntrp_Analysis::SetSymbolHandler(const Handle(CustomSymbolHandler)& handler) {
    mySymbolHandler = handler;
}
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
    // 优先使用自定义处理器
    if (!mySymbolHandler.IsNull()) {
        auto result = mySymbolHandler->HandleSymbol(name, *this);
        if (!result.IsNull()) return result;
    }
    // 默认处理...
}
2.7.2. 动态作用域
// 进入新作用域
void PushScope() {
    myScopeStack.Push(myCurrentScope);
    myCurrentScope = new SymbolScope();
}
// 退出作用域
void PopScope() {
    if (myScopeStack.IsEmpty()) return;
    myCurrentScope = myScopeStack.Pop();
}
// 作用域感知的符号查询
Standard_Boolean IsVariable(const TCollection_AsciiString& name) const {
    return myCurrentScope->Variables().IsBound(name) || myGlobalScope->Variables().IsBound(name);
}
2.7.3. 符号类型推断
// 自动识别未定义符号
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
    if (myVariables.IsBound(name)) {
        return myVariables(name);
    }
    // 尝试识别为函数(零参数)
    if (myAutoDetectFunctions && !myFunctions.IsBound(name)) {
        DefineFunction(name, 0); // 注册为零参数函数
        return new ExprIntrp_FunctionCall(name, ExprIntrp_SequenceOfExpression());
    }
    // 尝试识别为变量
    DefineVariable(name);
    return myVariables(name);
}

2.8.性能优化

2.8.1. 符号表缓存
// 缓存最近访问的符号
mutable NCollection_LRU<TCollection_AsciiString, Handle(Expr_GeneralExpression)> mySymbolCache;
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
    // 先检查缓存
    if (mySymbolCache.Contains(name)) {
        return mySymbolCache.Find(name);
    }
    // 正常查找...
    Handle(Expr_GeneralExpression) result = ...;
    // 更新缓存
    mySymbolCache.Bind(name, result);
    return result;
}
2.8.2. 延迟符号解析
// 特殊代理表达式
class LazySymbol : public Expr_GeneralExpression {
public:
    LazySymbol(const TCollection_AsciiString& name, const ExprIntrp_Analysis& analysis) : myName(name), myAnalysis(analysis) {}
    Standard_Real Evaluate(...) const override {
        return Resolve()->Evaluate(vars, vals);
    }
private:
    Handle(Expr_GeneralExpression) Resolve() const {
        if (myResolved.IsNull()) {
            myResolved = myAnalysis.GetNamed(myName);
        }
        return myResolved;
    }
    TCollection_AsciiString myName;
    mutable Handle(Expr_GeneralExpression) myResolved;
    const ExprIntrp_Analysis& myAnalysis;
};
// 在GetNamed中返回代理
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
    return new LazySymbol(name, *this);
}
2.8.3. 批量符号注册
// 从配置文件加载符号
void LoadSymbolsFromConfig(const TCollection_AsciiString& configFile) {
    // 解析配置文件
    NCollection_DataMap<TCollection_AsciiString, Standard_Real> constants;
    NCollection_List<TCollection_AsciiString> variables;
    // ...
    // 批量注册
    myConstants.Unite(constants);
    for (auto& var : variables) {
        DefineVariable(var);
    }
}

2.9.典型应用场景

CAD 参数化设计
// 创建设计参数上下文
Handle(ExprIntrp_Analysis) designCtx = new ExprIntrp_Analysis();
designCtx->DefineVariable("length");
designCtx->DefineVariable("width");
designCtx->DefineConstant("thickness", 5.0);
// 解析设计规则
parser.Parse("volume = length * width * thickness");
// 在交互环境中更新
designCtx->SetVariableValue("length", 100.0);
designCtx->SetVariableValue("width", 50.0);
Standard_Real vol = designCtx->Evaluate("volume");
工程计算模板
// 创建计算模板
Handle(ExprIntrp_Analysis) template = new ExprIntrp_Analysis();
template->DefineFunction("stress", 3); // stress(F, A, matFactor)
template->Parse("s = stress(force, area, material_factor)");
// 客户端使用
template->SetVariableValue("force", 5000); // N
template->SetVariableValue("area", 0.01);  // m²
template->SetVariableValue("material_factor", 1.5);
Standard_Real stress = template->Evaluate("s");
教学演示系统
// 创建交互式数学环境
Handle(ExprIntrp_Analysis) mathEnv = new ExprIntrp_Analysis();
mathEnv->DefineConstant("PI", 3.1415926535);
mathEnv->DefineFunction("deriv", 2); // deriv(expr, var)
// 用户输入
mathEnv->Process("f = x^2 + sin(y)");
mathEnv->Process("df_dx = deriv(f, x)");
// 求值演示
mathEnv->SetVariableValue("x", 2.0);
mathEnv->SetVariableValue("y", M_PI/2);
Standard_Real result = mathEnv->Evaluate("df_dx"); // 应为4.0

2.10.模块局限性

2.10.1. 作用域限制
  • 单层作用域,不支持嵌套作用域
  • 无法处理块级变量声明
2.10.2. 类型系统缺失
  • 无数据类型区分(整数、浮点、布尔)
  • 无类型检查机制
2.10.3. 符号冲突
  • 变量、函数、常量共享命名空间
  • 无法定义同名的变量和函数
2.10.4. 错误恢复
  • 错误发生后无法恢复解析状态
  • 缺乏详细的错误位置信息

2.11.总结

ExprIntrp_Analysis 是 OpenCASCADE 表达式解释器的状态管理核心

  1. 核心职责

    • 维护表达式解析栈
    • 管理符号表(变量、函数、常量)
    • 存储解析结果(表达式/关系)
  2. 关键特性

    • 高效的符号查找(哈希映射)
    • 双结果存储系统
    • 可扩展的符号处理机制
    • 错误处理框架
  3. 设计亮点

    • 集中式状态管理
    • 轻量级栈实现
    • 符号单例保证
    • 上下文隔离支持
  4. 应用价值

    • CAD参数化设计
    • 工程计算模板
    • 交互式数学环境
    • 约束规则管理
  5. 改进方向
    在这里插入图片描述

    作为表达式解释器的基础设施,ExprIntrp_Analysis 为 OpenCASCADE 的符号处理能力提供了关键支撑,使文本表达式到符号表达式的转换成为可能,在参数化设计和工程计算领域发挥着重要作用。

    3.ExprIntrp_Generator

    ExprIntrp_Generator 是 OpenCASCADE 表达式解释器模块的核心类,负责将词法分析器和语法分析器的输出转换为表达式树。以下是对其源码的深入解析:

    3.1.类定义与继承关系

    头文件位置
    ExprIntrp_Generator.hxx
    
    类声明
    class ExprIntrp_Generator : public Standard_Transient {
        DEFINE_STANDARD_RTTIEXT(ExprIntrp_Generator, Standard_Transient)
    public:
        // 创建生成器实例(工厂方法)
        Standard_EXPORT static Handle(ExprIntrp_Generator) Create();
        // 设置关联的分析上下文
        Standard_EXPORT void SetAnalysis(const Handle(ExprIntrp_Analysis)& theAnalysis);
        // 处理表达式字符串
        Standard_EXPORT void Process(const TCollection_AsciiString& str);
        // 获取解析结果
        Standard_EXPORT Handle(Expr_GeneralExpression) GetResult() const;
        Standard_EXPORT Handle(Expr_GeneralRelation) GetRelation() const;
        // 符号定义接口
        Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, Standard_Integer nbargs);
        Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name);
        Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, Standard_Real value);
        // 栈操作
        Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp);
        Standard_EXPORT Handle(Expr_GeneralExpression) Pop();
        // 语法分析器接口
        Standard_EXPORT virtual void Use(const Handle(ExprIntrp_yacc)& theParser);
    protected:
        // 构造函数
        Standard_EXPORT ExprIntrp_Generator();
        // 结果管理
        Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp);
        Standard_EXPORT void SetRelation(const Handle(Expr_GeneralRelation)& rel);
    private:
        Handle(ExprIntrp_Analysis) myAnalysis;  // 关联的分析上下文
        Handle(ExprIntrp_yacc) myParser;        // 语法分析器实例
    };
    

    3.2.核心组件解析

    3.2.1. 与分析上下文的关联 (ExprIntrp_Analysis)
    void SetAnalysis(const Handle(ExprIntrp_Analysis)& theAnalysis) {
        myAnalysis = theAnalysis;
    }
    
    • 职责代理:将符号定义和栈操作委托给分析上下文
    • 状态共享:允许多个生成器共享同一上下文
    • 生命周期:不持有所有权,需外部管理
    3.2.2. 语法分析器集成 (ExprIntrp_yacc)
    virtual void Use(const Handle(ExprIntrp_yacc)& theParser) {
        myParser = theParser;
        myParser->SetGenerator(this); // 建立双向链接
    }
    
    • 插件式架构:支持不同的语法分析器实现
    • 回调机制:语法分析器通过生成器构建表达式
    • 默认实现:使用Bison生成的ExprIntrp_yacc

    3.3.关键方法实现

    3.3.1. 表达式处理流程 (Process)
    void ExprIntrp_Generator::Process(const TCollection_AsciiString& str) {
        // 重置分析状态
        myAnalysis->Reset();
        // 配置词法分析器
        ExprIntrp_lexer lexer;
        lexer.SetInput(str);
        // 配置语法分析器
        myParser->SetScanner(&lexer);
        try {
            // 执行语法分析
            myParser->parse();
            // 检查结果有效性
            if (myAnalysis->Result().IsNull() && myAnalysis->Relation().IsNull()) {
                ExprIntrp::RaiseNoResult();
            }
        }
        catch (Standard_Failure) {
            // 异常处理
            myAnalysis->Reset();
            throw;
        }
    }
    
    3.3.2. 符号定义实现
    void DefineFunction(const TCollection_AsciiString& name, Standard_Integer nbargs) {
        if (myAnalysis.IsNull()) {
            Standard_NullObject::Raise("No analysis context set");
        }
        myAnalysis->DefineFunction(name, nbargs);
    }
    void DefineVariable(const TCollection_AsciiString& name) {
        myAnalysis->DefineVariable(name);
    }
    
    3.3.3. 栈操作实现
    void Push(const Handle(Expr_GeneralExpression)& exp) {
        myAnalysis->Push(exp);
    }
    Handle(Expr_GeneralExpression) Pop() {
        return myAnalysis->Pop();
    }
    
    3.3.4. 结果获取方法
    Handle(Expr_GeneralExpression) GetResult() const {
        return myAnalysis->Result();
    }
    Handle(Expr_GeneralRelation) GetRelation() const {
        return myAnalysis->Relation();
    }
    

    3.4.表达式构建机制

    3.4.1. 基础表达式构建
    数值常量
    // 在语法分析器中
    case TKN_NUMERIC:
        generator->Push(new Expr_NumericValue(yylval.real));
        break;
    
    变量引用
    case TKN_IDENTIFIER:
        generator->Push(generator->GetNamed(yylval.string));
        break;
    

    3.4.2. 二元运算处理

    加法运算
    // 在语法规则中
    expression: expression '+' term
        {
            Handle(Expr_GeneralExpression) right = generator->Pop();
            Handle(Expr_GeneralExpression) left = generator->Pop();
            generator->Push(new Expr_Sum(left, right));
        }
    
    乘法运算
    term: term '*' factor
        {
            Handle(Expr_GeneralExpression) right = generator->Pop();
            Handle(Expr_GeneralExpression) left = generator->Pop();
            generator->Push(new Expr_Product(left, right));
        }
    

    3.4.3. 函数调用处理

    function_call: TKN_IDENTIFIER '(' arguments ')'
        {
            // 获取参数
            ExprIntrp_SequenceOfExpression args = generator->PopArguments();
            // 创建函数调用
            generator->Push(new ExprIntrp_FunctionCall($1, args));
        }
        
    arguments: /* 空 */
             | expression_list
             ;
    expression_list: expression
                   | expression_list ',' expression
                   ;
    

    3.5.高级功能实现

    3.5.1. 关系表达式处理
    relation: expression '=' expression
        {
            Handle(Expr_GeneralExpression) right = generator->Pop();
            Handle(Expr_GeneralExpression) left = generator->Pop();
            generator->SetRelation(new Expr_SingleRelation(left, right));
        }
    
    3.5.2. 自定义函数处理
    // 函数创建接口
    virtual Handle(Expr_GeneralFunction) CreateFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfExpression& args) {
        // 检查参数数量
        Standard_Integer nbArgs = myAnalysis->FunctionArgs(name);
        if (args.Length() != nbArgs) {
            ExprIntrp::RaiseWrongArgs(name, nbArgs, args.Length());
        }
        // 创建标准函数
        if (name == "sin") {
            return new Expr_Sin(args.Value(1));
        }
        // ... 其他内置函数
        // 创建通用函数调用
        return new ExprIntrp_FunctionCall(name, args);
    }
    
    3.5.3. 运算符重载扩展
    // 添加自定义运算符支持
    void DefineOperator(const TCollection_AsciiString& op, Standard_Integer priority, OperatorAssociativity associativity, OperatorHandler handler) {
        myOperatorMap.Bind(op, OperatorInfo(priority, associativity, handler));
    }
    
    // 在语法分析中使用
    operator_expression: 
          primary
        | operator_expression op_token operator_expression
        {
            OperatorInfo info = generator->GetOperatorInfo($2);
            Handle(Expr_GeneralExpression) right = generator->Pop();
            Handle(Expr_GeneralExpression) left = generator->Pop();
            generator->Push(info.Handler(left, right));
        }
    

    3.6.语法树优化

    3.6.1. 常量折叠优化
    // 在表达式构建时优化
    void Push(const Handle(Expr_GeneralExpression)& exp) {
        // 尝试简化表达式
        Handle(Expr_GeneralExpression) simplified = exp->ShallowSimplified();
        // 如果是常量,直接存储数值
        if (simplified->IsConstant()) {
            simplified = new Expr_NumericValue(simplified->Evaluate(NullVars, NullVals));
        }
        myAnalysis->Push(simplified);
    }
    
    3.6.2. 公共子表达式消除
    // 公共子表达式缓存
    NCollection_DataMap<Expr_GeneralExpression, Handle(Expr_GeneralExpression)> myExpressionCache;
    Handle(Expr_GeneralExpression) CreateExpression(ExprType type, ...) {
        // 构造临时表达式
        Handle(Expr_GeneralExpression) temp = ...;
        // 检查是否已存在
        if (myExpressionCache.IsBound(temp)) {
            return myExpressionCache.Find(temp);
        }
        // 简化并缓存
        Handle(Expr_GeneralExpression) result = temp->ShallowSimplified();
        myExpressionCache.Bind(result, result);
        return result;
    }
    
    3.6.3. 死代码消除
    // 在关系处理中优化
    void SetRelation(const Handle(Expr_GeneralRelation)& rel) {
        // 移除恒真/恒假关系
        if (rel->IsSatisfied() == Standard_True) {
            rel = new Expr_AlwaysTrue();
        }
        else if (rel->IsSatisfied() == Standard_False) {
            rel = new Expr_AlwaysFalse();
        }
        myAnalysis->SetRelation(rel);
    }
    

    3.7.错误处理机制

    3.7.1. 语法错误处理
    // 在语法分析器中
    void yyerror(const char* msg) {
        // 获取位置信息
        Standard_Integer line = yylineno;
        Standard_Integer column = yycolumn;
        // 构建详细错误信息
        TCollection_AsciiString fullMsg = "Line ";
        fullMsg += TCollection_AsciiString(line);
        fullMsg += ", column ";
        fullMsg += TCollection_AsciiString(column);
        fullMsg += ": ";
        fullMsg += msg;
        // 抛出异常
        throw ExprIntrp_SyntaxError(fullMsg);
    }
    
    3.7.2. 语义错误处理
    未定义符号
    Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) {
        if (!myAnalysis->IsDefined(name)) {
            ExprIntrp::RaiseUndefinedSymbol(name);
        }
        return myAnalysis->GetNamed(name);
    }
    
    参数不匹配
    void CheckFunctionArgs(const TCollection_AsciiString& name, Standard_Integer expected, Standard_Integer actual) {
        if (expected != actual) {
            TCollection_AsciiString msg = "Function '";
            msg += name;
            msg += "' expects ";
            msg += TCollection_AsciiString(expected);
            msg += " arguments, got ";
            msg += TCollection_AsciiString(actual);
            throw ExprIntrp_InvalidArgs(msg);
        }
    }
    

    3.8.扩展机制

    3.8.1. 自定义语法分析器
    class CustomParser : public ExprIntrp_yacc {
    public:
        CustomParser(ExprIntrp_Generator* gen) : ExprIntrp_yacc(gen) {}
    protected:
        // 覆盖语法规则
        virtual int parse() override {
            // 自定义解析逻辑
            ...
        }
    };
    // 在生成器中使用
    generator->Use(new CustomParser(generator));
    
    3.8.2. 表达式监听器
    class ExprListener : public Standard_Transient {
    public:
        virtual void OnCreateExpression(const Handle(Expr_GeneralExpression)& exp) = 0;
        virtual void OnCreateRelation(const Handle(Expr_GeneralRelation)& rel) = 0;
    };
    // 在生成器中添加
    void AddListener(const Handle(ExprListener)& listener) {
        myListeners.Append(listener);
    }
    // 在创建表达式时通知
    void SetResult(const Handle(Expr_GeneralExpression)& exp) {
        for (auto& listener : myListeners) {
            listener->OnCreateExpression(exp);
        }
        myAnalysis->SetResult(exp);
    }
    
    3.8.3. 多方言支持
    // 方言枚举
    enum ExpressionDialect {
        StandardMath,     // 默认数学表达式
        GeometricConstraints, // 几何约束表达式
        PhysicalUnits     // 带单位的物理表达式
    };
    // 设置方言
    void SetDialect(ExpressionDialect dialect) {
        switch (dialect) {
        case GeometricConstraints:
            myParser = new GeomConstraintParser(this);
            break;
        case PhysicalUnits:
            myParser = new PhysicalUnitParser(this);
            break;
        default:
            myParser = new ExprIntrp_yacc(this);
        }
    }
    

    3.9.典型工作流程

    基本表达式解析

    在这里插入图片描述

    关系表达式解析

    在这里插入图片描述

    3.10.性能优化策略

    3.10.1. 表达式池技术
    class ExpressionPool {
    public:
        Handle<Expr_GeneralExpression> GetOrCreate(ExprType type, ...) {
            // 创建临时键
            ExpressionKey key(type, ...);
            // 检查池中是否存在
            if (myPool.Find(key, expr)) {
                return expr;
            }
            // 创建新表达式
            expr = new ...;
            myPool.Bind(key, expr);
            return expr;
        }
    private:
        NCollection_DataMap<ExpressionKey, Handle<Expr_GeneralExpression>> myPool;
    };
    // 在生成器中使用
    Handle<Expr_GeneralExpression> CreateSum(left, right) {
        return myPool->GetOrCreate(Expr_Sum, left, right);
    }
    
    3.10.2. 增量解析
    void AppendInput(const TCollection_AsciiString& partial) {
        // 追加到词法分析器
        myLexer->AppendInput(partial);
        // 继续解析
        if (myParser->CanResume()) {
            myParser->Resume();
        }
    }
    
    3.10.3. 预编译表达式
    Handle<Expr_CompiledExpression> Compile(const TCollection_AsciiString& expr) {
        // 解析表达式
        Process(expr);
        Handle<Expr_GeneralExpression> tree = GetResult();
        // 转换为可执行形式
        return new Expr_CompiledExpression(tree);
    }
    

    3.11.应用场景

    CAD 参数驱动设计
    // 创建参数生成器
    Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create();
    Handle(ExprIntrp_Analysis) analysis = new ExprIntrp_Analysis();
    gen->SetAnalysis(analysis);
    // 定义设计参数
    gen->DefineVariable("length");
    gen->DefineVariable("width");
    gen->DefineConstant("thickness", 5.0);
    // 解析体积公式
    gen->Process("volume = length * width * thickness");
    // 更新参数值
    analysis->SetValue("length", 100.0);
    analysis->SetValue("width", 50.0);
    // 计算体积
    Standard_Real vol = analysis->Evaluate("volume"); // 100*50*5=25000
    
    工程约束求解
    // 创建约束系统
    Handle(Expr_SystemRelation) system = new Expr_SystemRelation();
    // 添加距离约束
    gen->Process("(x2-x1)^2 + (y2-y1)^2 = dist^2");
    system->Add(gen->GetRelation());
    // 添加角度约束
    gen->Process("atan2(y2-y1, x2-x1) = angle");
    system->Add(gen->GetRelation());
    // 求解系统
    Handle(Expr_Solver) solver = new Expr_Solver(system);
    solver->SetVariable("x1", 0.0);
    solver->SetVariable("y1", 0.0);
    solver->SetVariable("dist", 10.0);
    solver->SetVariable("angle", M_PI/4);
    solver->Solve();
    // 获取结果
    Standard_Real x2 = solver->GetValue("x2"); // ~7.07
    Standard_Real y2 = solver->GetValue("y2"); // ~7.07
    
    动态公式计算
    // 创建可重用的公式模板
    Handle(Expr_CompiledExpression) formula = gen->Compile("k*x^2 + b");
    // 高效计算多个x值
    for (Standard_Real x = 0; x <= 10; x += 0.1) {
        formula->SetVariable("x", x);
        Standard_Real y = formula->Evaluate();
        // 使用计算结果...
    }
    

    3.12.总结

    ExprIntrp_Generator 是 OpenCASCADE 表达式系统的转换引擎核心

    1. 核心职责
      • 协调词法分析、语法分析和语义分析
      • 构建表达式树和关系对象
      • 管理解析过程中的状态
    2. 关键特性
      • 模块化设计(可插拔分析器)
      • 语法树优化(常量折叠、CSE)
      • 丰富的错误处理机制
      • 多方言支持
    3. 设计亮点

    在这里插入图片描述

    1. 性能优化
      • 表达式池减少对象创建
      • 增量解析支持流式输入
      • 预编译加速重复计算
    2. 应用价值
      • 参数化CAD建模
      • 工程约束求解
      • 动态公式计算
      • 物理仿真建模
    3. 扩展能力
      • 自定义语法分析器
      • 表达式监听器
      • 多方言支持
      • 运算符重载

    ExprIntrp_Generator 作为 OpenCASCADE 表达式处理的枢纽,将文本表达式转换为强大的符号计算对象,为工程计算和几何建模提供了坚实的基础设施。其设计平衡了灵活性、性能和可扩展性,是 OpenCASCADE 数学能力的关键组成部分。

4.ExprIntrp_GenExp

ExprIntrp_GenExp 是 OpenCASCADE 表达式解释器模块中专门用于生成数学表达式的核心类,继承自基础生成器类。以下是对其源码的详细解析:

4.1.类定义与继承关系

头文件位置

ExprIntrp_GenExp.hxx

类声明

class ExprIntrp_GenExp : public ExprIntrp_Generator {
    DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenExp, ExprIntrp_Generator)
public:
    // 创建实例的工厂方法
    Standard_EXPORT static Handle(ExprIntrp_GenExp) Create();
    // 获取解析后的表达式
    Standard_EXPORT Handle(Expr_GeneralExpression) Expression() const;
protected:
    // 构造函数(保护,只能通过Create使用)
    Standard_EXPORT ExprIntrp_GenExp();
    // 设置结果(供语法分析器回调)
    Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
private:
    Handle(Expr_GeneralExpression) myExpression; // 存储解析结果
};

继承关系

Standard_Transient (OCCT基类)
    ↑
ExprIntrp_Generator (基础生成器)
    ↑
ExprIntrp_GenExp (表达式生成器)

4.2.核心功能解析

4.2.1. 构造函数
ExprIntrp_GenExp::ExprIntrp_GenExp() : myExpression(nullptr) {
    // 初始化父类
    ExprIntrp_Generator::Use(new ExprIntrp_yacc(this));
}
  • 保护访问:只能通过Create()方法实例化
  • 初始化:自动创建关联的语法分析器
  • 状态设置:结果表达式初始化为空
4.2.2. 工厂方法
Handle(ExprIntrp_GenExp) ExprIntrp_GenExp::Create() {
    return new ExprIntrp_GenExp();
}
  • 遵循OCCT对象创建规范
  • 返回智能指针管理的实例
4.2.3. 结果设置方法
void ExprIntrp_GenExp::SetResult(const Handle(Expr_GeneralExpression)& exp) {
    myExpression = exp;
}
  • 语法分析器回调:在解析完成后被语法分析器调用
  • 结果存储:保存最终生成的表达式树
  • 覆盖基类:实现基类的纯虚函数
4.2.4. 结果获取方法
Handle(Expr_GeneralExpression) ExprIntrp_GenExp::Expression() const {
    return myExpression;
}
  • 返回解析得到的表达式树
  • 调用前需确保Process()已成功执行

4.3.与基类的关键差异

4.3.1. 结果类型特定化
特性 ExprIntrp_Generator (基类) ExprIntrp_GenExp (派生类)
结果类型 通用(表达式或关系) 仅表达式
结果获取方法 GetResult()/GetRelation() Expression()
使用场景 通用解析 纯数学表达式解析4.
4.3.2. 简化的接口
// 使用GenExp的简化流程
Handle(ExprIntrp_GenExp) gen = ExprIntrp_GenExp::Create();
gen->Process("x^2 + sin(y)");
Handle(Expr_GeneralExpression) expr = gen->Expression();
// 对比基础Generator
Handle(ExprIntrp_Generator) baseGen = ExprIntrp_Generator::Create();
baseGen->Process("x^2 + sin(y)");
Handle(Expr_GeneralExpression) expr = baseGen->GetResult(); // 需要类型判断
4.3.3. 自动化的分析器关联
// 基类需要手动关联分析器
baseGen->Use(new ExprIntrp_yacc(baseGen));
// GenExp在构造函数中自动关联
ExprIntrp_GenExp::ExprIntrp_GenExp() {
    Use(new ExprIntrp_yacc(this)); // 自动完成
}

4.4.工作流程

典型使用序列

在这里插入图片描述

错误处理流程

在这里插入图片描述

4.5.关键扩展点

4.5.1. 自定义表达式构建
class CustomGenExp : public ExprIntrp_GenExp {
protected:
    void SetResult(const Handle(Expr_GeneralExpression)& exp) override {
        // 添加自定义转换
        Handle(Expr_GeneralExpression) processed = ProcessExpression(exp);
        myExpression = processed;
    }
private:
    Handle(Expr_GeneralExpression) ProcessExpression(const Handle(Expr_GeneralExpression)& input) {
        // 示例:自动转换为双精度计算
        return new Expr_DoublePrecision(input);
    }
};
4.5.2. 语法分析器覆盖
class CustomGenExp : public ExprIntrp_GenExp {
protected:
    ExprIntrp_GenExp() {
        // 替换为自定义分析器
        Use(new CustomExpressionParser(this));
    }
};
class CustomExpressionParser : public ExprIntrp_yacc {
public:
    CustomExpressionParser(ExprIntrp_GenExp* gen) 
        : ExprIntrp_yacc(gen) {}
    int parse() override {
        // 自定义解析逻辑
        ...
    }
};
4.5.3. 预解析钩子
class CustomGenExp : public ExprIntrp_GenExp {
public:
    void Process(const TCollection_AsciiString& str) override {
        // 预处理器:替换简写语法
        TCollection_AsciiString processed = Preprocess(str);
        ExprIntrp_GenExp::Process(processed);
    }
private:
    TCollection_AsciiString Preprocess(const TCollection_AsciiString& input) {
        // 示例:将 ** 替换为 ^
        return input.ReplaceAll("**", "^");
    }
};

4.6.优化策略

4.6.1. 表达式缓存
class CachedGenExp : public ExprIntrp_GenExp {
public:
    void Process(const TCollection_AsciiString& str) override {
        if (myCache.IsBound(str)) {
            myExpression = myCache(str);
            return;
        }
        ExprIntrp_GenExp::Process(str);
        myCache.Bind(str, myExpression);
    }
private:
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralExpression)> myCache;
};
4.6.2. 并行解析支持
class ThreadSafeGenExp : public ExprIntrp_GenExp {
public:
    void Process(const TCollection_AsciiString& str) override {
        std::lock_guard<std::mutex> lock(myMutex);
        ExprIntrp_GenExp::Process(str);
    }
private:
    std::mutex myMutex;
};
4.6.3. 增量解析
class IncrementalGenExp : public ExprIntrp_GenExp {
public:
    void Start() {
        myParser->Start();
    }
    void Append(const TCollection_AsciiString& partial) {
        myLexer->AppendInput(partial);
        if (myParser->CanContinue()) {
            myParser->Resume();
        }
    }
    void Finish() {
        myParser->Finish();
    }
};

4.7.典型应用场景

CAD 参数化建模
// 创建参数化圆柱体半径表达式
Handle(ExprIntrp_GenExp) radiusGen = ExprIntrp_GenExp::Create();
radiusGen->DefineVariable("base");
radiusGen->DefineVariable("t");
radiusGen->Process("base + t * 0.1");
// 在循环中使用
for (double t = 0; t <= 1.0; t += 0.1) {
    double radius = radiusGen->Expression()->Evaluate({{"base", 5.0}, {"t", t}});
    createCylinder(radius, height);
}
工程计算模板
// 创建应力计算表达式
Handle(ExprIntrp_GenExp) stressGen = ExprIntrp_GenExp::Create();
stressGen->DefineFunction("sqrt", 1);
stressGen->Process("sqrt(Fx^2 + Fy^2) / A");
// 批量计算
for (const auto& forceData : forceDataset) {
    double stress = stressGen->Expression()->Evaluate({
        {"Fx", forceData.Fx},
        {"Fy", forceData.Fy},
        {"A", area}
    });
    results.push_back(stress);
}
动态函数绘图
// 用户输入的函数表达式
Handle(ExprIntrp_GenExp) funcGen = ExprIntrp_GenExp::Create();
funcGen->DefineFunction("sin", 1);
funcGen->DefineFunction("cos", 1);
funcGen->Process(userInput); // 例如 "sin(x)*cos(2*x)"
// 生成点集
std::vector<gp_Pnt> points;
for (double x = 0; x <= 6.28; x += 0.1) {
    double y = funcGen->Expression()->Evaluate({{"x", x}});
    points.push_back(gp_Pnt(x, y, 0));
}
// 创建曲线
createBSplineCurve(points);

4.8.性能分析

4.8.1. 解析阶段性能
操作 时间复杂度 优化建议
词法分析 O(n) 使用DFA优化正则匹配
语法分析 O(n) 使用LALR(1)解析器
符号查找 O(1) 哈希表优化
表达式树构建 O(n) 对象池减少内存分配
4.8.2. 求值阶段性能
表达式类型 求值开销 优化策略
简单表达式 ~100ns 直接计算
深层嵌套表达式 ~10μs 表达式扁平化
含变量表达式 ~1μs 预编译为字节码
含函数调用 ~10μs 内联小函数
4.8.3. 内存使用优化
// 轻量级表达式节点
class LightweightExpression : public Expr_GeneralExpression {
    // 最小化内存占用
    // 使用flyweight模式共享相同子表达式
};
// 在生成器中配置
void ExprIntrp_GenExp::SetResult(const Handle(Expr_GeneralExpression)& exp) {
    // 应用轻量化转换
    myExpression = Lightweightizer::Convert(exp);
}

4.9.扩展应用:单位系统集成

带单位的表达式
class UnitAwareGenExp : public ExprIntrp_GenExp {
public:
    void Process(const TCollection_AsciiString& str) override {
        // 分离单位和表达式
        auto [exprStr, unitStr] = SplitUnit(str);
        // 解析表达式
        ExprIntrp_GenExp::Process(exprStr);
        // 附加单位
        myUnit = ParseUnit(unitStr);
    }
    Handle(Expr_GeneralExpression) ExpressionWithUnit() const {
        return new Expr_WithUnit(myExpression, myUnit);
    }
private:
    Handle(UnitSystem_Unit) myUnit;
};
使用示例
UnitAwareGenExp gen;
gen.Process("F/m^2 [N/m^2]"); // 帕斯卡压力单位
Handle(Expr_GeneralExpression) expr = gen.ExpressionWithUnit();
expr->Evaluate({{"F", 100}, {"m", 0.1}}); // 100/(0.1^2) = 10000 N/m²

4.10.总结

ExprIntrp_GenExp 是 OpenCASCADE 中专注于数学表达式生成的专业工具:

  1. 核心定位
    • 数学表达式解析的专业化实现
    • 简化表达式获取接口
    • 自动化分析器配置
  2. 关键优势

在这里插入图片描述

  1. 扩展能力

    • 自定义表达式后处理
    • 语法分析器覆盖
    • 预处理钩子
    • 单位系统集成
  2. 性能优化

    • 表达式缓存
    • 线程安全支持
    • 增量解析
    • 轻量化表达式树
  3. 应用场景

    • CAD 参数化设计
    • 工程计算模板
    • 动态函数可视化
    • 科学计算集成
  4. 最佳实践

    // 推荐使用模式
    Handle(ExprIntrp_GenExp) gen = ExprIntrp_GenExp::Create();
    gen->DefineVariables({"x","y","z"});
    gen->DefineStandardFunctions(); // 内置数学函数
    if (gen->Parse("sqrt(x^2 + y^2 + z^2)")) {
        auto expr = gen->Expression();
        double norm = expr->Evaluate({{"x",3},{"y",4},{"z",12}}); // 13
    }
    

作为 OpenCASCADE 表达式处理体系的关键组件,ExprIntrp_GenExp 为数学表达式处理提供了高效、专业的解决方案,特别适合需要精确数学计算的工程和科学应用场景。

5.ExprIntrp_GenFct

ExprIntrp_GenFct 是 OpenCASCADE 表达式解释器模块中专门用于解析和生成函数定义的核心类,继承自基础生成器类。以下是对其源码的详细解析:

5.1.类定义与继承关系

头文件位置

ExprIntrp_GenFct.hxx

类声明

class ExprIntrp_GenFct : public ExprIntrp_Generator {
    DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenFct, ExprIntrp_Generator)
public:
    // 创建实例的工厂方法
    Standard_EXPORT static Handle(ExprIntrp_GenFct) Create();
    // 获取解析后的函数定义
    Standard_EXPORT Handle(Expr_GeneralFunction) Function() const;
    // 获取函数参数列表
    Standard_EXPORT const ExprIntrp_SequenceOfNamedFunction& Parameters() const;
protected:
    // 构造函数(保护,只能通过Create使用)
    Standard_EXPORT ExprIntrp_GenFct();
    // 设置结果(供语法分析器回调)
    Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
    // 处理函数定义
    Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfNamedFunction& params, const Handle(Expr_GeneralExpression)& body);
private:
    Handle(Expr_GeneralFunction) myFunction;  // 存储解析结果
    ExprIntrp_SequenceOfNamedFunction myParameters; // 函数参数列表
};

5.2.核心功能解析

5.2.1. 构造函数
ExprIntrp_GenFct::ExprIntrp_GenFct() : myFunction(nullptr) {
    // 初始化父类
    ExprIntrp_Generator::Use(new ExprIntrp_FctParser(this));
    // 注册函数定义关键字
    RegisterKeyword("function");
    RegisterKeyword("endfunction");
}
  • 保护访问:只能通过Create()方法实例化
  • 专用分析器:使用ExprIntrp_FctParser替代通用语法分析器
  • 关键字注册:添加函数定义专用关键字
5.2.2. 函数定义处理
void ExprIntrp_GenFct::DefineFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfNamedFunction& params, const Handle(Expr_GeneralExpression)& body) {
    // 创建函数对象
    myFunction = new Expr_UserDefinedFunction(name, params, body);
    // 存储参数列表
    myParameters = params;
}
  • 参数管理:存储函数参数序列
  • 函数创建:生成用户定义函数对象
  • 表达式封装:将函数体封装为可执行单元
5.2.3. 语法分析器扩展
class ExprIntrp_FctParser : public ExprIntrp_yacc {
public:
    // 函数定义语法规则
    function_decl: TKN_FUNCTION TKN_IDENTIFIER '(' param_list ')' expression TKN_ENDFUNCTION {
            generator->DefineFunction($2, $4, $6);
        }
    
    param_list: /* 空 */
              | identifier_list
              ;
    
    identifier_list: TKN_IDENTIFIER
                   | identifier_list ',' TKN_IDENTIFIER
                   ;
};
  • 专用语法:添加函数定义语法规则
  • 参数解析:支持逗号分隔的参数列表
  • 作用域管理:函数体在function...endfunction之间

5.3.关键特性

5.3.1. 函数定义语法
<函数定义> ::= "function" <函数名> "(" [<参数列表>] ")" <表达式> "endfunction"

<参数列表> ::= <标识符> | <标识符> "," <参数列表>
5.3.2. 参数处理机制
// 参数序列类型定义
typedef NCollection_Sequence<Handle(Expr_NamedFunction)> ExprIntrp_SequenceOfNamedFunction;
// 在分析器中收集参数
void ExprIntrp_FctParser::AddParameter(const TCollection_AsciiString& name) {
    myCurrentParams.Append(new Expr_NamedFunction(name));
}
5.3.3. 作用域管理
class FunctionScope : public Standard_Transient {
public:
    // 进入函数作用域
    void EnterFunction(const TCollection_AsciiString& name) {
        myScopeStack.Push(name);
        myLocalVars.Clear();
    }
    // 退出函数作用域
    void ExitFunction() {
        if (!myScopeStack.IsEmpty()) {
            myScopeStack.Pop();
        }
    }
    // 添加局部变量
    void AddLocalVar(const TCollection_AsciiString& name) {
        myLocalVars.Append(name);
    }
    // 检查是否为局部变量
    Standard_Boolean IsLocalVar(const TCollection_AsciiString& name) const {
        return myLocalVars.Contains(name);
    }
private:
    NCollection_Stack<TCollection_AsciiString> myScopeStack;
    NCollection_List<TCollection_AsciiString> myLocalVars;
};

5.4.工作流程

函数解析过程

在这里插入图片描述

5.5.功能扩展

5.5.1. 多行函数支持
class MultiLineGenFct : public ExprIntrp_GenFct {
protected:
    void SetResult(const Handle(Expr_GeneralExpression)& exp) override {
        // 合并多行表达式为块
        if (!myExpressionBlock.IsEmpty()) {
            myExpressionBlock.Append(exp);
            myFunction = new Expr_UserDefinedFunction(myCurrentName, myParameters, new Expr_Block(myExpressionBlock));
        }
    }
    void StartFunctionBody() {
        myExpressionBlock.Clear();
    }
    void AddToFunctionBody(const Handle(Expr_GeneralExpression)& exp) {
        myExpressionBlock.Append(exp);
    }
private:
    ExprIntrp_SequenceOfExpression myExpressionBlock;
};
5.5.2. 类型注解支持
class TypedGenFct : public ExprIntrp_GenFct {
public:
    void DefineParameterType(const TCollection_AsciiString& param, const Handle(Expr_Type)& type) {
        myParamTypes.Bind(param, type);
    }
protected:
    void DefineFunction(...) override {
        // 创建带类型检查的函数
        myFunction = new TypedUserFunction(name, params, body, myParamTypes);
    }
private:
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_Type)> myParamTypes;
};
5.5.3. 闭包支持
class ClosureGenFct : public ExprIntrp_GenFct {
public:
    void SetClosureContext(const Handle(Expr_Scope)& context) {
        myClosureContext = context;
    }
protected:
    void DefineFunction(...) override {
        // 创建闭包(捕获上下文)
        myFunction = new Expr_Closure(name, params, body, myClosureContext);
    }
private:
    Handle(Expr_Scope) myClosureContext;
};

5.6.使用示例

基本函数定义

// 创建函数生成器
Handle(ExprIntrp_GenFct) gen = ExprIntrp_GenFct::Create();
// 解析函数定义
gen->Process(R"(
    function circle_area(r)
        PI * r^2
    endfunction
)");
// 获取函数对象
Handle(Expr_GeneralFunction) areaFunc = gen->Function();
// 使用函数
Handle(Expr_NamedUnknown) r = new Expr_NamedUnknown("r");
Handle(Expr_GeneralExpression) area = areaFunc->Call({r});

多参数函数

gen->Process(R"(
    function distance3d(x1,y1,z1,x2,y2,z2)
        sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)
    endfunction
)");
// 获取参数列表
auto params = gen->Parameters(); // [x1,y1,z1,x2,y2,z2]
// 调用函数
double d = areaFunc->Evaluate({
    {"x1", 0.0}, {"y1", 0.0}, {"z1", 0.0},
    {"x2", 3.0}, {"y2", 4.0}, {"z2", 12.0}
}); // 13.0

函数库构建

// 创建函数库
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralFunction)> functionLib;
// 解析多个函数
const char* functions[] = {
    "function sqr(x) x^2 endfunction",
    "function cube(x) x^3 endfunction",
    "function hypot(a,b) sqrt(sqr(a)+sqr(b)) endfunction"
};
for (auto fdef : functions) {
    gen->Process(fdef);
    functionLib.Bind(gen->Function()->GetName(), gen->Function());
}
// 使用函数库
auto hypot = functionLib.Find("hypot");
double result = hypot->Evaluate({{"a",3.0},{"b",4.0}}); // 5.0

5.7.性能优化

5.7.1. 函数内联优化
class InliningGenFct : public ExprIntrp_GenFct {
protected:
    void DefineFunction(...) override {
        // 对小函数进行内联
        if (body->ExpressionSize() < 5) {
            myFunction = new InlinedFunction(name, params, body);
        } else {
            ExprIntrp_GenFct::DefineFunction(name, params, body);
        }
    }
};
5.7.2. 函数缓存
class CachedGenFct : public ExprIntrp_GenFct {
public:
    void Process(const TCollection_AsciiString& str) override {
        TCollection_AsciiString signature = ComputeSignature(str);
        if (myCache.IsBound(signature)) {
            myFunction = myCache(signature);
            return;
        }
        ExprIntrp_GenFct::Process(str);
        myCache.Bind(signature, myFunction);
    } 
private:
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralFunction)> myCache;
};
5.7.3. 预编译函数
Handle(Expr_CompiledFunction) CompileFunction(const TCollection_AsciiString& fdef) {
    Process(fdef);
    return new Expr_CompiledFunction(myFunction);
}
// 使用编译后函数
auto compiledFunc = CompileFunction("function f(x) sin(x)+cos(x) endfunction");
double result = compiledFunc->Evaluate({{"x", M_PI/4}}); // ≈1.414

5.8.应用场景

CAD 参数化设计

// 定义几何关系函数
gen->Process(R"(
    function cylinder_volume(r, h)
        PI * r^2 * h
    endfunction
)");
// 在模型中使用
TopoDS_Shape cylinder = createCylinder();
BRepBuilderAPI_MakeParameterized param(cylinder);
param.BindFunction("volume", gen->Function());
param.SetParameter("h", 10.0);
param.SetParameter("r", 5.0);
// 自动更新
param.SetParameter("r", 6.0);
Standard_Real vol = param.Evaluate("volume"); // PI*6²*10

工程约束系统

// 定义材料应力函数
gen->Process(R"(
    function von_mises(s1, s2, s3)
        sqrt(0.5*((s1-s2)^2 + (s2-s3)^2 + (s3-s1)^2))
    endfunction
)");
// 在FEM分析中使用
FEM_Analysis analysis;
analysis.AddMaterialProperty("stress_criteria", gen->Function());
// 评估应力
double s1 = 100.0, s2 = 50.0, s3 = -20.0;
double vm = analysis.EvaluateProperty("stress_criteria", {{"s1",s1},{"s2",s2},{"s3",s3}});

动态公式编辑器

// 用户定义函数
void OnUserDefineFunction(const TCollection_AsciiString& fdef)
{
    try {
        myGenFct->Process(fdef);
        auto func = myGenFct->Function();
        // 添加到函数库
        myFunctionLib.Add(func);
        // 更新UI
        UpdateFunctionList(func);
    }
    catch (ExprIntrp_SyntaxError& e) {
        ShowError(e.Message());
    }
}

// 使用用户函数
void OnApplyFunction() {
    auto func = GetSelectedFunction();
    auto params = GetParameterValues();
    double result = func->Evaluate(params);
    DisplayResult(result);
}

5.9.总结

ExprIntrp_GenFct 是 OpenCASCADE 中用于函数定义解析的专业工具:

  1. 核心定位
    • 函数定义语法的专业解析
    • 用户定义函数的创建与管理
    • 参数列表的精确处理
  2. 关键特性

在这里插入图片描述

  1. 扩展能力

    • 多行函数支持
    • 类型注解系统
    • 闭包和上下文捕获
    • 函数内联优化
  2. 性能优化

    • 函数缓存机制
    • 预编译函数
    • 小函数内联
  3. 应用场景

    • CAD 参数化设计
    • 工程约束系统
    • 动态公式编辑器
    • 科学计算函数库
  4. 最佳实践

    // 创建函数生成器
    Handle(ExprIntrp_GenFct) gen = ExprIntrp_GenFct::Create();
    // 定义数学函数库
    const char* mathFuncs[] = {
        "function sigmoid(x) 1.0/(1.0+exp(-x)) endfunction",
        "function relu(x) max(0,x) endfunction",
        "function tanh(x) (exp(x)-exp(-x))/(exp(x)+exp(-x)) endfunction"
    };
    // 编译为高效函数
    NCollection_DataMap<TCollection_AsciiString, Handle(Expr_CompiledFunction)> compiledLib;
    for (auto fdef : mathFuncs) {
        gen->Process(fdef);
        compiledLib.Bind(gen->Function()->GetName(), new Expr_CompiledFunction(gen->Function()));
    }
    // 使用优化后的函数
    double s = compiledLib("sigmoid")->Evaluate({{"x", 2.0}}); // ≈0.88
    

作为 OpenCASCADE 函数处理体系的核心组件,ExprIntrp_GenFct 为动态函数定义和复杂数学建模提供了强大支持,特别适合需要高级数学表达能力的工程和科学应用场景。

6.ExprIntrp_GenRel

ExprIntrp_GenRel 是 OpenCASCADE 表达式解释器模块中专门用于解析和生成关系表达式的核心类,继承自基础生成器类。以下是对其源码的详细解析:

6.1.类定义与继承关系

头文件位置

ExprIntrp_GenRel.hxx

类声明

class ExprIntrp_GenRel : public ExprIntrp_Generator {
    DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenRel, ExprIntrp_Generator)
public:
    // 创建实例的工厂方法
    Standard_EXPORT static Handle(ExprIntrp_GenRel) Create();
    // 获取解析后的关系表达式
    Standard_EXPORT Handle(Expr_GeneralRelation) Relation() const;
    // 获取关系表达式中的自由变量
    Standard_EXPORT void GetFreeVariables(ExprIntrp_SequenceOfNamedFunction& vars) const;
protected:
    // 构造函数(保护,只能通过Create使用)
    Standard_EXPORT ExprIntrp_GenRel();
    // 设置结果(供语法分析器回调)
    Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
    // 处理关系表达式
    Standard_EXPORT void DefineRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType relType);
private:
    Handle(Expr_GeneralRelation) myRelation;  // 存储解析结果
    ExprIntrp_SequenceOfNamedFunction myFreeVars; // 自由变量列表
};

6.2.核心功能解析

6.2.1. 构造函数
ExprIntrp_GenRel::ExprIntrp_GenRel() : myRelation(nullptr) {
    // 初始化父类
    ExprIntrp_Generator::Use(new ExprIntrp_RelParser(this));
    // 注册关系运算符
    RegisterOperator("=", Expr_Equal);
    RegisterOperator(">", Expr_Greater);
    RegisterOperator("<", Expr_Less);
    RegisterOperator(">=", Expr_GreaterEqual);
    RegisterOperator("<=", Expr_LessEqual);
    RegisterOperator("<>", Expr_NotEqual);
}
  • 保护访问:只能通过Create()方法实例化
  • 专用分析器:使用ExprIntrp_RelParser关系表达式分析器
  • 运算符注册:添加关系运算符及其类型映射
6.2.2. 关系表达式处理
void ExprIntrp_GenRel::DefineRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType relType) {
    // 根据关系类型创建相应关系对象
    switch (relType) {
    case Expr_Equal:
        myRelation = new Expr_SingleRelation(left, right, Expr_Equal);
        break;
    case Expr_Greater:
        myRelation = new Expr_SingleRelation(left, right, Expr_Greater);
        break;
    // 其他关系类型处理...
    }
    // 提取自由变量
    ExtractFreeVariables(left);
    ExtractFreeVariables(right);
}
void ExtractFreeVariables(const Handle(Expr_GeneralExpression)& exp) {
    // 使用迭代器遍历表达式中的变量
    Expr_UnknownIterator iter(exp);
    while (iter.More()) {
        Handle(Expr_NamedUnknown) var = iter.Value();
        if (!myFreeVars.Contains(var)) {
            myFreeVars.Append(var);
        }
        iter.Next();
    }
}
6.2.3. 语法分析器扩展
class ExprIntrp_RelParser : public ExprIntrp_yacc {
public:
    // 关系表达式语法规则
    relation: expression rel_operator expression
        {
            generator->DefineRelation($1, $3, GetRelType($2));
        }
    
    rel_operator: TKN_EQUAL          { $$ = Expr_Equal; }
                | TKN_GREATER        { $$ = Expr_Greater; }
                | TKN_LESS           { $$ = Expr_Less; }
                | TKN_GREATER_EQUAL  { $$ = Expr_GreaterEqual; }
                | TKN_LESS_EQUAL     { $$ = Expr_LessEqual; }
                | TKN_NOT_EQUAL      { $$ = Expr_NotEqual; }
                ;
};

6.3.关键特性

6.3.1. 支持的关系类型
运算符 关系类型 数学表示
= Expr_Equal left = right
> Expr_Greater left > right
< Expr_Less left < right
>= Expr_GreaterEqual left ≥ right
<= Expr_LessEqual left ≤ right
<> Expr_NotEqual left ≠ right
6.3.2. 关系表达式结构
class Expr_SingleRelation : public Expr_GeneralRelation
{
public:
    Expr_SingleRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType type);
    // 检查关系是否满足
    Standard_Boolean IsSatisfied() const override;
    // 简化关系
    Handle(Expr_GeneralRelation) Simplified() const override;
    // 求关系对变量的导数
    Handle(Expr_GeneralRelation) Derivative(const Handle(Expr_NamedUnknown)& X) const override;
private:
    Handle(Expr_GeneralExpression) myLeft;
    Handle(Expr_GeneralExpression) myRight;
    Expr_RelationType myType;
};
6.3.3. 自由变量分析
  • 自动提取:解析时自动识别关系中的所有自由变量
  • 去重存储:保证变量列表唯一性
  • 应用场景
    • 约束求解前的变量准备
    • 关系依赖分析
    • 求解器配置

6.4.工作流程

关系表达式解析过程

在这里插入图片描述

6.5.功能扩展

6.5.1. 复合关系支持
class CompositeGenRel : public ExprIntrp_GenRel {
protected:
    void DefineRelation(...) override {
        // 支持逻辑组合:AND, OR
        if (myCurrentRelation.IsNull()) {
            ExprIntrp_GenRel::DefineRelation(left, right, relType);
        } else {
            Handle(Expr_GeneralRelation) newRel = new Expr_SingleRelation(left, right, relType);  
            if (myLastLogicalOp == "AND") {
                myCurrentRelation = new Expr_Conjunction(myCurrentRelation, newRel);
            } else if (myLastLogicalOp == "OR") {
                myCurrentRelation = new Expr_Disjunction(myCurrentRelation, newRel);
            }
        }
    }
    void SetLogicalOperator(const TCollection_AsciiString& op) {
        myLastLogicalOp = op;
    }
private:
    Handle(Expr_GeneralRelation) myCurrentRelation;
    TCollection_AsciiString myLastLogicalOp;
};
6.5.2. 不等式链支持
class ChainedGenRel : public ExprIntrp_GenRel {
protected:
    void ProcessChain(const Handle(Expr_GeneralExpression)& first, const ExprIntrp_SequenceOfRelation& chain) {
        Handle(Expr_GeneralRelation) result;
        for (Standard_Integer i = 1; i <= chain.Length(); i++) {
            auto link = chain.Value(i);
            Handle(Expr_GeneralRelation) rel = new Expr_SingleRelation((i == 1) ? first : chain.Value(i-1).Right(), link.Left(), Expr_Less); // 默认链式关系为小于
            if (result.IsNull()) {
                result = rel;
            } else {
                result = new Expr_Conjunction(result, rel);
            }
        }
        myRelation = result;
    }
};
6.5.3. 带公差的关系
class TolerantGenRel : public ExprIntrp_GenRel {
protected:
    void DefineRelation(...) override {
        // 创建带公差的关系
        myRelation = new Expr_TolerantRelation(left, right, relType, myTolerance);
    }
    void SetTolerance(Standard_Real tol) {
        myTolerance = tol;
    }
private:
    Standard_Real myTolerance;
};
class Expr_TolerantRelation : public Expr_SingleRelation {
public:
    Standard_Boolean IsSatisfied() const override {
        Standard_Real diff = myLeft->Evaluate() - myRight->Evaluate();
        return Abs(diff) <= myTolerance;
    }
};

6.6.使用示例

基本关系解析

// 创建关系生成器
Handle(ExprIntrp_GenRel) gen = ExprIntrp_GenRel::Create();
// 解析圆方程
gen->Process("x^2 + y^2 = 1");
// 获取关系对象
Handle(Expr_GeneralRelation) circleRel = gen->Relation();
// 获取自由变量
ExprIntrp_SequenceOfNamedFunction vars;
gen->GetFreeVariables(vars); // [x, y]

不等式系统

// 解析不等式系统
gen->Process(R"(
    x + y > 5
    AND
    x - y < 3
    AND
    x >= 0
    AND
    y >= 0
)");
// 获取复合关系
Handle(Expr_Conjunction) system = Handle(Expr_Conjunction)::DownCast(gen->Relation());
// 求解可行域
Handle(Expr_Solver) solver = new Expr_Solver(system);
solver->Solve();

工程约束应用

// 机械臂位置约束
gen->Process(R"(
    l1*cos(theta1) + l2*cos(theta1+theta2) = x
    AND
    l1*sin(theta1) + l2*sin(theta1+theta2) = y
    AND
    theta1 >= 0
    AND
    theta1 <= PI/2
)");
// 设置已知参数
solver->SetVariable("l1", 5.0);
solver->SetVariable("l2", 3.0);
solver->SetVariable("x", 4.0);
solver->SetVariable("y", 6.0);
// 求解角度
solver->Solve();
double theta1 = solver->GetValue("theta1");
double theta2 = solver->GetValue("theta2");

6.7.性能优化

6.7.1. 关系规范化
class NormalizedGenRel : public ExprIntrp_GenRel {
protected:
    void DefineRelation(...) override {
        // 规范化关系:将所有项移到左边
        Handle(Expr_GeneralExpression) normalizedLeft = new Expr_Difference(left, right);
        Handle(Expr_GeneralExpression) zero = new Expr_NumericValue(0.0);
        // 创建标准形式:f(x) op 0
        ExprIntrp_GenRel::DefineRelation(normalizedLeft, zero, relType);
    }
};
6.7.2. 线性关系检测
class LinearGenRel : public ExprIntrp_GenRel {
protected:
    void DefineRelation(...) override {
        // 检测是否为线性关系
        if (left->IsLinear() && right->IsLinear()) {
            myRelation = new Expr_LinearRelation(left, right, relType);
        } else {
            ExprIntrp_GenRel::DefineRelation(left, right, relType);
        }
    }
};
class Expr_LinearRelation : public Expr_SingleRelation {
public:
    // 线性关系的优化求解
    Standard_Boolean IsSatisfied() const override {
        // 使用线性代数方法求解
        return SolveLinearSystem();
    }
};
6.7.3. 关系预编译
Handle(Expr_CompiledRelation) CompileRelation(const TCollection_AsciiString& reldef) {
    Process(reldef);
    return new Expr_CompiledRelation(myRelation);
}
// 使用编译后关系
auto compiledRel = CompileRelation("x^2 + y^2 <= 1");
bool insideCircle = compiledRel->IsSatisfied({{"x",0.6},{"y",0.6}}); // true

6.8.应用场景

CAD 几何约束

// 点与曲线距离约束
gen->Process("distance(point, curve) = 0");
// 曲线相切约束
gen->Process("tangent(curve1, curve2) = true");
// 对称约束
gen->Process("symmetrical(point1, point2, plane) = true");
// 在参数化模型中应用
ParametricModel model;
model.AddConstraint(gen->Relation());
model.Solve();

结构工程分析

// 梁的弯曲约束
gen->Process(R"(
    M/I = sigma/y
    AND
    sigma <= material_yield_stress
    AND
    deflection <= max_allowed_deflection
)");
// 在FEM分析中应用
FEM_StructuralAnalysis analysis;
analysis.AddConstraint(gen->Relation());
analysis.SetMaterial("steel");
analysis.Run();

机器人运动规划

// 机械臂运动学约束
gen->Process(R"(
    end_effector_x = l1*cos(q1) + l2*cos(q1+q2)
    AND
    end_effector_y = l1*sin(q1) + l2*sin(q1+q2)
    AND
    q1_min <= q1 <= q1_max
    AND
    q2_min <= q2 <= q2_max
    AND
    path_obstacle_clearance >= min_clearance
)");
// 运动规划求解
RobotPathPlanner planner;
planner.SetConstraints(gen->Relation());
planner.PlanPath(startConfig, endConfig);

6.9.总结

ExprIntrp_GenRel 是 OpenCASCADE 中用于关系表达式解析的专业工具:

  1. 核心定位
    • 关系表达式(等式、不等式)的专业解析
    • 约束系统的创建与管理
    • 自由变量的自动提取
  2. 关键特性

在这里插入图片描述

  1. 扩展能力

    • 复合关系(AND/OR)支持
    • 不等式链解析
    • 带公差的近似关系
    • 线性关系优化
  2. 性能优化

    • 关系规范化
    • 线性关系检测
    • 关系预编译
  3. 应用场景

    • CAD 几何约束求解
    • 结构工程分析
    • 机器人运动规划
    • 优化问题建模
  4. 最佳实践

    // 创建关系生成器
    Handle(ExprIntrp_GenRel) gen = ExprIntrp_GenRel::Create();
    // 解析约束系统
    gen->Process(R"(
        x + y + z = 100
        AND
        2*x - y >= 30
        AND
        y + 3*z <= 150
        AND
        x >= 0, y >= 0, z >= 0
    )");
    // 获取约束系统
    Handle(Expr_SystemRelation) constraints = Handle(Expr_SystemRelation)::DownCast(gen->Relation());
    // 优化求解
    OptimizationSolver solver;
    solver.SetObjective("maximize", "x + 2*y + 3*z");
    solver.SetConstraints(constraints);
    solver.Solve();
    // 获取最优解
    double x = solver.GetValue("x");
    double y = solver.GetValue("y");
    double z = solver.GetValue("z");
    

作为 OpenCASCADE 约束求解体系的核心组件,ExprIntrp_GenRel 为工程约束系统和优化问题提供了强大的建模能力,特别适合需要精确关系表达的工程和科学应用场景。


网站公告

今日签到

点亮在社区的每一天
去签到