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;
}