У меня есть простая грамматика, состоящая из смешанных переменных ($(name)
) и пар переменная-значение ($(name:value)
).У меня есть рекурсивный парсер, закодированный вручную, но я заинтересован в его использовании в качестве упражнения для изучения Духа, которое мне понадобится для более сложных грамматик в конечном итоге (/ скоро).
В любом случае, набор возможных формЯ работаю с (упрощенно от полной грамматики):
$(variable) // Uses simple look-up, recursion and inline replace
$(name:value) // Inserts a new variable into the local lookup table
Мои текущие правила выглядят примерно так:
typedef std::map<std::string, std::string> dictionary;
template <typename Iterator>
bool parse_vars(Iterator first, Iterator last, dictionary & vars, std::string & output)
{
using qi::phrase_parse;
using qi::_1;
using ascii::char_;
using ascii::string;
using ascii::space;
using phoenix::insert;
dictionary statevars;
typedef qi::rule<Iterator, std::string()> string_rule;
typedef qi::rule<Iterator, std::pair<std::string, std::string>()> pair_rule;
string_rule state = string >> ':' >> string; // Error 3
pair_rule variable =
(
char_('$') >> '(' >>
(
state[insert(phoenix::ref(statevars), _1)] |
string[output += vars[_1]] // Error 1, will eventually need to recurse
) >> ')'
); // Error 2
bool result = phrase_parse
(
first, last,
(
variable % ','
),
space
);
return r;
}
Если это не было очевидно, я понятия не имеюкак работает Дух, и у документов есть все, кроме реальных объяснений, так что это примерно час объединения примеров.
Части, которые я особенно задаю вопрос, являются ведущими char_('$')
в правиле variable , но удаление этого вызывает ошибку оператора сдвига (компилятор интерпретирует '$' >> '('
как сдвиг вправо).
При компиляции я получаю ошибки, связанные с правилом state , в частности, при созданиипара и поиск:
- ошибка C2679: двоичный файл '[': не найден оператор, который принимает правый операнд типа 'const boost :: spirit :: _ 1_type' (или нетприемлемый конвекrsion)
- ошибка C2512: 'boost :: spirit :: qi :: rule :: rule': не доступен соответствующий конструктор по умолчанию
Изменение поиска (vars[_1]
) напростой +=
дает:
3 .ошибка C2665: 'boost :: spirit :: char_class :: classify :: is': ни одна из 15 перегрузок не может преобразовать все типы аргументов
Кажется, ошибка 1 связана с типом (атрибутом?)_1
заполнитель, но это должна быть строка, а равно при использовании для печати или объединения в выходную строку.2 кажется шумом, вызванным 1.
Ошибка 3, копающая стопку ошибок шаблона, кажется, связана с неспособностью превратить правило state в пару, которая кажетсястранно, поскольку оно почти точно соответствует одному из правил этого примера .
Как изменить правило variable для правильной обработки обеих форм ввода?