2016-05-26 2 views
2

Я хотел бы разобрать следующую возвратные степенные правило, которое разбирает простой идентификатор шаблона Classe как foo<bar> foo<bar,baz> foo<bar<baz>> здесь простая грамматика:Разбор рекурсивных правил с духом x3

identifier := A-Z | a-z | _ 
class_identifier = identifier ?("<" identifier|class_identifier 
            ("," identifier|class_identifier)* 
           ">") 

Я пытался написать парсер с х3, как это:

auto const identifier = x3::rule<class identifier_id, std::string>{"identifier"} 
          = +x3::char_("A-Za-z"); 

x3::rule<class class_identifier, std::string> class_identifier = "class_identifier"; 

auto const class_identifier_def = identifier //classname 
              >> -(x3::string("<") 
               >> (identifier | class_identifier)           
               >> *(x3::string(",")              
                 >> (identifier | class_identifier)) 
               >> x3::string(">")); 
BOOST_SPIRIT_DEFINE(class_identifier) 

но эта попытка не удается разобрать вещи, как этот foo<bar<baz>> но Foo прекрасно. Есть ли какая-то логическая ошибка в моей грамматике, или я использую boost дух неправильно, поскольку это рекурсивное правило?

+1

Чтобы сделать вашу жизнь проще, я считаю, '(идентификатор | class_identifier) ​​ >> * (x3 :: строка («») > > (идентификатор | class_identifier)) 'можно заменить на' (идентификатор | class_identifier)% x3 :: string (",") '. Я не удивлюсь, если бы это было упрощено до '% ',' ', также, наряду с другими местами, где литерал не мешал бы перегрузке оператора. – chris

+1

Действительно. '% ','' is fine – sehe

+0

, даже если я анализирую строку и хочу, чтобы '', ''находились в строке? – Exagon

ответ

3

Я нашел, почему это не удается разобрать. Я должен был изменить это (identifier | class_identifier) на это (class_identifier | identifier), потому что оно также правило class_identifier также начинается с identifier. вот почему он пытался разобрать каждый раз с identifier правила, а затем терпит неудачу в <

+1

Я думаю, что в настоящее время вторая ветка альтернативного анализатора никогда не принимается. Я не тестировал его, поэтому я могу ошибаться, но я уверен, что вам даже не нужен альтернативный оператор, если у вас есть опция в 'class_identifier'. Если в будущем вы измените атрибуты (от простой строки до какого-то АСТ), ваше текущее определение будет лучше (удаление этого необязательного). – llonesmiz

Смежные вопросы