用其他符号表重新计算Boost Spirit解析的属性的最有效方法是什么? [英] What is the most efficient way to recalculate attributes of a Boost Spirit parse with a different symbol table?

查看:132
本文介绍了用其他符号表重新计算Boost Spirit解析的属性的最有效方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Boost Spirit在某些软件中实现功能,该功能允许用户输入数学方程式,该方程式将反复应用于输入流.输入流值使用boost::spirit::qi::symbols表示为符号,用户可以在公式中引用. (例如out1 = 3 * in1 + in2)

I'm using Boost Spirit to implement functionality in some software that allows the user to enter a mathematical equation that will be repeatedly applied to an input stream. Input stream values are represented as symbols using boost::spirit::qi::symbols which the user can reference in their equation. (e.g. out1 = 3 * in1 + in2)

解析和编译用户方程对性能不敏感,但计算它的输出值是因为它构成了时间紧迫的管道的一部分.

Parsing and compiling the user's equation is not performance sensitive but calculating its output value is as it forms part of a time-critical pipeline.

Spirit在文档中使用的标准方式是在解析输入时计算其输出(属性).但是,由于在每次计算之间仅符号的属性值(out1in1等)将发生变化,因此可能存在一种更有效的方法来实现此目的,可能是通过缓存抽象语法树表达式并在表达式中反复进行.

The standard way Spirit is used within the documentation is to calculate the output (attribute) of an input as it is parsed. However, as between each calculation only the attribute values of the symbols (out1, in1, etc.) will have changed, it feels like there might be a more efficient way to achieve this, perhaps by caching the abstract syntax tree of the expression and reiterating through it.

在给定一组新的符号值的情况下,重新计算此(固定)方程式的值的最有效方法是什么?

What is the most efficient way to recalculate the value of this (fixed) equation given a new set of symbol values?

推荐答案

Spirit的标准使用方式并不像您想象的那样受限制.

The standard way Spirit is used is not as limited as you seem to think.

虽然可以使用它来即时计算即时值,但是在输出属性中 build AST树通常更为常见,可以对其进行转换(简化,优化)和解释(例如发出虚拟机,甚至汇编指令).

While you can use it to calulate an immediate value on the fly, it is much more usual to build an AST tree in the output attribute, that can be transformed (simplified, optimized) and interpreted (e.g. emitting virtual machine or even assembly instructions).

完整的编译器教程对此进行了展示,但是计算器示例与您所寻找的非常接近:

The compiler tutorials show this in full fledged, but the calculator samples are very close to what you seem to be looking for: http://www.boost.org/doc/libs/1_55_0/libs/spirit/example/qi/compiler_tutorial/

  • calc1 in example/qi/compiler_tutorial/calc1.cpp

展示语法的普通计算器示例.解析器是一种语法 仅检查器,不进行任何语义评估.

Plain calculator example demonstrating the grammar. The parser is a syntax checker only and does not do any semantic evaluation.

calc2 在example/qi/compiler_tutorial/calc2.cpp

calc2 in example/qi/compiler_tutorial/calc2.cpp

一个计算器示例,使用演示语法和语义动作 普通功能.解析器打印适用于基于堆栈的虚拟机的代码 机器.

A Calculator example demonstrating the grammar and semantic actions using plain functions. The parser prints code suitable for a stack based virtual machine.

calc3 在example/qi/compiler_tutorial/calc3.cpp

calc3 in example/qi/compiler_tutorial/calc3.cpp

一个计算器示例,使用演示语法和语义动作 凤凰做实际表达评价.解析器本质上是 口译员"即时评估表达式.

A calculator example demonstrating the grammar and semantic actions using phoenix to do the actual expression evaluation. The parser is essentially an "interpreter" that evaluates expressions on the fly.

这是您感兴趣的地方,因为它在解析期间停止进行计算:

Here's where it gets interesting for you, since it stops doing the calculations during parsing:

  • calc4 在example/qi/compiler_tutorial/calc4.cpp

  • calc4 in example/qi/compiler_tutorial/calc4.cpp

一个计算器示例,演示AST的生成.一次,AST 创建,遍历

A Calculator example demonstrating generation of AST. The AST, once created, is traversed,

  1. 要打印其内容和
  2. 评估结果.

  • calc5 在example/qi/compiler_tutorial/calc5.cpp

  • calc5 in example/qi/compiler_tutorial/calc5.cpp

    这次与Calc4相同,我们将合并调试支持以及错误 处理和报告.

    Same as Calc4, this time, we'll incorporate debugging support, plus error handling and reporting.

    calc6 在example/qi/compiler_tutorial/calc6.cpp

    calc6 in example/qi/compiler_tutorial/calc6.cpp

    还有另一个计算器示例!这次,我们将编译为一个简单的 虚拟机.这实际上是第一个Spirit示例 大约在2000年.现在,它已移植到Spirit2.

    Yet another calculator example! This time, we will compile to a simple virtual machine. This is actually one of the very first Spirit example circa 2000. Now, it's ported to Spirit2.

    calc7 在example/qi/compiler_tutorial/calc7/main.cpp

    calc7 in example/qi/compiler_tutorial/calc7/main.cpp

    现在,我们将介绍变量和赋值.这次,我们也将 重命名一些规则-一种更大计划的策略;-)

    Now we'll introduce variables and assignment. This time, we'll also be renaming some of the rules -- a strategy for a grander scheme to come ;-)

    此版本还展示了语法模块化.在这里,您将看到 表达式和语句被构建为模块化语法.

    This version also shows off grammar modularization. Here you will see how expressions and statements are built as modular grammars.

    calc8 在example/qi/compiler_tutorial/calc8/main.cpp

    calc8 in example/qi/compiler_tutorial/calc8/main.cpp

    现在,我们将介绍布尔表达式和控件结构.是吗 现在很明显我们在做什么? ;-)

    Now we'll introduce boolean expressions and control structures. Is it obvious now what we are up to? ;-)

    我相信您会在本教程结束时找到很多灵感!

    I'm sure you'll find lots of inspiration towards the end of the tutorial!

    这篇关于用其他符号表重新计算Boost Spirit解析的属性的最有效方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆