【问题标题】:boost::spirit alternative parsers return duplicatesboost::spirit 替代解析器返回重复项
【发布时间】:2021-02-04 16:58:44
【问题描述】:

我正在处理https://github.com/F-Bergemann/RegexSplitter
目的:解析正则表达式字符串,并创建可破坏和不可破坏的顶级子字符串。可分解的子串可以再次分解。牢不可破的子串必须保持原样。牢不可破适用于“组”和“字符类”
我目前正在研究“角色类”。对于那些,我主要使用 qi::rule 解析器,并且只有一个 qi::rule 解析器用于根解析器。 IE。只有根解析器才能创建 AST 结果。子解析器只需验证即可。

在测试编译的正则表达式拆分器时,我得到了这个:

> ./regex-splitter "[1]"
TEST:[1]
### ASTNode c'tor (std::string &) #1: Unbreakable
### ASTNode c'tor (std::string &) #2: U:[11]
### ASTNode c'tor (ASTNode const *, std::vector<ASTNode *> &) #1: Collection
### ASTNode d'tor #1: Unbreakable
### ASTNode d'tor #2: U:[11]
### ASTNode c'tor (ASTNode const *, std::vector<ASTNode *> &) #2: Collection
U:[11], 
### ASTNode d'tor #1: Collection
### ASTNode d'tor #2: C:[11]

即结果不是“[1]”,而是“[11]”。
我知道这与以下部分代码有关:

tok_set_item =
tok_range | tok_char
;

tok_range =
tok_char >> qi::char_('-') >> tok_char
;

tok_char =
qi::alnum // TODO BNF: <char> ::= any non metacharacter | "\" metacharacter
;

似乎在尝试tok_range,1st。然后切换到 tok_char。
但是我为什么要在这里得到“[11]”?
它应该只验证语法并返回原始数据。

我试图在这里找出解析器操作会发生什么。
我这里没有明确的解析器操作。
它在隐式使用什么? boost::variant<...>?
当我使用 qi::as_string[...] 包装器时,它有什么不同吗?

【问题讨论】:

    标签: c++ boost-spirit-qi


    【解决方案1】:

    这是古老的“容器属性不是原子的”陷阱:

    您可以使用qi::hold 将其覆盖。或者你可以修改你的策略。

    我会看看是否能抽出时间来查看代码。您可以在 CodeReview.stackexchange.com 上发帖以获取良好的衡量标准。

    【讨论】:

    • 所以...我对代码进行了审查,并将其减少到大约 40 行代码(请参阅commitsLive Demo。请注意它如何不做任何动态分配(在 vcctor 之外),没有语义操作,没有手动调试,没有更多重复的规则等。它只是工作,只是使用 qi::raw
    • 非常感谢!这是一个非常好的示例(参考),说明如何使用 BOOST_FUSION_ADAPT_STRUCT() 和 boost::iterator_range 使用专用的 boost::iterator_range 解析器填充不同的数据类型,以及用于填充结果数据结构的互操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2015-01-25
    • 1970-01-01
    相关资源
    最近更新 更多