boost :: spirit access position из семантических действий

Допустим, у меня есть такой код (номера строк для справки):

1:
2:function FuncName_1 {
3:    var Var_1 = 3;
4:    var  Var_2 = 4;
5:    ...

Я хочу написать грамматику, которая анализирует такой текст, помещает все идентификаторы (имена функций и переменных) в дерево (utree?). Каждый узел должен сохранять: line_num, column_num и значение символа. пример:

root: FuncName_1 (line:2,col:10)
  children[0]: Var_1 (line:3, col:8)
  children[1]: Var_1 (line:4, col:9)

Я хочу поместить это в дерево, потому что я планирую пройти через это дерево, и для каждого узла я должен знать 'контекст»: (все родительские узлы текущих узлов).

Например, при обработке узла с помощью Var_1 я должен знать, что это имя локальной переменной для функции FuncName_1 (которая в настоящее время обрабатывается как узел, но на один уровень раньше)

Я не могу понять несколько вещей

Может ли это быть сделано в духе с помощью семантических действий ис? Или я должен использовать вариант <> деревья?Как передать узлу эти три информации (столбец, строка, символ_имя) одновременно? Я знаю, что должен использовать pos_iterator в качестве типа итератора для грамматики, но как получить доступ к этой информации в семантическом действии?

Я новичок в Boost, поэтому я перечитываю документацию Spirit снова и снова, я пытаюсь погуглить свои проблемы, но почему-то не могу собрать все части вместе, чтобы найти решение. Похоже, не было ни одного меня с таким случаем использования, как у меня раньше (или яя просто не могу его найти) Похоже, единственными решениями с итератором позиции являются те, которые обрабатывают ошибки, но это не тот случай, когда яЯ заинтересован в. Код, который только анализирует код, который я принимал ниже, но я не знаю, как двигаться дальше с ним.

  #include 
  #include 

  namespace qi = boost::spirit::qi;
  typedef boost::spirit::line_pos_iterator pos_iterator_t;

  template
  struct ParseGrammar: public qi::grammar
  {
        ParseGrammar():ParseGrammar::base_type(SourceCode)
        {
           using namespace qi;
           KeywordFunction = lit("function");
           KeywordVar    = lit("var");
           SemiColon     = lit(';');

           Identifier = lexeme [alpha >> *(alnum | '_')];
           VarAssignemnt = KeywordVar >> Identifier >> char_('=') >> int_ >> SemiColon;
           SourceCode = KeywordFunction >> Identifier >> '{' >> *VarAssignemnt >> '}';
        }

        qi::rule SourceCode;
        qi::rule KeywordFunction;
        qi::rule VarAssignemnt;
        qi::rule KeywordVar;
        qi::rule SemiColon;
        qi::rule Identifier;
  };

  int main()
  {
     std::string const content = "function FuncName_1 {\n var Var_1 = 3;\n var  Var_2 = 4; }";

     pos_iterator_t first(content.begin()), iter = first, last(content.end());
     ParseGrammar resolver;    //  Our parser
     bool ok = phrase_parse(iter,
                            last,
                            resolver,
                            qi::space);

     std::cout < std::boolalpha;
     std::cout < "\nok : " < ok < std::endl;
     std::cout < "full   : " < (iter == last) < std::endl;
     if(ok && iter == last)
     {
        std::cout < "OK: Parsing fully succeeded\n\n";
     }
     else
     {
        int line   = get_line(iter);
        int column = get_column(first, iter);
        std::cout < "-------------------------\n";
        std::cout < "ERROR: Parsing failed or not complete\n";
        std::cout < "stopped at: " < line  < ":" < column < "\n";
        std::cout < "remaining: '" < std::string(iter, last) < "'\n";
        std::cout < "-------------------------\n";
     }
     return 0;
  }

Ответы на вопрос(1)

Ваш ответ на вопрос