【问题标题】:Boost Spirit new line and end of inputBoost Spirit 换行和输入结束
【发布时间】:2014-03-23 12:45:35
【问题描述】:

我正在尝试使用 Boost Spirit 编写一个解析器,它解析以换行符或输入结尾结尾的语句的脚本语言。因此,我编写了一个自定义跳过程序,它跳过空白和一行 cmets (// bla bla) 检测输入结束和行结束但不消耗,因此所有表达式都可以明确地以“eol”或“eoi”结束。 不幸的是,该程序似乎无休止地解析,或者最后一条语句确实存在错误,该语句以 eoi 而不是 eol 结束,我不知道如何正确拆分表达式:

*qi::eol >> (*(qi::char_ - (qi::eol)) % (+qi::eol)) >> qi::eoi

除了最后一个由 eoi 结束的语句之外,这一个有效,因为它期望所有行至少有一个 eol。 以下语句无休止地解析:

*qi::eol >> (*(qi::char_ - (qi::eol)) % (+qi::eol | &qi::eoi)) >> qi::eoi

它不应该消耗 eoi,而是接受它作为语句的有效结尾。它仍然被认为是最后一个字符。

船长有以下陈述:

 blank | lit("//") >> *(char_ - (eol | eoi) ) >> (&eol | &eoi)

最后我想得到一个字符串列表,每个字符串代表一行。对于测试,我使用以下输入:

// This is a comment in the first line 1234567890!"$?:;.-_+/=
globals
    integer bla = 10 // This is a comment after an expression
endglobals
// This is a comment in the last line
type bla extends integer

我希望有 6 个字符串,其中两个是空的,因为只有 cmets。对于声明

integer bla = 10 // This is a comment after an expression

它只是应该删掉评论和空白

integerbla=10

应该是结果字符串。

如果你有更好的想法如何编写这样的语法,请告诉我!

【问题讨论】:

  • 你试过+(qi::char_ - (qi::eol))吗?反正你已经消耗了所有的 eols,为什么不在这里检查非空行呢?

标签: c++ parsing boost boost-spirit boost-spirit-qi


【解决方案1】:

我认为你让它变得比你需要的更复杂。输入结束将终止解析而不会出错,因此如果源数据是 kosher 则不需要使用 eoi。

试试这个船长:

blank | lit("//") >> *(char_ - eol)

为你的表达式解析器试试这个:

*(char_ - eol) % eol

每行只有一个表达式,并且必须检查空行并丢弃它们。为避免这种情况,您可以尝试以下方法:

*((+(char_ - eol) >> eol) | eol)

【讨论】:

  • 只有一个建议,吃空行,我更喜欢*(char_ - eol) % (+eol)
  • 是的,这样会更好。不过,您仍然可以在一开始就得到一个空行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多