Я работал в Yacc (по аналогии с Bison) с похожим сценарием.
Стандартные грамматики иногда называют "синтаксическим анализом, направленным по синтаксису".
Этот случай иногданазывается что-то вроде "синтаксический анализ, направленный семантикой".
Пример:
...
// shift operator example
if ((x >> 2) == 0)
...
// consecutive template closing tag example
List<String, List<String>> MyList =
...
Давайте помним, наш ум работает как компилятор.Человеческий разум может скомпилировать это, но предыдущие грамматики не могут.Mhhh.Давайте посмотрим, как человеческий разум скомпилирует этот код.
Как вы уже знаете, "x" перед последовательными жетонами ">" и ">" указывает выражение или lvalue.Разум думает, что «два последовательных символа больше чем после выражения должны стать токеном одного оператора сдвига».
А для «строкового» токена: «два последовательных символа больше чем после идентификатора типа, должны стать двумя последовательными токенами закрывающих шаблонов ".
Я думаю, что этот случай не может быть обработан обычным оператором приоритета, сдвига или уменьшения или просто грамматикой, но с использованием (" взлома ") некоторых функций, предоставляемыхсам парсер.
Я не вижу ошибки в вашем примере грамматического правила.Символ «оператор» позволяет избежать путаницы в двух упомянутых вами случаях.Части, которые должны касаться его грамматики, где используется оператор сдвига, и последовательные теги закрытия шаблона.
operator_expr_example:
lvalue "<<" lvalue |
lvalue ">>" lvalue |
lvalue "&&" lvalue |
;
template_params:
identifier |
template_declaration_example |
array_declaration |
other_type_declaration
;
template_declaration_example:
identifier "<" template_params ">"
;
Приветствия.