gpt4 book ai didi

c++ - 如何结合跳过和不跳过(lexeme)规则?

转载 作者:行者123 更新时间:2023-12-02 10:19:32 31 4
gpt4 key购买 nike

我的解析器快要工作了:)
(仍然对Spirit功能集(和编译时)以及非常欢迎的社区感到惊讶)

在线尝试的小样本:
http://coliru.stacked-crooked.com/a/1c1bf88909dce7e3

所以我学会了使用更多的lexeme-rules并尝试防止no_skip-
我的规则较小,因此更易于阅读,但现在我坚持使用
将lexeme-rules和skipping-rules结合起来似乎是不可能的(编译时错误和警告,提示无法将其转换为Skipper)

我的问题是订阅中用逗号分隔的列表
不会跳过表达式周围的空格

解析:

"a.b[a,b]"

失败:
"a.b[ a , b ]"

这些是我的规则:
qi::rule<std::string::const_iterator, std::string()> identifier_chain;

qi::rule<std::string::const_iterator, std::string()>
expression_list = identifier_chain >> *(qi::char_(',') >> identifier_chain);

qi::rule < std::string::const_iterator, std::string() >
subscription = qi::char_('[') >> expression_list >> qi::char_(']');

qi::rule<std::string::const_iterator, std::string()>
identifier = qi::ascii::alpha >> *(qi::ascii::alnum | '_');

identifier_chain = identifier >> *(('.' >> identifier) | subscription);

如您所见,所有规则都是“lexeme”,我认为订阅规则应为ascii::space_type跳过程序,但这不能编译

我应该在expression_list的identifier_chains的前面和后面添加空间消耗器吗?

感觉就像写一个正则表达式:(
expression_list = *qi::blank >> identifier_chain >> *(*qi::blank >> qi::char_(',') >> *qi::blank >> identifier_chain >> *qi::blank);

它可以工作,但是我已经读到,这最终将使我进入更大的解析器中(自己处理所有空间)

谢谢任何建议

顺便说一句:任何想法如果我用 '.'包围indentifier_chain中的 qi::char_('.'),为什么我不能编译
identifier_chain = identifier >> *(('.' >> identifier) | subscription);

更新:

我已经按照sehe的建议更新了表情列表
qi::rule<std::string::const_iterator, spirit::ascii::blank_type, std::string()>
expression_list = identifier_chain >> *(qi::char_(',') >> identifier_chain);

qi::rule < std::string::const_iterator, std::string() >
subscription = qi::char_('[') >> qi::skip(qi::blank)[expression_list] >> qi::char_(']');

但仍然由于不可转换的船长而出现编译错误: http://coliru.stacked-crooked.com/a/adcf665742b055dd

我也尝试将identifer_chain更改为
identifier_chain = identifier >> *(('.' >> identifier) | qi::skip(qi::blank)[subscription]);

但我仍然无法编译示例

最佳答案

我先前链接的答案描述了所有组合(如果我没有记错的话):Boost spirit skipper issues

简而言之:

  • 任何声明了船长的规则(因此rule<It, Skipper[, Attr()]>rule<It, Attr(), Skipper>)都必须使用兼容的船长(可以分配给Skipper类型的表达式)调用。
  • 任何不声明船长的规则(形式为rule<It[, Attr()]>)将隐式表现为lexeme,这意味着不会跳过任何输入字符。

  • 而已。较微妙的结果是给出了两个规则:
    rule<It, blank_type> a;
    rule<It> b; // b is implicitly lexeme

    可以b调用 a:
    a = "test" >> b;

    但是,当您希望从 a调用 b时,您会发现必须提供船长:
    b = "oops" >> a; // DOES NOT COMPILE
    b = "okay" >> qi::skip(qi::blank) [ a ];

    几乎就是全部。关于Qi中的船长和词素还有其他一些指令,请再次参见上面链接的答案。

    附带问题:

    should i add space eaters in the front and back of identifier_chains in the expression_list?



    如果您仔细看这里的答案示例 Parse a '.' chained identifier list, with qi::lexeme and prevent space skipping,您会发现它已经正确地进行了前后跳转,因为我使用了 phrase_parse:
    " a.b " OK: ( "a" "b" ) 
    ----
    "a . b" Failed
    Remaining unparsed: "a . b"
    ----

    您也可以将整个内容包装在“外部”规则中:
    rule<std::string::const_iterator> main_rule = 
    qi::skip(qi::blank) [ identifier_chain ];

    一样,但是允许用户在不指定船长的情况下调用 parse

    关于c++ - 如何结合跳过和不跳过(lexeme)规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60845800/

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