gpt4 book ai didi

parsing - 我可以从我的船长解析器收集属性吗?

转载 作者:行者123 更新时间:2023-12-04 07:40:02 24 4
gpt4 key购买 nike

我有一个数据文件格式,其中包括

  • /* 评论 */
  • /* 嵌套的/* 注释 */也是 */和
  • //c++ 风格的单行注释..

  • 像往常一样,这些注释可以出现在输入文件中允许正常空白的任何地方。
    因此,我没有通过普遍的注释处理来污染语法,而是制作了一个处理空白和各种注释的skipper解析器。
    到目前为止一切顺利,我能够解析我所有的测试用例。
    但是,在我的用例中,如果存在一个或多个注释,则任何已解析的值( double 、字符串、变量、列表...)都必须将其前面的注释作为属性携带。也就是说,我的 double AST 节点应该是
    struct Double {
    double value;
    std::string comment;
    };
    对于我在语法中的所有值,依此类推。
    因此,我想知道是否有可能以某种方式将收集到的评论“存储”在船长解析器中,然后让它们可用于以正常语法构建 AST 节点?
    处理评论的船长:
    template<typename Iterator>
    struct SkipperRules : qi::grammar<Iterator> {
    SkipperRules() : SkipperRules::base_type(skipper) {
    single_line_comment = lit("//") >> *(char_ - eol) >> (eol | eoi);
    block_comment = ((string("/*") >> *(block_comment | char_ - "*/")) >> string("*/"));
    skipper = space | single_line_comment | block_comment;
    }
    qi::rule<Iterator> skipper;
    qi::rule<Iterator, std::string()> block_comment;
    qi::rule<Iterator, std::string()> single_line_comment;
    };
    我可以在船长规则中使用全局变量和语义操作来存储注释,但这似乎是错误的,并且通常在解析器回溯中可能不会很好地发挥作用。什么是存储评论的好方法,以便以后可以在主语法中检索它们?

    最佳答案

    I can store the commments using a global variable and semantic actions in the skipper rule, but that seems wrong and probably won't play well in general with parser backtracking.


    好想法。见 Boost Spirit: "Semantic actions are evil"? .此外,在您的情况下,它会使源位置与评论的相关性变得不必要地复杂化。

    can I collect attributes from my skipper parser?


    你不能。船长隐含 qi::omit[] (顺便说一下,就像 Kleene-% 列表中的分隔符)。

    In my use case, however, any of the parsed values (double, string,variable, list, ...) must carry the comments preceding it as anattribute, if one or more comments are present. That is, my AST nodefor double should be

    struct Double {
    double value;
    std::string comment;
    };

    你有它: 您的评论不是评论 .您在 AST 中需要它们,因此在语法中也需要它们。
    想法
    我在这里有几个想法。
  • 您不能简单地使用船长来增加评论,就像您提到的那样,这在语法上会很麻烦/嘈杂。
  • 你可以 暂时将船长改写为 qi::space在需要评论的地方。就像是
    value_ = qi::skip(qi::space) [ comment_ >> (string_|qi::double_|qi::int_)  ];
    或者给定您的 AST,可能会更冗长一些
    value_ = qi::skip(qi::space) [ comment_ >> (string_|double_|int_) ];
    string_ = comment_ >> lexeme['"' >> *('\\' >> qi::char_ | ~qi::char_('"')) >> '"'];
    double_ = comment_ >> qi::real_parser<double, qi::strict_real_policies<double> >{};
    int_ = comment_ >> qi::int_;
    笔记:
  • 在这种情况下,请确保 double_ , string_int_qi::space_type 声明作为船长(见 Boost spirit skipper issues )
  • comment_假定规则公开 std::string()属性。如果在船长上下文中使用也可以,因为实际属性将绑定(bind)到 qi::unused_type它编译为属性传播的无操作。
  • 作为一个微妙的旁注,我确保在第二个片段中使用严格的真实策略,以便双分支也不会吃整数。

  • 一个 花式 解决方案可能是将增强的注释存储到“解析器状态”(例如成员变量)中,然后使用 on_success处理程序以根据需要将该值传输到规则属性中(并且可以选择在某些规则完成时刷新注释)。

    I have some examples of what can be achieved using on_success for inspiration: https://stackoverflow.com/search?q=user%3A85371+on_success+qi. (Specifically look at the way position information is being added to AST nodes. There's a subtle play with fusion-adapted struct vs. members that are being set outside the control of autmatic attribute propagation. A particularly nice method is to use a base-class that can be generically "detected" so AST nodes deriving from that base magically get the contextual comments added without code duplication)


    实际上,这是一种混合:是的,您使用语义操作来“旁路”评论值。但是,它不那么笨拙了,因为现在您可以确定性地“收获”成功处理程序中的这些值。如果您不过早地重置评论,它甚至应该在回溯下正常工作。
    对此的提示是,推理“魔术评论”的机制会稍微不那么透明。但是,它确实坐得很好,原因有两个:
    - "magic comments" are a semantic hack whichever way you look at it, so it matches the grammar semantics in the code
    - it does succeed at removing comment noise from productions, which is effectively what the comments were from in the first place: they were embellishing the semantics without complicating the language grammar.

  • 我认为选项 2. 是您可能没有意识到的“直截了​​当”的方法。选项 3. 是一种奇特的方法,以防您想享受更大的通用性/灵 active 。例如。你会做什么
      /*obsolete*/ /*deprecated*/ 5.12e7
    或者,怎么样
      bla = /*this is*/ 42 /*also relevant*/;
    在“花哨”的情况下,这些将更容易正确处理。
    所以,如果你想避免复杂性,我建议选择 2。如果你需要灵 active ,我建议选择 3。

    关于parsing - 我可以从我的船长解析器收集属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67531913/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com