несоответствующий вход '/' ожидающий {BIN_OPERATOR, ')'} [дубликат]

Давайте посмотрим на лес сначала, прежде чем смотреть на деревья.

Здесь есть много информативных ответов с большими подробностями, я не буду повторять ни одного из них. Ключ к программированию в JavaScript имеет сначала правильную ментальную модель общего исполнения.

  1. Ваша точка входа (ов) выполняется в результате события. Например, в браузер загружается тег сценария с кодом. (Соответственно, поэтому вам, возможно, придется заботиться о готовности страницы запускать ваш код, если он требует, чтобы элементы dom были сконструированы первыми и т. Д.)
  2. Ваш код выполняется до завершения, однако многие асинхронные вызовы, которые он делает, без выполнения каких-либо ваших обратных вызовов, включая запросы XHR, установку тайм-аутов, обработчиков событий dom и т. д. Каждый из этих обратных вызовов, ожидающих выполнения, будет находиться в очереди, ожидая, что их очередь будет запущена после других событий
  3. Каждый отдельный обратный вызов XHR-запроса, установленного таймаута или dom события после вызова будет завершен.

Хорошие новости заключается в том, что, если вы хорошо понимаете этот момент, вам никогда не придется беспокоиться о гоночных условиях. Прежде всего вы должны понимать, как вы хотите упорядочить свой код как по существу ответ на разные дискретные события, и как вы хотите объединить их в логическую последовательность. Вы можете использовать обещания или новые асинхронные / ожидающие более высокие уровни в качестве инструментов для этой цели, или вы можете откатывать свои собственные.

Но вы не должны использовать какие-либо тактические инструменты для решения проблемы, пока вам не понравится актуальная проблемная область. Нарисуйте карту этих зависимостей, чтобы знать, что нужно запускать, когда. Попытка ad-hoc подхода ко всем этим обратным вызовам просто не поможет вам.

18
задан Chiune Sugihara 21 April 2015 в 16:15
поделиться

1 ответ

Это кажется распространенным недоразумением ANTLR:

Обработка языка в ANTLR:

Обработка языка выполняется в двух строго разделенных фазах:

  • Лексинг, то есть разбиение текста на токены
  • Анализ, т. е. построение дерева разбора из токенов

Поскольку лексирование должно предшествовать синтаксическому анализу, возникает следствие : Lexer не зависит от анализатора, парсер не может влиять на лексику.

Лексинг

Лексинг в ANTLR работает следующим образом:

  • все правила с верхний регистр первого слова - это правила lexer
  • , лексер начинается с начала и пытается найти правило, которое наилучшим образом соответствует текущему входу
  • , наилучшее совпадение - это совпадение с максимальной длиной, т.е. токен, полученный из добавления следующего входного символа к совпадению максимальной длины, не сопоставляется никаким лексерским правилам
  • токены генерируются из совпадений: если одно правило соответствует максимальной длине совпадения, соответствующий токен равен pu пролить в поток токенов, если несколько правил соответствуют максимальной длине, соответствует первому определенному токену в грамматике, толкается в поток токенов

Пример: что не так с вашей грамматикой

Ваша грамматика имеет два правила, которые являются критическими:

FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;

Каждое совпадение, соответствующее TITLE, также будет соответствовать FILEPATH. И FILEPATH определяется до TITLE: Таким образом, каждый токен, который вы ожидаете стать заголовком, будет FILEPATH.

Для этого есть два намека:

  • сохранить ваши правила лексера disjunct (никакой токен не должен соответствовать надмножеству другого).
  • , если ваши жетоны преднамеренно соответствуют тем же строкам, а затем помещают их в правильном порядке (в вашем случае этого будет достаточно).
  • , если вам нужен лексер, управляемый парсером, вам нужно перейти на другой генератор парсера: PEG-Parsers или GLR-Parsers сделают это (но, конечно, это может вызвать другие проблемы).
39
ответ дан A_Matar 3 September 2018 в 17:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: