提升语义操作导致解析问题

2023-12-02

我一直在使用 Boost mini 编译器示例。这是源代码的根:http://www.boost.org/doc/libs/1_59_0/libs/spirit/example/qi/compiler_tutorial/mini_c/

我感兴趣的片段是statement_def.hpp

我遇到的问题是,如果您附加语义操作,例如这样,

statement_ =
                variable_declaration[print_this_declaration]
            |   assignment
            |   compound_statement
            |   if_statement
            |   while_statement
            |   return_statement
            ;

随后运行mini_c示例程序的编译器,例如:

int foo(n) {
    if (n == 3) { }
    return a;
}

int main() {
    return foo(10);
}

它会触发“compile.cpp”文件中发现的“重复函数错误”(使用上面的链接找到)。这是供快速参考的片段:

    if (functions.find(x.function_name.name) != functions.end())
    {
        error_handler(x.function_name.id, "Duplicate function: " + x.function_name.name);
        return false;
    }

对于我的一生,我无法弄清楚为什么。

我不太确定如何描述这个问题,但似乎以某种方式发送到标准输出的任何内容都会被解析器拾取作为要解析的有效代码(但这在这种情况下似乎是不可能的)。

另一种可能性是语义操作以某种方式将外部数据绑定到符号表,其中它再次被认为是原始解析的输入文件的一部分(当它不应该是时)。

最后一个可能的选择是,我可能不完全理解这个例子的细节(或Boost),并且某个地方的指针/引用/迭代器在不应该被转移到另一个内存位置时(如SA 的结果),使整个迷你编译器陷入混乱。


[...] 似乎以某种方式发送到标准输出的任何内容都被解析器拾取为要解析的有效代码

尽管看起来不太可能...但确实如此:) 没有魔法发生。

另一种可能性是语义动作以某种方式将外部数据绑定到符号表,它再次被认为是最初解析的输入文件的一部分(当它不应该是时)。

其实你离这里并不远。不过,这并不是那么多“外部”数据。它具有约束力未初始化的数据到符号表。它实际上尝试这样做两次。

一步步:

  1. 默认情况下,具有语义操作的 Qi 规则不会执行自动属性传播。这是assumed语义动作将负责为暴露的属性分配一个值。

    这是根本原因. See 文档:规则/表达式语义

    enter image description here

    Also: 规则如何传播属性

  2. 因此,暴露的实际属性statement_规则将是类型的默认构造对象ast::statement:

    qi::rule<Iterator, ast::statement(), skipper<Iterator> > statement_;
    
  3. 这个类型ast::statement是一个变体,默认构造的变体保存第一个元素类型的默认构造对象:

    typedef boost::variant<
            variable_declaration
        , assignment
        , boost::recursive_wrapper<if_statement>
        , boost::recursive_wrapper<while_statement>
        , boost::recursive_wrapper<return_statement>
        , boost::recursive_wrapper<statement_list>
        >
    statement;
    
  4. 你瞧,那个对象是类型variable_declaration!

    struct variable_declaration {
        identifier lhs;
        boost::optional<expression> rhs;
    };
    

    所以,每次statement_规则匹配时,AST 将被解释为“变量声明identifier name ""”。(不用说,初始化器(rhs) 也是空的)。

    第二次遇到此声明违反了“符号表”中不能存在重复名称的规则。

怎么修?

即使存在语义操作,您也可以明确指示您希望自动传播属性。

Use operator%=代替operator=_分配规则定义:

    statement_ %=
            variable_declaration [print_this_declaration]
        |   assignment
        |   compound_statement
        |   if_statement
        |   while_statement
        |   return_statement
        ;

现在,一切都会恢复正常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提升语义操作导致解析问题 的相关文章

随机推荐

  • 是否可以在不同线程上使用 std::deque::push_back() 和 std::deque::front()/std::deque::pop_front() 而不同步? [复制]

    这个问题在这里已经有答案了 我有一个生产者 消费者的情况 只有一个生产者和一个消费者 共享一个公共的 std deque 让我写一些代码 deque
  • 无法使用参数调用 Word VBA 宏

    我有一个 VB6 应用程序 需要调用 Word 2010 VBA 例程并提供字符串参数 VBA 例程位于通过打开的文档启用的插件中 根据MSDN参考 http msdn microsoft com en us library ff83893
  • 从 JavaScript 调用 JAX-WS Web 服务时的空参数

    我有一个 JAX WS Web 服务 当从任何客户端 即 Java destkop 应用程序 调用但不能从 JavaScript 调用时 该服务工作正常 我的 WS 界面如下所示 WebService public interface Li
  • 将光标设置在 EditText 上的右侧,并提示重力居中

    这可能吗 有任何 EditText 属性可以这样做吗 Thanks 您可以使用 android ellipsize end android gravity center 当你声明 EditText 时在你的 xml 中 第一行是将光标移动到
  • 自跟踪实体和延迟加载

    有没有办法在上下文打开时使用延迟加载和自我跟踪实体 会有什么问题吗 我需要考虑什么 非常感谢您的提前答复 STE 根本不支持延迟加载 因为延迟加载需要在实体上创建动态代理 但 STE 在设计上并未代理 检查摘要中的附加注释 or MSDN问
  • 在python中向时间序列图添加水平限制线

    我想为温度时间序列图添加水平上限和下限线 假设上限线为 30 下限线为 10 df3 plot x Date y Temp PM Temp AM figsize 20 8 我认为这个解决方案可以帮助你 import matplotlib p
  • Joomla URL:一篇文章本身没有漂亮的 URL?

    我是 Joomla 1 5 的新手 我试图澄清一些有关 Joomla 处理 URL 的方式 我已经激活了他们所说的 搜索引擎友好的网址 但似乎页面 或 文章 只有在我从菜单链接到它时才会获得这样的 URL 漂亮的 无参数 URL 真的只在我
  • JQuery 滑块替代品? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在使用 JQuerySlider用作双面滑块的控件 这是一个很棒的 UI 控件 但我正在寻找一个不那么 胖 的替代方案 现在 为了让我使用滑块控件 我必须包括 jQuery核心
  • 'virtualenv' 'pip install sqlalchemy' 但看不到 'pip list'

    我学会了安装python的虚拟环境 看来我对一些基本的点子常识不太熟悉 That is 在虚拟环境中 virtualenv test 然后我有一个名为 test 的虚拟环境 然后我通过激活它 source test bin activate
  • 这个哈希对于安全性有优势吗?

    有什么好处吗 sha1 sha1 sha1 password salt 基本上有多个 sha1 与只有一个 sha1 sha1 password salt 我再说一遍 不要DO NOT尝试通过对哈希值进行 特殊 操作来使密码哈希值更安全 F
  • 使用 auto 访问类的私有结构

    我发现下一个奇怪的代码编译并运行 在 VS 2019 上 include
  • 什么是条件同步?

    有人可以向我解释条件同步吗 一个例子 最好是 C 的 也将不胜感激 听起来你的教授正在谈论线程 线程使计算机程序能够一次执行多件事情 在线程已经运行的情况下启动新线程的行为被计算机程序员称为 启动线程 线程可以共享相同的内存空间 条件同步
  • 0xC0000005:读取位置 0x00000008 时发生访问冲突

    我已经为此苦苦挣扎了一段时间 想知道是否有人可以提供帮助 我正在尝试使用 C 和 SDL1 3 制作粒子样本 到目前为止我已经取得了巨大的成功 程序编译并打开屏幕 但没有任何反应 当我运行调试器时 我收到此错误 SDL 1 3 Space
  • 为每个用户选择每天最高的 3 个分数

    我有一个像这样的 MYSQL 表 id userid score datestamp 1 1 5 2012 12 06 03 55 16 2 2 0 5 2012 12 06 04 25 21 3 1 7 2012 12 06 04 35
  • Windows 堆栈和堆地址范围

    到目前为止 我在使用 Linux 时 堆栈地址非常高 而堆地址非常低 通过使用 C 程序打印堆和堆栈地址可以看出 我对 Win32 进程内存布局有一个问题 MWSDN说堆栈地址高于堆地址 但从我在实践中看到的情况来看 堆栈地址低于堆地址 所
  • 关闭 MySQL 连接 (PHP)

    我编写了一个类来创建与 MySQL 的自动连接并创建查询 它看起来是这样的 include constants php class MySQLDB var connection function construct this gt conn
  • openpty 之后的 ncurses newterm

    我正在尝试弄清楚如何执行以下操作 创建一个新的伪终端 打开在 从属 伪终端内运行的 ncurses 屏幕 fork A 将 I O 从程序运行的终端 bash 转发到新的 从属 终端或 B 退出 让 ncurses 程序在新 pty 中运行
  • 从 R 中未知密度的分位数生成随机样本[重复]

    这个问题在这里已经有答案了 如何从未知密度的分位数生成随机样本数据f x for x之间0 and 4 in R f function x x 1 2 exp x 3 3 2 x 2 2 x 如果我理解正确的话 你想生成具有密度函数由下式给
  • 后缀(前缀)增量、L 值和 R 值(在 C 和 C++ 中)

    我刚刚了解到以下事实 前缀增量 var name 的结果是 C 中的 R 值 至少 我是 确保它不是 C 中的 L 值 但它是 C 中的 L 值 后缀增量 var name 的结果是 C 中的 R 值 至少 我是 确保它不是 C 中的 L
  • 提升语义操作导致解析问题

    我一直在使用 Boost mini 编译器示例 这是源代码的根 http www boost org doc libs 1 59 0 libs spirit example qi compiler tutorial mini c 我感兴趣的