2016-03-13 9 views
0

Я пытаюсь сделать инструмент как ANTLR с нуля в Swift (просто для удовольствия). Но я не понимаю, как грамматика знает, что там не должно быть пробелы (пример идентификатора: «_myIdentifier123»):Какая магия за WS в ANTLR?

Identifier 
: Identifier_head Identifier_characters? 

И должно быть пробелы (например, «это строка»):

type_casting_operator 
    : 'is' type 
    | 'as' type 
    | 'as' '?' type 
    | 'as' '!' type 
    ; 

Я искал WS в исходном коде ANTLR, но ничего не нашел. В java-коде нет строки «WS»: https://github.com/antlr/antlr4

Может ли кто-нибудь объяснить алгоритм этого? Как он решает, разделяются ли токены с пробелами или нет?

+2

Ты знаешь об этом проекте: https://github.com/janyou/ANTLR-Swift-Target? Также обсуждаемая здесь быстро заданная задача: https://github.com/antlr/antlr4/issues/945 –

ответ

2

Первое правило - правило лексера (обратите внимание на первую букву буквы), а второе правило - это правило синтаксического анализатора.

Маркер белого пространства обычно не передается в синтаксический анализатор (в этом случае должно быть правило пропуска пробела в лексере), поэтому второе правило не видит его. Пробелы могут появляться где угодно между другими токенами.

Правила Lexer в отличие от всех символов на входе, поэтому любое свободное пространство должно быть явно указано.

+0

Итак, если правило анализатора состоит из трех подстрок (последовательность из трех терминалов или нетерминалов), тогда я должен ожидать 0 или более пробелов или разделы комментариев между ними? Это полный алгоритм без исключений? –

+0

Да, если вы определяете пробел и комментарии для пропуска, они полностью невидимы для анализатора и могут появляться между любыми двумя токенами. – Henry

3

Удачи вам в этом проекте. Не зная даже самых основных алгоритмов, эта нетривиальная задача создания генератора парсера становится еще более амбициозной. Вы должны хотя бы прочитать книгу или две о предмете (классика - Книга Дракона, от Ахо, Сети + Ульманн).

Но вернемся к вашему вопросу. Принцип заключается в том, что: whitespaces нужно обрабатывать, как и любой другой вход, но обычно вы найдете правило грамматики WS или Whitespace lexer, которое соответствует различным типам пробелов (пробел, разрывы строк, вкладка и т. Д.) И помещает их в скрытый канал. Парсер видит только токены со стандартного канала и, следовательно, не получает пробелы в качестве токенов. Это наиболее распространенный подход, потому что существование пробелов обычно не имеет значения (за исключением разделения двух лексических записей, которые необходимо распознать как два разных токена).

+0

Эта книга полезна для моей задачи, я прочитал первые три главы, и этого достаточно для лексического анализа (это означает, что теперь мне не нужно читать другие главы). Однако эта книга не дает полного представления о лексическом анализе, различных алгоритмах синтаксического анализа, архитектуре программного обеспечения лексического анализа для анализа сложных языков. –

+0

И вернемся к вопросу, я понимаю, что существуют два типа правил производства: правила lexer и правила парсера. Если правило состоит из последовательности терминалов и нетерминалов, то если это правило лексера, между ними не допускаются пробелы, и если это правило парсера, то они могут быть разделены 0 или более символами пробела. Я прав? Это полный алгоритм работы с пробелами? –

+0

Прочтите мой ответ еще раз. Это не связано с правилом лексера или парсера. Пробелы должны быть обозначены как любой другой вход, и вы можете решить, что делать с токеном. Если вы поместите его на скрытый канал, синтаксический анализатор его не увидит, иначе вам придется обрабатывать их, как любой другой токен в грамматике парсера. Btw: правила производства относятся только к парсеру. В лексере нет постановок, это просто токенизатор. –