我如何找到 Spirit 解析器匹配的位置?
how do i find the location where a Spirit parser matched?
我正在解析一个由名称-值对组成的简单配置文件格式:
an_int_option 42;
a_string_option "foo";
an_identifier_option somevalue;
我有一个基本规则来解析每个项目:
typedef boost::variant<int, double, std::string> config_value;
struct config_item {
std::string name;
config_value value;
};
qi::rule<Iterator, config_value(), ascii::space_type> value;
qi::rule<Iterator, config_item(), ascii::space_type> item;
value =
identifier
| qstring
| my_double
| qi::int_
;
item =
identifier[at_c<0>(_val) = _1]
>> value[at_c<1>(_val) = _1]
>> ';'
;
这很好用,并为我提供了每个项目的 config_value。
现在我想将找到每个值的位置存储在输入文件中,这样如果用户配置了一个无效的选项,我可以报告发生错误的文件行和列号。
到目前为止我找到的最佳选择是 raw[]
,它可以让我做类似的事情:
item =
raw[ identifier ] [do_something_with_iterators(_1)]
>> raw[ value ] [do_something_with_iterators(_1)]
>> ';'
;
...但是由于 raw[]
丢弃了该属性,我的 do_something_with_iterators
现在必须像旧式 Spirit 一样手动解析该值 - 当我已经这样做时,这似乎是很多不必要的工作解析值就在那里。
您可以使用 qi::raw[]
获取跨越匹配项的源迭代器对。
Qi Repository 中有一个方便的助手 iter_pos
,您可以使用它直接获取源迭代器而无需使用 qi::raw[]
。
此外,通过一些语义动作技巧,您可以同时获得:
raw[ identifier [ do_something_with_attribute(_1) ] ]
[do_something_with_iterators(_1)]
事实上,
raw[ identifier [ _val = _1 ] ] [do_something_with_iterators(_1)]
将接近“自然行为”。
加倍努力
要获取文件 name/line/column 值,您可以执行一些迭代器算法或使用 line_pos_iterator
适配器:
#include <boost/spirit/include/support_line_pos_iterator.hpp>
这有一些访问函数可以帮助行 number/column 跟踪。您可能可以在这里找到我的一些答案和示例。
我正在解析一个由名称-值对组成的简单配置文件格式:
an_int_option 42;
a_string_option "foo";
an_identifier_option somevalue;
我有一个基本规则来解析每个项目:
typedef boost::variant<int, double, std::string> config_value;
struct config_item {
std::string name;
config_value value;
};
qi::rule<Iterator, config_value(), ascii::space_type> value;
qi::rule<Iterator, config_item(), ascii::space_type> item;
value =
identifier
| qstring
| my_double
| qi::int_
;
item =
identifier[at_c<0>(_val) = _1]
>> value[at_c<1>(_val) = _1]
>> ';'
;
这很好用,并为我提供了每个项目的 config_value。
现在我想将找到每个值的位置存储在输入文件中,这样如果用户配置了一个无效的选项,我可以报告发生错误的文件行和列号。
到目前为止我找到的最佳选择是 raw[]
,它可以让我做类似的事情:
item =
raw[ identifier ] [do_something_with_iterators(_1)]
>> raw[ value ] [do_something_with_iterators(_1)]
>> ';'
;
...但是由于 raw[]
丢弃了该属性,我的 do_something_with_iterators
现在必须像旧式 Spirit 一样手动解析该值 - 当我已经这样做时,这似乎是很多不必要的工作解析值就在那里。
您可以使用 qi::raw[]
获取跨越匹配项的源迭代器对。
Qi Repository 中有一个方便的助手 iter_pos
,您可以使用它直接获取源迭代器而无需使用 qi::raw[]
。
此外,通过一些语义动作技巧,您可以同时获得:
raw[ identifier [ do_something_with_attribute(_1) ] ]
[do_something_with_iterators(_1)]
事实上,
raw[ identifier [ _val = _1 ] ] [do_something_with_iterators(_1)]
将接近“自然行为”。
加倍努力
要获取文件 name/line/column 值,您可以执行一些迭代器算法或使用 line_pos_iterator
适配器:
#include <boost/spirit/include/support_line_pos_iterator.hpp>
这有一些访问函数可以帮助行 number/column 跟踪。您可能可以在这里找到我的一些答案和示例。