簡體   English   中英

如何找到 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)]

將接近“自然行為”。

額外里程

要獲取文件名/行/列值,您可以執行一些迭代器算術或使用line_pos_iterator適配器:

#include <boost/spirit/include/support_line_pos_iterator.hpp>

這具有一些有助於行號/列跟蹤的訪問器功能。 您可能可以在這里找到我的一些答案,並附上示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM