content: {-# LANGUAGE DeriveAnyClass, DeriveGeneric, TypeFamilies, QuasiQuotes
      , DataKinds, ScopedTypeVariables, OverloadedStrings, TypeSynonymInstances
      , FlexibleInstances, UndecidableInstances, TemplateHaskell #-}
  module Grammar where
  import Language.ANTLR4
  
  -- This grammar is still in development / experimental.
  
  -- Original license below.
  -- Modified by Karl Cronburg to work with v0.1.0.0 of antlr-haskell
  --
  -- [The "BSD license"]
  --  Copyright (c) 2014 Terence Parr
  --  All rights reserved.
  --
  --  Redistribution and use in source and binary forms, with or without
  --  modification, are permitted provided that the following conditions
  --  are met:
  --
  --  1. Redistributions of source code must retain the above copyright
  --     notice, this list of conditions and the following disclaimer.
  --  2. Redistributions in binary form must reproduce the above copyright
  --     notice, this list of conditions and the following disclaimer in the
  --     documentation and/or other materials provided with the distribution.
  --  3. The name of the author may not be used to endorse or promote products
  --     derived from this software without specific prior written permission.
  --
  --  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  --  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  --  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  --  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  --  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  --  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  --  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  --  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  --  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  --  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  --
  -- Converted from Apple's doc, http://tinyurl.com/n8rkoue, to ANTLR's
  -- meta-language.
  
  [g4|
  
  grammar Swift;
  
  topLevel : statements? ;
  
  // Statements
  
  // GRAMMAR OF A STATEMENT
  
  statement
   : declaration ';'?
   | loopStatement ';'?
   | branchStatement ';'?
   | labeledStatement
   | controlTransferStatement ';'?
   | deferStatement ';' ?
   | doStatement ':'?
   | compilerControlStatement ';'?
   | expression ';'?  // Keep expression last to handle ambiguity
   ;
  
  statements : statement+ ;
  
  // GRAMMAR OF A LOOP STATEMENT
  
  loopStatement : forInStatement
   | whileStatement
   | repeatWhileStatement
   ;
  
  // GRAMMAR OF A FOR_IN STATEMENT
  
  forInStatement : 'for' 'case'? pattern 'in' expression whereClause? codeBlock  ;
  
  // GRAMMAR OF A WHILE STATEMENT
  
  whileStatement : 'while' conditionList codeBlock  ;
  
  // GRAMMAR OF A REPEAT WHILE STATEMENT
  
  repeatWhileStatement: 'repeat' codeBlock 'while' expression ;
  
  // GRAMMAR OF A BRANCH STATEMENT
  
  branchStatement : ifStatement | guardStatement | switchStatement  ;
  
  // GRAMMAR OF AN IF STATEMENT
  
  ifStatement : 'if' conditionList codeBlock elseClause? ;
  elseClause : 'else' codeBlock | 'else' ifStatement  ;
  
  // GRAMMAR OF A GUARD STATEMENT
  
  guardStatement : 'guard' conditionList 'else' codeBlock ;
  
  // GRAMMAR OF A SWITCH STATEMENT
  
  switchStatement : 'switch' expression '{' switchCases? '}'  ;
  switchCases : switchCase+ ;
  switchCase : caseLabel statements | defaultLabel statements  | caseLabel ';' | defaultLabel ';'  ;
  caseLabel : 'case' caseItemList ':' ;
  caseItemList : caseItem (',' caseItem)* ;
  caseItem: pattern whereClause? ;
  defaultLabel : 'default' ':' ;
  
  // GRAMMAR OF A LABELED STATEMENT
  
  labeledStatement : statementLabel labeledInner ;
  statementLabel : labelName ':' ;
  labelName : identifier  ;
  labeledInner : loopStatement | ifStatement | switchStatement | doStatement ;
  
  // GRAMMAR OF A CONTROL TRANSFER STATEMENT
  
  controlTransferStatement : breakStatement
   | continueStatement
   | fallthroughStatement
   | returnStatement
   | throwStatement
   ;
  
  // GRAMMAR OF A BREAK STATEMENT
  
  breakStatement : 'break' labelName? ;
  
  // GRAMMAR OF A CONTINUE STATEMENT
  
  continueStatement : 'continue' labelName? ;
  
  // GRAMMAR OF A FALLTHROUGH STATEMENT
  
  fallthroughStatement : 'fallthrough'  ;
  
  // GRAMMAR OF A RETURN STATEMENT
  
  returnStatement : 'return' expression? ;
  
  // GRAMMAR OF A THROW STATEMENT
  
  throwStatement : 'throw' expression ;
  
  // GRAMMAR OF A DEFER STATEMENT
  
  deferStatement: 'defer' codeBlock ;
  
  // GRAMMAR OF A DO STATEMENT
  
  doStatement: 'do' codeBlock catchClauses? ;
  catchClauses: catchClause catchClauses? ;
  catchClause: 'catch' pattern? whereClause? codeBlock ;
  
  conditionList : condition commaCondition* ;
  commaCondition: ',' condition ;
  condition: availabilityCondition | caseCondition | optionalBindingCondition | expression ;
  caseCondition: 'case' pattern initializer ;
  optionalBindingCondition: letORvar pattern initializer ;
  letORvar : 'let' | 'var' ;
  
  whereClause: 'where' whereExpression ;
  whereExpression: expression ;
  
  // GRAMMAR OF AN AVAILABILITY CONDITION
  
  availabilityCondition: '#available' '(' availabilityArguments ')' ;
  availabilityArguments: availabilityArgument commaAvailArgs* ;
  commaAvailArgs : ',' availabilityArguments ;
  availabilityArgument: platformName platformVersion | '*' ;
  platformName: 'iOS' | 'iOSApplicationExtension' | 'OSX' | 'OSXApplicationExtension' | 'watchOS'
   | 'watchOSApplicationExtension' | 'tvOS' | 'tvOSApplicationExtension' ;
  platformVersion: versionLiteral | DecimalLiteral | FloatingPointLiteral ; // TODO: Find a way to make this only versionLiteral
  
  // Generic Parameters and Arguments
  
  // GRAMMAR OF A GENERIC PARAMETER CLAUSE
  
  genericParameterClause : '<' genericParameterList '>'  ;
  genericParameterList : genericParameter commaGenParam* ;
  commGenParam : ',' genericParameter ;
  genericParameter : typeName | typeName ':' typeIdentifier | typeName ':' protocolCompositionType  ;
  genericWhereClause : 'where' requirementList  ;
  requirementList : requirement commaRequirement* ;
  commaRequirement : ',' requirement ;
  requirement : conformanceRequirement | sameTypeRequirement  ;
  conformanceRequirement : typeIdentifier ':' typeIdentifier | typeIdentifier ':' protocolCompositionType  ;
  sameTypeRequirement : typeIdentifier '==' sType  ;
  
  // GRAMMAR OF A GENERIC ARGUMENT CLAUSE
  
  genericArgumentClause : '<' genericArgumentList '>'  ;
  genericArgumentList : genericArgument commaGenericArg* ;
  commaGenericArg : ',' genericArgument ;
  genericArgument : sType  ;
  
  // Declarations
  
  // GRAMMAR OF A DECLARATION
  
  declaration
   : importDeclaration ';'?
   | constantDeclaration ';'?
   | variableDeclaration ';'?
   | typealiasDeclaration ';'?
   | functionDeclaration ';'?
   | enumDeclaration ';'?
   | structDeclaration ';'?
   | classDeclaration ';'?
   | protocolDeclaration ';'?
   | initializerDeclaration ';'?
   | deinitializerDeclaration ';'?
   | extensionDeclaration ';'?
   | subscriptDeclaration ';'?
   | operatorDeclaration ';'?
   // compiler-control-statement not in Swift Language Reference
   | compilerControlStatement ';'?
   | precedenceGroupDeclaration ';'?
   ;
  
  declarations : declaration+ ;
  declarationModifiers : declarationModifier+ ;
  declarationModifier : 'class' | 'convenience' | 'dynamic' | 'final' | 'infix'
   | 'lazy' | 'optional' | 'override' | 'postfix'
   | 'prefix' | 'required' | 'static' | 'unowned' | 'unowned' '(' 'safe' ')'
   | 'unowned' '(' 'unsafe' ')' | 'weak'
   | accessLevelModifier
   | mutationModifier ;
  
  accessLevelModifier : 'private' | 'private' '(' 'set' ')'
   | 'fileprivate' | 'fileprivate' '(' 'set' ')'
   | 'internal' | 'internal' '(' 'set' ')'
   | 'public' | 'public' '(' 'set' ')'
   | 'open' | 'open' '(' 'set' ')' ;
  accessLevelModifiers : accessLevelModifier+ ;
  
  mutationModifier: 'mutating' | 'nonmutating' ;
  
  // GRAMMAR OF A CODE BLOCK
  
  codeBlock : '{' statements? '}'  ;
  
  // GRAMMAR OF AN IMPORT DECLARATION
  
  importDeclaration : attributes? 'import' importKind? importPath  ;
  // Swift Language Reference does not have let
  importKind : 'typealias' | 'struct' | 'class' | 'enum' | 'protocol' | 'var' | 'func' | 'let'  ;
  importPath : importPathIdentifier | importPathIdentifier '.' importPath  ;
  importPathIdentifier : identifier | operator  ;
  
  // GRAMMAR OF A CONSTANT DECLARATION
  
  constantDeclaration : attributes? declarationModifiers? 'let' patternInitializerList  ;
  patternInitializerList : patternInitializer commaPatInit* ;
  commaPatInit : ',' patternInitializer ;
  patternInitializer : pattern initializer? ;
  initializer : '=' expression  ;
  
  // GRAMMAR OF A VARIABLE DECLARATION
  
  variableDeclaration
   : variableDeclarationHead variableName typeAnnotation getterSetterBlock
   | variableDeclarationHead variableName typeAnnotation getterSetterKeywordBlock
   | variableDeclarationHead variableName initializer willSetDidSetBlock
   | variableDeclarationHead variableName typeAnnotation initializer? willSetDidSetBlock
   // keep this below getter and setter rules for ambiguity reasons
   | variableDeclarationHead variableName typeAnnotation codeBlock
   | variableDeclarationHead patternInitializerList
   ;
  
  variableDeclarationHead : attributes? declarationModifiers? 'var'  ;
  variableName : identifier  ;
  getterSetterBlock : '{' getterClause setterClause?'}'  | '{' setterClause getterClause '}'  ;
  // declarationModifiers missing in the Swift Language Reference
  getterClause : attributes? declarationModifiers? 'get' codeBlock  ;
  // declarationModifiers missing in the Swift Language Reference
  setterClause : attributes? declarationModifiers? 'set' setterName? codeBlock  ;
  setterName : '(' identifier ')'  ;
  getterSetterKeywordBlock : '{' getterKeywordClause setterKeywordClause?'}' | '{' setterKeywordClause getterKeywordClause '}'  ;
  getterKeywordClause : attributes? 'get'  ;
  setterKeywordClause : attributes? 'set'  ;
  willSetDidSetBlock : '{' willSetClause didSetClause?'}' | '{' didSetClause willSetClause? '}'  ;
  willSetClause : attributes? 'willSet' setterName? codeBlock  ;
  didSetClause : attributes? 'didSet' setterName? codeBlock  ;
  
  // GRAMMAR OF A TYPE ALIAS DECLARATION
  
  typealiasDeclaration : typealiasHead typealiasAssignment  ;
  typealiasHead : attributes? accessLevelModifier? 'typealias' typealiasName genericParameterClause?  ;
  typealiasName : identifier  ;
  typealiasAssignment : '=' sType  ;
  
  // GRAMMAR OF A FUNCTION DECLARATION
  
  // HACK: functionBody? is intentionally not used to force the parser to try and match a functionBody first
  // This can be removed once we figure out how to enforce that statements are either separated by semi colons or new line characters
  
  functionDeclaration : functionHead functionName genericParameterClause? functionSignature genericWhereClause? functionBody
   | functionHead functionName genericParameterClause? functionSignature genericWhereClause?
   ;
  
  functionHead : attributes? declarationModifiers? 'func'  ;
  functionName : identifier |  operator  ;
  // rethrows is not marked as optional in the Swift Language Reference
  functionSignature : parameterClause throwsORrethrows? functionResult? ;
  throwsORrethrows : 'throws' | 'rethrows' ;
  functionResult : '->' attributes? sType  ;
  functionBody : codeBlock  ;
  parameterClause : '(' ')' |  '(' parameterList '...'? ')'  ;
  parameterList : parameter commaParameter* ;
  commaParameter : ',' parameter ;
  // Parameters don't have attributes in the Swift Language Reference
  parameter
   : attributes? externalParameterName? localParameterName typeAnnotation defaultArgumentClause?
   | attributes? externalParameterName? localParameterName typeAnnotation '...'
   ;
  // Swift Language Reference does not have "keyword" or "_"
  externalParameterName : identifier | keyword | '_';
  localParameterName : identifier | '_' ;
  defaultArgumentClause : '=' expression  ;
  
  // GRAMMAR OF AN ENUMERATION DECLARATION
  
  enumDeclaration : attributes? accessLevelModifier? enumDef  ;
  enumDef: unionStyleEnum | rawValueStyleEnum  ;
  unionStyleEnum : 'indirect'? 'enum' enumName genericParameterClause? typeInheritanceClause? genericWhereClause? '{' unionStyleEnumMembers?'}'  ;
  unionStyleEnumMembers : unionStyleEnumMember+ ;
  unionStyleEnumMember : declaration | unionStyleEnumCaseClause ';'? | compilerControlStatement ;
  unionStyleEnumCaseClause : attributes? 'indirect'? 'case' unionStyleEnumCaseList  ;
  unionStyleEnumCaseList : unionStyleEnumCase commanUnionStyleEnumCase* ;
  commaUnionStyleEnumCase : ',' unionStyleEnumCase ;
  unionStyleEnumCase : enumCaseName tupleType? ;
  enumName : identifier  ;
  enumCaseName : identifier  ;
  // typeInheritanceClause is not optional in the Swift Language Reference
  rawValueStyleEnum : 'enum' enumName genericParameterClause? typeInheritanceClause? genericWhereClause? '{' rawValueStyleEnumMembers?'}'  ;
  rawValueStyleEnumMembers : rawValueStyleEnumMember+ ;
  rawValueStyleEnumMember : declaration | rawValueStyleEnumCaseClause | compilerControlStatement  ;
  rawValueStyleEnumCaseClause : attributes? 'case' rawValueStyleEnumCaseList  ;
  rawValueStyleEnumCaseList : rawValueStyleEnumCase commaRawValueStyleEnumCase* ;
  commaRawValueStyleEnumCase : ',' rawValueStyleEnumCase ;
  rawValueStyleEnumCase : enumCaseName rawValueAssignment? ;
  rawValueAssignment : '=' literal  ;
  
  // GRAMMAR OF A STRUCTURE DECLARATION
  
  structDeclaration : attributes? accessLevelModifier? 'struct' structName genericParameterClause? typeInheritanceClause? genericWhereClause? structBody  ;
  structName : identifier  ;
  structBody : '{' structMembers? '}'  ;
  structMembers: structMember+ ;
  structMember: declaration | compilerControlStatement ;
  
  // GRAMMAR OF A CLASS DECLARATION
  
  classDeclaration : attributes? classDeclarationModifiers? 'class' className genericParameterClause? typeInheritanceClause? genericWhereClause? classBody  ;
  classDeclarationModifiers: accessLevelModifier 'final'? | 'final' accessLevelModifier? ;
  className : identifier ;
  classBody : '{' classMembers? '}'  ;
  classMembers: classMember+ ;
  classMember: declaration | compilerControlStatement ;
  
  // GRAMMAR OF A PROTOCOL DECLARATION
  
  protocolDeclaration : attributes? accessLevelModifier? 'protocol' protocolName typeInheritanceClause? protocolBody  ;
  protocolName : identifier  ;
  protocolBody : '{' protocolMembers? '}'  ;
  protocolMembers: protocolMember+ ;
  protocolMember: protocolMemberDeclaration | compilerControlStatement ;
  protocolMemberDeclaration : protocolPropertyDeclaration ';'?
   | protocolMethodDeclaration ';'?
   | protocolInitializerDeclaration ';'?
   | protocolSubscriptDeclaration ';'?
   | protocolAssociatedTypeDeclaration ';'?
   ;
  
  // GRAMMAR OF A PROTOCOL PROPERTY DECLARATION
  
  protocolPropertyDeclaration : variableDeclarationHead variableName typeAnnotation getterSetterKeywordBlock  ;
  
  // GRAMMAR OF A PROTOCOL METHOD DECLARATION
  
  protocolMethodDeclaration : functionHead functionName genericParameterClause? functionSignature genericWhereClause?  ;
  
  // GRAMMAR OF A PROTOCOL INITIALIZER DECLARATION
  
  protocolInitializerDeclaration : initializerHead genericParameterClause? parameterClause throwsORrethrows? genericWhereClause? ;
  
  // GRAMMAR OF A PROTOCOL SUBSCRIPT DECLARATION
  
  protocolSubscriptDeclaration : subscriptHead subscriptResult getterSetterKeywordBlock  ;
  
  // GRAMMAR OF A PROTOCOL ASSOCIATED TYPE DECLARATION
  
  protocolAssociatedTypeDeclaration : attributes? accessLevelModifier? 'associatedtype' typealiasName typeInheritanceClause? typealiasAssignment?;
  
  // GRAMMAR OF AN INITIALIZER DECLARATION
  
  initializerDeclaration : initializerHead genericParameterClause? parameterClause throwsORrethrows? genericWhereClause? initializerBody  ;
  initializerHead : attributes? declarationModifiers? 'init' questORbang? ;
  questORbang : '?' | '!' ;
  initializerBody : codeBlock  ;
  
  // GRAMMAR OF A DEINITIALIZER DECLARATION
  
  deinitializerDeclaration : attributes? 'deinit' codeBlock  ;
  
  // GRAMMAR OF AN EXTENSION DECLARATION
  
  extensionDeclaration : attributes? accessLevelModifier? 'extension' typeIdentifier genericORtypeInherit? extensionBody  ;
  genericORtypeInherit : genericWhereClause | typeInheritanceClause ;
  extensionBody : '{' extensionMembers?'}'  ;
  extensionMembers: extensionMember+ ;
  extensionMember: declaration | compilerControlStatement ;
  
  // GRAMMAR OF A SUBSCRIPT DECLARATION
  
  subscriptDeclaration : subscriptHead subscriptResult getterSetterBlock
   | subscriptHead subscriptResult getterSetterKeywordBlock
   // most general form of subscript declaration; should be kept at the bottom.
   | subscriptHead subscriptResult codeBlock
   ;
  subscriptHead : attributes? declarationModifiers? 'subscript' parameterClause  ;
  subscriptResult : '->' attributes? sType  ;
  
  // GRAMMAR OF AN OPERATOR DECLARATION
  
  operatorDeclaration : prefixOperatorDeclaration | postfixOperatorDeclaration | infixOperatorDeclaration  ;
  prefixOperatorDeclaration : 'prefix' 'operator' operator  ;
  postfixOperatorDeclaration : 'postfix' 'operator' operator  ;
  infixOperatorDeclaration : 'infix' 'operator' operator infixOperatorGroup? ;
  infixOperatorGroup: ':' precedenceGroupName ;
  
  
  // GRAMMAR OF A PRECEDENCE GROUP DECLARATION
  
  precedenceGroupDeclaration: 'precedencegroup' precedenceGroupName '{' precedenceGroupAttributes? '}' ;
  
  precedenceGroupAttributes: precedenceGroupAttribute+;
  precedenceGroupAttribute: precedenceGroupRelation | precedenceGroupAssignment | precedenceGroupAssociativity ;
  precedenceGroupRelation: higherORlower ':' precedenceGroupNames;
  higherORlower : 'higherThan' | 'lowerThan' ;
  precedenceGroupAssignment: 'assignment' ':' booleanLiteral ;
  precedenceGroupAssociativity: 'associativity' ':' lrn ;
  lrn : 'left' | 'right' | 'none' ;
  
  precedenceGroupNames: precedenceGroupName commaPrecGN* ;
  commaPrecGN : ',' precedenceGroupName ;
  precedenceGroupName: identifier ;
  
  
  // Patterns
  
  
  // GRAMMAR OF A PATTERN
  
  pattern
   : wildcardPattern typeAnnotation?
   | identifierPattern typeAnnotation?
   | valueBindingPattern
   | tuplePattern typeAnnotation?
   | enumCasePattern
   | 'is' sType
   | pattern 'as' sType
   | expressionPattern
   ;
  
  // GRAMMAR OF A WILDCARD PATTERN
  
  wildcardPattern : '_'  ;
  
  // GRAMMAR OF AN IDENTIFIER PATTERN
  
  identifierPattern : identifier  ;
  
  // GRAMMAR OF A VALUE_BINDING PATTERN
  
  valueBindingPattern : 'var' pattern | 'let' pattern  ;
  
  // GRAMMAR OF A TUPLE PATTERN
  
  tuplePattern : '(' tuplePatternElementList? ')'  ;
  tuplePatternElementList : tuplePatternElement commaTupPatElem* ;
  commaTypPatElem : ',' tuplePatternElement ;
  tuplePatternElement : pattern | identifier ':' pattern ;
  
  // GRAMMAR OF AN ENUMERATION CASE PATTERN
  
  // Swift Language Reference has '.' as mandatory
  enumCasePattern : typeIdentifier? '.'? enumCaseName tuplePattern? ;
  
  // GRAMMAR OF A TYPE CASTING PATTERN
  
  typeCastingPattern : isPattern | asPattern  ;
  isPattern : 'is' sType  ;
  asPattern : pattern 'as' sType  ;
  
  // GRAMMAR OF AN EXPRESSION PATTERN
  
  expressionPattern : expression  ;
  
  // Attributes
  
  // GRAMMAR OF AN ATTRIBUTE
  
  attribute : '@' attributeName attributeArgumentClause? ;
  attributeName : identifier ;
  attributeArgumentClause : '('  balancedTokens?  ')'  ;
  attributes : attribute+ ;
  // Swift Language Reference does not have ','
  balancedTokens : balancedToken+ ;
  balancedToken
   : '('  balancedTokens? ')'
   | '[' balancedTokens? ']'
   | '{' balancedTokens? '}'
   // versionLiteral and availabilityArgument are not in the Swift Language Reference
   | identifier | expression | contextSensitiveKeyword | literal | operator | versionLiteral | availabilityArgument
   // | Any punctuation except ( ,  ')' , '[' , ']' , { , or }
   // Punctuation is very ambiguous, interpreting punctuation as defined in www.thepunctuationguide.com
   | ':' | ';' | ',' | '!' | '<' | '>' | '-' | '\'' | '/' | '...' | '"'
   ;
  
  // Expressions
  
  // GRAMMAR OF AN EXPRESSION
  
  expression : tryOperator? prefixExpression binaryExpression* ;
  
  prefixExpression
    : prefixOperator? postfixExpression ';'?
    | inOutExpression
    ;
  
  // /*
  // expression
  //  : prefixOperator expression
  //  | inOutExpression
  //  | primaryExpression
  //  | expression binaryOperator expression
  //  | expression assignmentOperator expression
  //  | expression conditionalOperator expression
  //  | expression typeCastingOperator
  //  | expression postfixOperator
  //  | expression parenthesizedExpression trailingClosure?
  //  | expression '.' 'init'
  //  | expression '.' DecimalLiteral
  //  | expression '.' identifier genericArgumentClause?
  //  | expression '.' 'self'
  //  | expression '.' 'dynamicType'
  //  | expression '[' expressionList ']'
  //  | expression '!'
  //  | expression '?'
  //  ;
  // */
  
  // GRAMMAR OF A PREFIX EXPRESSION
  
  inOutExpression : '&' identifier ;
  
  // GRAMMAR OF A TRY EXPRESSION
  
  tryOperator : 'try' questORbang? ;
  
  // GRAMMAR OF A BINARY EXPRESSION
  
  binaryExpression
    : binaryOperator prefixExpression
    | assignmentOperator tryOperator? prefixExpression
    | conditionalOperator tryOperator? prefixExpression
    | typeCastingOperator
    ;
  
  // GRAMMAR OF AN ASSIGNMENT OPERATOR
  
  assignmentOperator : '='  ;
  
  // GRAMMAR OF A CONDITIONAL OPERATOR
  
  conditionalOperator : '?' tryOperator? expression ':' ;
  
  // GRAMMAR OF A TYPE_CASTING OPERATOR
  
  typeCastingOperator
    : 'is' sType
    | 'as' '?' sType
    | 'as' sType
    | 'as' '!' sType
    ;
  
  // GRAMMAR OF A PRIMARY EXPRESSION
  
  id_op_key_OR_cont : identifier | operator | keyword | contextSensitiveKeyword ;
  
  primaryExpression
   : id_op_key_OR_cont genericArgumentClause? // operator, keyword, and contextSensitiveKeyword are not mentioned in the Swift Language Reference
   | literalExpression
   | selfExpression
   | superclassExpression
   | closureExpression
   | parenthesizedExpression
   | tupleExpression
   | implicitMemberExpression
  // | implicit_member_expression disallow as ambig with explicit member expr in postfix_expression
   | wildcardExpression
   | selectorExpression
   | keyPathExpression
   ;
  
  // GRAMMAR OF A LITERAL EXPRESSION
  
  literalExpression
   : literal
   | arrayLiteral
   | dictionaryLiteral
   | playgroundLiteral
   | '#file' | '#line' | '#column' | '#function'
   ;
  
  comma : ',' ;
  
  arrayLiteral : '[' arrayLiteralItems? ']'  ;
  arrayLiteralItems : arrayLiteralItem commaArrayLiteralItem* comma?  ;
  commaArrayLiteralItem : ',' arrayLiteralItem ;
  arrayLiteralItem : expression ;
  
  dictionaryLiteral : '[' dictionaryLiteralItems ']' | '[' ':' ']'  ;
  dictionaryLiteralItems : dictionaryLiteralItem commaDictLitItem* comma? ;
  commaDictLitItem : ',' dictionaryLiteralItem ;
  dictionaryLiteralItem : expression ':' expression  ;
  
  playgroundLiteral: '#colorLiteral' '(' 'red' ':' expression ',' 'green' ':' expression ',' 'blue' ':' expression ',' 'alpha' ':' expression ')'
   | '#fileLiteral' '(' 'resourceName' ':' expression ')'
   | '#imageLiteral' '(' 'resourceName' ':' expression ')' ;
  
  // GRAMMAR OF A SELF EXPRESSION
  
  selfExpression
   : 'self'
   | 'self' '.' identifier  // self-method-expression
   // Swift Language Reference uses expressionList
   | 'self' '[' tupleElementList ']'  // self-subscript-expression
   | 'self' '.' 'init' // self-initializer-expression
   ;
  
  // GRAMMAR OF A SUPERCLASS EXPRESSION
  
  superclassExpression
    : superclassMethodExpression
    | superclassSubscriptExpression
    | superclassInitializerExpression
    ;
  
  superclassMethodExpression : 'super' '.' identifier  ;
  // Swift Language Reference uses expressionList
  superclassSubscriptExpression : 'super' '[' tupleElementList ']'  ;
  superclassInitializerExpression : 'super' '.' 'init'  ;
  
  // GRAMMAR OF A CLOSURE EXPRESSION
  
  closureExpression : '{' closureSignature? statements? '}'  ;
  
  closureSignature
   : captureList? closureParameterClause 'throws'? functionResult? 'in'
   | captureList 'in'
   ;
  
  closureParameterClause: '(' ')' | '(' closureParameterList ')' | identifierList ;
  closureParameterList: closureParameter commaClosureParameterList* ;
  commaClosureParameterList : ',' closureParameterList ;
  closureParameter: closureParameterName typeAnnotation?
   | closureParameterName typeAnnotation '...'
   ;
  // Swift Language Reference does not have "_"
  closureParameterName: identifier | '_';
  
  captureList : '[' captureListItems ']' ;
  captureListItems: captureListItem commaCaptureListItem* ;
  commaCaptureListItem : ',' captureListItem ;
  captureListItem: captureSpecifier? expression ;
  captureSpecifier : 'weak' | 'unowned' | 'unowned(safe)' | 'unowned(unsafe)'  ;
  
  // GRAMMAR OF A IMPLICIT MEMBER EXPRESSION
  
  implicitMemberExpression : '.' identifier  ;
  
  // GRAMMAR OF A PARENTHESIZED EXPRESSION
  
  parenthesizedExpression : '(' expression ')'  ;
  
  // GRAMMAR OF A TUPLE EXPRESSION
  
  tupleExpression: '(' tupleElementList? ')' ;
  tupleElementList: tupleElement commaTupleElement* ;
  commaTupleElement : ',' tupleElement ;
  tupleElement: identifierColon? expression ;
  identifierColon : identifier ':' ;
  
  // GRAMMAR OF A WILDCARD EXPRESSION
  
  wildcardExpression : '_'  ;
  
  // GRAMMAR OF A SELECTOR EXPRESSION
  
  selectorExpression
   : '#selector' '(' expression ')'
   | '#selector' '(' getterORsetter expression ')'
   ;
  getterORsetter : 'getter:' | 'setter:' ;
  
  // GRAMMAR OF A KEY PATH EXPRESSION
  
  keyPathExpression
   : '#keyPath' '(' expression ')' 
   | Backslash expression
   ;
  
  Backslash : '[\\]' ;
  
  // GRAMMAR OF A POSTFIX EXPRESSION
  
  postfixExpression
   : primaryExpression
   | postfixExpression postfixOperator
   // Function call with closure expression should always be above a lone parenthesized expression to reduce ambiguity
   | postfixExpression functionCallArgumentClause? closureExpression
   | postfixExpression functionCallArgumentClause
   | postfixExpression '.' 'init'
   | postfixExpression '.' 'init' '(' argumentNames ')'
   // TODO: don't allow '_' here in DecimalLiteral:
   | postfixExpression '.' DecimalLiteral
   | postfixExpression '.' identifier genericArgumentClause?
   | postfixExpression '.' identifier '(' argumentNames ')'
   | postfixExpression '.' 'self'
   | 'type' '(' 'of' ':' expression ')'
   // Swift Language Reference uses expressionList
   | postfixExpression '[' tupleElementList ']'
   | postfixExpression '!'
   | postfixExpression '?'
   ;
  
  // GRAMMAR OF A FUNCTION CALL EXPRESSION
  functionCallArgumentClause: '(' functionCallArgumentList? ')' ;
  functionCallArgumentList: functionCallArgument commaFuncCallArg* ;
  commaFuncCallArg : ',' functionCallArgument ;
  // (expression | operator) is optional to handle selector expressions (see #425 for example)
  functionCallArgument: functionCallIDColon expORop?
    | functionCallIDColon? expORop? ;
  expORop : expression | operator ;
  functionCallIDColon : functionCallIdentifier ':' ;
  // SwiftLanguageReference does not have keyword
  functionCallIdentifier: identifier | keyword ;
  
  // GRAMMAR OF AN ARGUMENT NAME
  argumentNames : argumentName+  ;
  argumentName: idORunder ':'  ; // Swift Language Reference has argumentName → identifier :
  idORunder : identifier | '_' ;
  
  //trailing_closure : closure_expression  ;
  
  //initializer_expression : postfix_expression '.' 'init' ;
  
  // /*
  // explicitMemberExpression
  //   : postfixExpression '.' DecimalLiteral // TODO: don't allow '_' here in DecimalLiteral
  //   | postfixExpression '.' identifier genericArgumentClause?
  //   | postfixExpression '.' identifier '(' argumentNames ')'
  //   ;
  // */
  
  //postfix_self_expression : postfix_expression '.' 'self' ;
  
  // GRAMMAR OF A DYNAMIC TYPE EXPRESSION
  
  //dynamic_type_expression : postfix_expression '.' 'dynamicType' ;
  
  // GRAMMAR OF A SUBSCRIPT EXPRESSION
  
  //subscript_expression : postfix_expression '[' expression_list ']' ;
  
  // GRAMMAR OF A FORCED_VALUE EXPRESSION
  
  //forced_value_expression : postfix_expression '!' ;
  
  // GRAMMAR OF AN OPTIONAL_CHAINING EXPRESSION
  
  //optional_chaining_expression : postfix_expression '?' ;
  
  // GRAMMAR OF OPERATORS
  
  // split the operators out into the individual tokens as some of those tokens
  // are also referenced individually. For example, type signatures use
  // <...>.
  
  operatorHead: '=' | '<' | '>' | '!' | '*' | '&' | '==' | '?' | '-' | '&&' | '||' | '/' | '>=' | '->' | OperatorHead;
  operatorCharacter: operatorHead | OperatorCharacter;
  
  operator: operatorHead operatorCharacter*
    | '..' operatorCharacter*
    | '...'
    ;
  
  // WHITESPACE scariness:
  
  // /* http://tinyurl.com/oalzfus
  // "If an operator has no whitespace on the left but is followed
  // immediately by a dot (.), it is treated as a postfix unary
  // operator. As an example, the ++ operator in a++.b is treated as a
  // postfix unary operator (a++ . b rather than a ++ .b).  For the
  // purposes of these rules, the characters (, [, and { before an
  // operator, the characters ), ], and } after an operator, and the
  // characters ,, ;, and : are also considered whitespace.
  // 
  // There is one caveat to the rules above. If the ! or ? operator has no
  // whitespace on the left, it is treated as a postfix operator,
  // regardless of whether it has whitespace on the right. To use the ?
  // operator as syntactic sugar for the Optional type, it must not have
  // whitespace on the left. To use it in the conditional (? :) operator,
  // it must have whitespace around both sides."
  //  */
  // 
  // /**
  //  "If an operator has whitespace around both sides or around neither side,
  //  it is treated as a binary operator. As an example, the + operator in a+b
  //   and a + b is treated as a binary operator."
  // */
  binaryOperator : operator ;
  
  // /**
  //  "If an operator has whitespace on the left side only, it is treated as a
  //  prefix unary operator. As an example, the ++ operator in a ++b is treated
  //  as a prefix unary operator."
  // */
  prefixOperator : operator  ; // only if space on left but not right
  
  // /**
  //  "If an operator has whitespace on the right side only, it is treated as a
  //  postfix unary operator. As an example, the ++ operator in a++ b is treated
  //  as a postfix unary operator."
  //  */
  postfixOperator : operator  ;
  
  // Types
  
  // GRAMMAR OF A TYPE
  
  sType
   : arrayType
   | dictionaryType
   | functionType
   | typeIdentifier
   | tupleType
   | sType '?'  // optional-type
   | sType '!'  // implicitly-unwrapped-optional-type
   | protocolCompositionType
   | sType '.' 'Type' | sType '.' 'Protocol' // metatype
   | 'Any' | 'Self'
   ;
  
  functionType: attributes? functionTypeArgumentClause throwsORrethrows? '->' sType ;
  functionTypeArgumentClause: '(' ')'
   | '(' functionTypeArgumentList '...'? ')' ;
  functionTypeArgumentList: functionTypeArgument commaFunctionTypeArg* ;
  commaFunctionTypeArg : ',' functionTypeArgument ;
  functionTypeArgument: attributes? 'inout'? sType | argumentLabel typeAnnotation ;
  argumentLabel: identifier ;
  
  arrayType: '[' sType ']' ;
  
  dictionaryType: '[' sType ':' sType ']' ;
  
  optionalType: sType '?' ;
  
  implicitlyUnwrappedOptionalType: sType '!' ;
  
  // GRAMMAR OF A TYPE ANNOTATION
  
  typeAnnotation : ':' attributes? 'inout'? sType  ;
  
  // GRAMMAR OF A TYPE IDENTIFIER
  
  typeIdentifier
   : typeName genericArgumentClause?
   | typeName genericArgumentClause? '.' typeIdentifier
   ;
  
  typeName : identifier ;
  
  // GRAMMAR OF A TUPLE TYPE
  
  tupleType : '('  tupleTypeElementList? ')'  ;
  tupleTypeElementList : tupleTypeElement commaTupleTypeElement* ;
  commaTupleTypeElement : ',' tupleTypeElement ;
  tupleTypeElement : elementName typeAnnotation | sType ;
  elementName : identifier  ;
  
  // GRAMMAR OF A PROTOCOL COMPOSITION TYPE
  
  protocolCompositionType: protocolIdentifier '&' protocolCompositionContinuation ;
  protocolCompositionContinuation: protocolIdentifier | protocolCompositionType ;
  protocolIdentifier: typeIdentifier ;
  
  // GRAMMAR OF A METATYPE TYPE
  
  metatypeType : sType '.' 'Type' | sType '.' 'Protocol';
  
  // GRAMMAR OF A TYPE INHERITANCE CLAUSE
  
  typeInheritanceClause : ':' classRequirement ',' typeInheritanceList
   | ':' classRequirement
   | ':' typeInheritanceList
   ;
  typeInheritanceList : typeIdentifier commaTypeID* ;
  commaTypeID : ',' typeIdentifier ;
  classRequirement: 'class' ;
  
  // GRAMMAR OF A COMPILER CONTROL STATEMENT
  
  compilerControlStatement: conditionalCompilationBlock | lineControlStatement ;
  
  // GRAMMAR OF A CONDITIONAL COMPILATION BLOCK
  
  conditionalCompilationBlock: ifDirectiveClause elseifDirectiveClauses? elseDirectiveClause? '#endif' ;
  ifDirectiveClause: '#if' compilationCondition statements? ;
  elseifDirectiveClauses: elseifDirectiveClause+ ;
  elseifDirectiveClause: '#elseif' compilationCondition statements? ;
  elseDirectiveClause: '#else' statements? ;
  
  compilationCondition
   : platformCondition
   | identifier
   | booleanLiteral
   | '(' compilationCondition ')'
   | '!' compilationCondition
   | compilationCondition andORor compilationCondition
   ;
  
  andORor : '&&' | '||' ;
  
  platformCondition
   : 'os' '(' operatingSystem ')'
   | 'arch' '(' architecture ')'
   | 'swift' '(' '>=' swiftVersion ')'
   ;
  
  operatingSystem: 'OSX' | 'iOS' | 'watchOS' | 'tvOS' ;
  architecture: 'i386' | 'x86_64' | 'arm' | 'arm64' ;
  swiftVersion: FloatingPointLiteral ;
  
  lineControlStatement: '#sourceLocation' '(' 'file' ':' fileName ',' 'line' ':' lineNumber ')'
   | '#sourceLocation' '(' ')' ;
  lineNumber: integerLiteral ;
  fileName: StringLiteral ;
  
  // ---------- Lexical Structure -----------
  
  BooleanLiteral: 'true' | 'false' ;
  NilLiteral: 'nil' ;
  
  // GRAMMAR OF AN IDENTIFIER
  
  identifier : Identifier | contextSensitiveKeyword | grammarString ;
  
  keyword :
   // Keywords used in declarations
   'associatedtype' | 'class' | 'deinit' | 'enum' | 'extension' | 'fileprivate' | 'func' | 'import' | 'init' | 'inout'
   | 'internal' | 'let' | 'open' | 'operator' | 'private' | 'protocol' | 'public' | 'static' | 'struct' | 'subscript'
   | 'typealias' | 'var'
   // Keywords used in statements
   | 'break' | 'case' | 'continue' | 'default' | 'defer' | 'do' | 'else' | 'fallthrough' | 'for' | 'guard' | 'if' | 'in'
   | 'repeat' | 'return' | 'switch' | 'where' | 'while'
   // Keywords used in expressions and types
   | 'as' | 'Any' | 'catch' | 'dynamicType' | 'is' | 'nil' | 'rethrows' | 'super' | 'self' | 'Self' | 'throw'
   | 'throws' | 'try'
   | BooleanLiteral
   // Keywords used in patterns
   | '_'
   // Keywords that begin with a number sign (#)
   | '#available' | '#colorLiteral' | '#column' | '#else' | '#elseif' | '#endif' | '#file' | 'fileLiteral' | '#function'
   | '#if' | 'imageLiteral' | '#line' | '#selector'
   ;
  
  contextSensitiveKeyword :
   'associativity' | 'convenience' | 'dynamic' | 'didSet' | 'final' | 'get' | 'infix' | 'indirect' |
   'lazy' | 'left' | 'mutating' | 'none' | 'nonmutating' | 'optional' | 'operator' | 'override' | 'postfix' | 'precedence' |
   'prefix' | 'Protocol' | 'required' | 'right' | 'set' | 'Type' | 'unowned' | 'weak' | 'willSet' |
   'iOS' | 'iOSApplicationExtension' | 'OSX' | 'OSXApplicationExtension­' | 'watchOS' | 'x86_64' |
   'arm' | 'arm64' | 'i386' | 'os' | 'arch' | 'safe' | 'tvOS' | 'file' | 'line' | 'default' | 'Self' | 'var'
   ;
  
  grammarString:
    'red' | 'blue' | 'green' | 'alpha' | 'resourceName' | 'of' | 'type' ;
  
  OperatorHead
    : '/' | '=' | '-' | '+' | '!' | '*' | '%' | '<' | '>' | '&' | '|' | '^' | '~' | '?'
    | [\u00A1-\u00A7]
    | [\u00A9\u00AB\u00AC\u00AE]
    | [\u00B0-\u00B1\u00B6\u00BB\u00BF\u00D7\u00F7]
    | [\u2016-\u2017\u2020-\u2027]
    | [\u2030-\u203E]
    | [\u2041-\u2053]
    | [\u2055-\u205E]
    | [\u2190-\u23FF]
    | [\u2500-\u2775]
    | [\u2794-\u2BFF]
    | [\u2E00-\u2E7F]
    | [\u3001-\u3003]
    | [\u3008-\u3030]
    ;
  
  OperatorCharacter
    : OperatorHead
    | [\u0300–\u036F]
    | [\u1DC0–\u1DFF]
    | [\u20D0–\u20FF]
    | [\uFE00–\uFE0F]
    | [\uFE20–\uFE2F]
    //| [\uE0100–\uE01EF]  ANTLR can't do >16bit char
    ;
  
  DotOperatorHead
    : '..'
    ;
  
  Identifier : IdentifierHead IdentifierCharacters?
   | '`' IdentifierHead IdentifierCharacters? '`'
   | ImplicitParameterName
   ;
  
  identifierList : idORunder comma_idORunder*  ;
  comma_idORunder : ',' idORunder ;
  
  fragment IdentifierHead : [a-zA-Z] | '_'
   | '\u00A8' | '\u00AA' | '\u00AD' | '\u00AF' | [\u00B2-\u00B5] | [\u00B7-\u00BA]
   | [\u00BC-\u00BE] | [\u00C0-\u00D6] | [\u00D8-\u00F6] | [\u00F8-\u00FF]
   | [\u0100-\u02FF] | [\u0370-\u167F] | [\u1681-\u180D] | [\u180F-\u1DBF]
   | [\u1E00-\u1FFF]
   | [\u200B-\u200D] | [\u202A-\u202E] | [\u203F-\u2040] | '\u2054' | [\u2060-\u206F]
   | [\u2070-\u20CF] | [\u2100-\u218F] | [\u2460-\u24FF] | [\u2776-\u2793]
   | [\u2C00-\u2DFF] | [\u2E80-\u2FFF]
   | [\u3004-\u3007] | [\u3021-\u302F] | [\u3031-\u303F] | [\u3040-\uD7FF]
   | [\uF900-\uFD3D] | [\uFD40-\uFDCF] | [\uFDF0-\uFE1F] | [\uFE30-\uFE44]
   | [\uFE47-\uFFFD]
  // /*
  //  | U+10000–U+1FFFD | U+20000–U+2FFFD | U+30000–U+3FFFD | U+40000–U+4FFFD
  //  | U+50000–U+5FFFD | U+60000–U+6FFFD | U+70000–U+7FFFD | U+80000–U+8FFFD
  //  | U+90000–U+9FFFD | U+A0000–U+AFFFD | U+B0000–U+BFFFD | U+C0000–U+CFFFD
  //  | U+D0000–U+DFFFD or U+E0000–U+EFFFD
  // */
   ;
  
  fragment IdentifierCharacter : [0-9]
   | [\u0300-\u036F] | [\u1DC0-\u1DFF] | [\u20D0-\u20FF] | [\uFE20-\uFE2F]
   | IdentifierHead
   ;
  
  fragment IdentifierCharacters : IdentifierCharacter+ ;
  
  ImplicitParameterName : '$' DecimalLiteral ; // TODO: don't allow '_' here
  
  // GRAMMAR OF A LITERAL
  
  booleanLiteral: BooleanLiteral ;
  literal : numericLiteral | StringLiteral | BooleanLiteral | NilLiteral ;
  
  // GRAMMAR OF AN INTEGER LITERAL
  
  numericLiteral: '-'? integerLiteral | '-'? FloatingPointLiteral ;
  
  integerLiteral
   : BinaryLiteral
   | OctalLiteral
   | DecimalLiteral
   | HexadecimalLiteral
   ;
  
  BinaryLiteral : '0b' BinaryDigit BinaryLiteralCharacters? ;
  fragment BinaryDigit : [01] ;
  fragment BinaryLiteralCharacter : BinaryDigit | '_'  ;
  fragment BinaryLiteralCharacters : BinaryLiteralCharacter+ ;
  
  OctalLiteral : '0o' OctalDigit OctalLiteralCharacters? ;
  fragment OctalDigit : [0-7] ;
  fragment OctalLiteralCharacter : OctalDigit | '_'  ;
  fragment OctalLiteralCharacters : OctalLiteralCharacter+ ;
  
  DecimalLiteral : DecimalDigit DecimalLiteralCharacters? ;
  fragment DecimalDigit : [0-9] ;
  fragment DecimalDigits : DecimalDigit+ ;
  fragment DecimalLiteralCharacter : DecimalDigit | '_'  ;
  fragment DecimalLiteralCharacters : DecimalLiteralCharacter+ ;
  HexadecimalLiteral : '0x' HexadecimalDigit HexadecimalLiteralCharacters? ;
  fragment HexadecimalDigit : [0-9a-fA-F] ;
  fragment HexadecimalLiteralCharacter : HexadecimalDigit | '_'  ;
  fragment HexadecimalLiteralCharacters : HexadecimalLiteralCharacter+ ;
  
  // GRAMMAR OF A FLOATING_POINT LITERAL
  
  FloatingPointLiteral
   : DecimalLiteral DecimalFraction? DecimalExponent?
   | HexadecimalLiteral HexadecimalFraction? HexadecimalExponent
   ;
  fragment DecimalFraction : '.' DecimalLiteral ;
  fragment DecimalExponent : FloatingPointE Sign? DecimalLiteral ;
  fragment HexadecimalFraction : '.' HexadecimalLiteral? ;
  fragment HexadecimalExponent : FloatingPointP Sign? HexadecimalLiteral ;
  fragment FloatingPointE : [eE] ;
  fragment FloatingPointP : [pP] ;
  fragment Sign : [+\-] ;
  
  versionLiteral: DecimalLiteral DecimalFraction DecimalFraction ;
  
  // GRAMMAR OF A STRING LITERAL
  
  StringLiteral : '"' QuotedText? '"' ;
  fragment QuotedText : QuotedTextItem+ ;
  fragment QuotedTextItem : EscapedCharacter | InterpolatedString
  // | '\\(' expression ')'
   | ~["\\\u000A\u000D]
   ;
  fragment InterpolatedString: '\\(' (QuotedTextItem | StringLiteral)* ')';
  
  EscapedCharacter : '\\' [0\\tnr"']
   | '\\x' HexadecimalDigit HexadecimalDigit
   | '\\u' '{' HexadecimalDigit HexadecimalDigit? HexadecimalDigit? HexadecimalDigit? HexadecimalDigit? HexadecimalDigit? HexadecimalDigit? HexadecimalDigit? '}'
  ;
  
  WS : [ \n\r\t\u000B\u000C\u0000] -> channel(HIDDEN) ;
  
  // /* Added optional newline character to prevent the whitespace lexer rule from matching newline
  //  * at the end of the comment. This affects how blank lines are counted around functions.
  //  */
  BlockComment : '/*' (BlockComment|.)*? '*/' '\n'? -> channel(HIDDEN) ; // nesting allow
  
  LineComment : '//' .*? '\n' -> channel(HIDDEN) ;
  
  |]
  
  --isWS T_WS = True
  --isWS _ = False
  
  