【发布时间】: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