我正在写一个pdf解析库。
很久以前,我有一个输入可以像下面这样进行解析:
1 0 obj
(anything)
endobj我为外部容器创建了解析规则,然后为内部对象创建了单独的规则:
CONTAINER_PARSER %=
number >> number >> "obj" >> OBJECT_PARSER >> "endobj";
OBJECT_PARSER %= number | value | ... 这没有任何问题。但是,由于各种原因,我不得不重新设计规则,以便两个容器值都属于对象本身。
容器本身只能是可选的。意思是,前面的代码和下面的代码表示相同的对象,而没有附加的容器信息:
(anything)我有两个想法,如何解决这个问题,但在我看来,两者都是不符合齐的方法。
替代解析器
我想告诉解析器,解析obj中包含的值,或者只解析值。
start %=
(
object_number
>> generation_number
>> qi::lit("obj")
>> object
> qi::lit("endobj")
) | object;
// I intentionally missed some semantic actions assigning the values to the object,
because it is out of the scope of my problem我没有成功地完成这个任务,因为变更的两个部分都有相同的公开属性,编译器也很困惑。
可选方法
我试图告诉解析器,前一个容器对于解析的值来说是可选的。
start %=
-(
object_number
>> generation_number
>> qi::lit("obj")
)
>> object
> -qi::lit("endobj");这种方法的问题是,如果第一部分也存在,则最后一部分"endobj“必须存在。
这个解决方案可能很简单,但我确实无法从代码、文档和堆栈溢出的答案中找到答案。
发布于 2015-01-18 11:11:45
在评论后更新:
start =
(
( object_number >> generation_number
| qi::attr(1) > qi::attr(0) // defaults
) >> "obj" >> object > "endobj"
| qi::attr(1) >> qi::attr(0) >> object
)
;假设您对(可选的)数字不感兴趣:
start =
-qi::omit [ object_number >> generation_number ]
>> "obj" >> object > "endobj"
;如果您感兴趣并且有合适的默认值:
start =
( object_number >> generation_number
| qi::attr(1) > qi::attr(0) // defaults
)
>> "obj" >> object > "endobj"
;当然,你可以
optional<int>用于object_numbers,因此您可以简单地使用-object_number >> -generation_number;这有点草率,因为它还允许"1 obj (anything) endobj"boost::variant<simple_object, object_contaier>
在这种情况下,AST与您的问题中的“替代”方法(第一种)相匹配。https://stackoverflow.com/questions/28008615
复制相似问题