Зубр, анализ C ++ GLR: как заставить сдвинуть \ уменьшить конфликт? - PullRequest
3 голосов
/ 01 февраля 2012

Как я могу принудительно разрешить конфликт сдвига \ уменьшения методом GLR?
Предположим, я хочу, чтобы синтаксический анализатор разрешил конфликт между оператором правого сдвига и двумя закрывающими угловыми скобками аргументов шаблона для себя.Я заставляю лексера передавать 2 последовательных символа «>» в ​​виде отдельных токенов, не объединяя их в один токен «>>».Затем я помещаю эти правила в грамматику:

operator_name:  
     "operator" ">"  
   | "operator" ">" ">"  
;  

Я хочу, чтобы это был сдвиг \ уменьшение конфликта.Если у меня есть объявление токена для «>» с левой ассоциативностью, это не будет конфликтом.Поэтому я должен удалить объявление приоритета токена \ ассоциативности, но это приводит ко многим другим конфликтам, которые я не хочу решать вручную, указав контекстный приоритет для каждого конфликтующего правила.Итак, есть ли способ вызвать сдвиг \ уменьшить конфликт при объявлении токена?

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

Я считаю, что использование контекстно-зависимого приоритета в правилах для operator_name будет работать.

Грамматика C ++, как определено в обновленном стандарте, фактически изменяет грамматику, чтобы принимать >> токен как закрывающий два объявления открытого шаблона. Я бы порекомендовал следовать этому, чтобы получить стандартное поведение. Например, вы должны быть осторожны, чтобы «x>> y» не анализировался как «x >> y», и вы также должны убедиться, что «foo > 1 >>» недопустима, а «foo < bar <(2 >> 1) >> "действителен.

1 голос
/ 01 февраля 2012

Я работал в 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 ">"
;  

Приветствия.

...