title: How ANTLR decides whether terminals should be separated with whitespaces or not?
body: <p>I'm writing lexical analyzer in Swift for Swift. I used ANTLR's grammar, but I faced with problem that I don't understand how ANTLR decides whether terminals should be separated with whitespaces.</p>
  
  <p>Here's the grammar: <a href="https://github.com/antlr/grammars-v4/blob/master/swift/Swift.g4" rel="nofollow">https://github.com/antlr/grammars-v4/blob/master/swift/Swift.g4</a></p>
  
  <p>Assume we have casting in Swift. It can also operate with optional types (Int?, String?) and with non-optional types (Int, String). Here are valid examples: "as? Int", "as Int", "as?Int". Invalid examples: "asInt" (it isn't a cast). I've implemented logic, when terminals in grammar rules can be separated with 0 or more WS (whitespace) symbols. But with this logic "asInt" is matching a cast, because it contains "as" and a type "Int" and have 0 or more WS symbols. But it should be invalid.</p>
  
  <p>Swift grammar contains these rules:</p>
  
  <pre><code>DOT     : '.' ;
  LCURLY  : '{' ;
  LPAREN  : '(' ;
  LBRACK  : '[' ;
  RCURLY  : '}' ;
  RPAREN  : ')' ;
  RBRACK  : ']' ;
  COMMA   : ',' ;
  COLON   : ':' ;
  SEMI    : ';' ;
  LT      : '&lt;' ;
  GT      : '&gt;' ;
  UNDERSCORE : '_' ;
  BANG    : '!' ;
  QUESTION: '?' ;
  AT      : '@' ;
  AND     : '&amp;' ;
  SUB     : '-' ;
  EQUAL   : '=' ;
  OR      : '|' ;
  DIV     : '/' ;
  ADD     : '+' ;
  MUL     : '*' ;
  MOD     : '%' ;
  CARET   : '^' ;
  TILDE   : '~' ;
  </code></pre>
  
  <p>It seems that all these terminals can be separated with other's with 0 WS symbols, and other terminals don't (e.g. "as" + Identifier).</p>
  
  <p>Am I right? If I'm right, the problem is solved. But there may be more complex logic.</p>
  
  <p>Now if I have rules</p>
  
  <pre><code>WS : [ \n\r\t\u000B\u000C\u0000]+
  a : 'str1' b
  b : 'str2' c
  c : '+' d
  d : 'str3'
  </code></pre>
  
  <p>I use them as if they were these rules:</p>
  
  <pre><code>WS : [ \n\r\t\u000B\u000C\u0000]+
  a : WS? 'str1' WS? 'str2' WS? '+' WS? 'str3' WS?
  </code></pre>
  
  <p>And I suppose that they should be like these (I don't know and that is the question):</p>
  
  <pre><code>WS : [ \n\r\t\u000B\u000C\u0000]+
  a: 'str1' WS 'str2' WS? '+' WS? 'str3'
  </code></pre>
  
  <p>(notice WS is not optional between 'str1' and 'str2')</p>
  
  <p>So there's 2 questions:</p>
  
  <ol>
  <li>Am I right?</li>
  <li>What I missed?</li>
  </ol>
  
  <p>Thanks.</p>