Пишу лексический анализатор на Swift для Swift. Я использовал грамматику ANTLR, но столкнулся с проблемой, что не понимаю, как ANTLR решает, следует ли разделять терминалы пробелами.
Вот грамматика: https://github.com/antlr/grammars-v4/blob/master/swift/Swift.g4
Предположим, у нас есть кастинг в Swift. Он также может работать с необязательными типами (Int?, String?) и с необязательными типами (Int, String). Вот допустимые примеры: "as?Int", "as?Int", "as?Int". Недопустимые примеры: "asInt" (это не приведение). Я реализовал логику, когда терминалы в правилах грамматики могут быть разделены 0 или более символами WS (пробелами). Но с этой логикой «asInt» соответствует приведению, потому что он содержит «as» и тип «Int» и имеет 0 или более символов WS. Но он должен быть недействительным.
Грамматика Swift содержит следующие правила:
DOT : '.' ;
LCURLY : '{' ;
LPAREN : '(' ;
LBRACK : '[' ;
RCURLY : '}' ;
RPAREN : ')' ;
RBRACK : ']' ;
COMMA : ',' ;
COLON : ':' ;
SEMI : ';' ;
LT : '<' ;
GT : '>' ;
UNDERSCORE : '_' ;
BANG : '!' ;
QUESTION: '?' ;
AT : '@' ;
AND : '&' ;
SUB : '-' ;
EQUAL : '=' ;
OR : '|' ;
DIV : '/' ;
ADD : '+' ;
MUL : '*' ;
MOD : '%' ;
CARET : '^' ;
TILDE : '~' ;
Кажется, что все эти терминалы могут быть разделены с другими с 0 символами WS, а другие терминалы - нет (например, "как" + идентификатор).
Я прав? Если я прав, проблема решена. Но может быть и более сложная логика.
Теперь, если у меня есть правила
WS : [ \n\r\t\u000B\u000C\u0000]+
a : 'str1' b
b : 'str2' c
c : '+' d
d : 'str3'
Я использую их, как если бы это были следующие правила:
WS : [ \n\r\t\u000B\u000C\u0000]+
a : WS? 'str1' WS? 'str2' WS? '+' WS? 'str3' WS?
И я предполагаю, что они должны быть такими (я не знаю, вот в чем вопрос):
WS : [ \n\r\t\u000B\u000C\u0000]+
a: 'str1' WS 'str2' WS? '+' WS? 'str3'
(обратите внимание, что WS не является обязательным между «str1» и «str2»)
Итак, есть 2 вопроса:
- Я прав?
- Что я пропустил?
Спасибо.