From 6bb13338651c2427d27ee818aa802b68da8e8d3e Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Fri, 23 Oct 2020 17:48:00 -0700 Subject: [PATCH 1/6] Add ANTLR grammar --- .../Language/5_Grammar/QSharpLexer.g4 | 190 +++++++++++++ .../Language/5_Grammar/QSharpParser.g4 | 261 ++++++++++++++++++ Specifications/Language/5_Grammar/README.md | 7 + Specifications/Language/README.md | 1 + 4 files changed, 459 insertions(+) create mode 100644 Specifications/Language/5_Grammar/QSharpLexer.g4 create mode 100644 Specifications/Language/5_Grammar/QSharpParser.g4 create mode 100644 Specifications/Language/5_Grammar/README.md diff --git a/Specifications/Language/5_Grammar/QSharpLexer.g4 b/Specifications/Language/5_Grammar/QSharpLexer.g4 new file mode 100644 index 0000000..0abc948 --- /dev/null +++ b/Specifications/Language/5_Grammar/QSharpLexer.g4 @@ -0,0 +1,190 @@ +lexer grammar QSharpLexer; + +// Keywords + +Adj : 'Adj'; +AdjointFunctor : 'Adjoint'; +AdjointGenerator : 'adjoint'; +And : 'and'; +Apply : 'apply'; +As : 'as'; +Auto : 'auto'; +BigInt : 'BigInt'; +Body : 'body'; +Bool : 'Bool'; +Borrowing : 'borrowing'; +ControlledFunctor : 'Controlled'; +ControlledGenerator : 'controlled'; +Ctl : 'Ctl'; +Distribute : 'distribute'; +Double : 'Double'; +Elif : 'elif'; +Else : 'else'; +Fail : 'fail'; +False : 'false'; +Fixup : 'fixup'; +For : 'for'; +Function : 'function'; +If : 'if'; +In : 'in'; +Int : 'Int'; +Internal : 'internal'; +Intrinsic : 'intrinsic'; +Invert : 'invert'; +Is : 'is'; +Let : 'let'; +Mutable : 'mutable'; +Namespace : 'namespace'; +New : 'new'; +Newtype : 'newtype'; +Not : 'not'; +One : 'One'; +Open : 'open'; +Operation : 'operation'; +Or : 'or'; +Pauli : 'Pauli'; +PauliI : 'PauliI'; +PauliX : 'PauliX'; +PauliY : 'PauliY'; +PauliZ : 'PauliZ'; +Qubit : 'Qubit'; +Range : 'Range'; +Repeat : 'repeat'; +Result : 'Result'; +Return : 'return'; +Self : 'self'; +Set : 'set'; +String : 'String'; +True : 'true'; +Unit : 'Unit'; +Until : 'until'; +Using : 'using'; +While : 'while'; +Within : 'within'; +Zero : 'Zero'; + +// Operators + +AndEqual : 'and='; +ArrowLeft : '<-'; +ArrowRight : '->'; +Asterisk : '*'; +AsteriskEqual : '*='; +At : '@'; +Bang : '!'; +BraceLeft : '{' -> pushMode(DEFAULT_MODE); +BraceRight : '}' { if (!_modeStack.isEmpty()) popMode(); }; +BracketLeft : '['; +BracketRight : ']'; +Caret : '^'; +CaretEqual : '^='; +Colon : ':'; +Comma : ','; +DollarQuote : '$"' -> pushMode(INTERPOLATED); +Dot : '.'; +DoubleColon : '::'; +DoubleDot : '..'; +DoubleEqual : '=='; +DoubleQuote : '"' -> pushMode(STRING); +Ellipsis : '...'; +Equal : '='; +FatArrowRight : '=>'; +Greater : '>'; +GreaterEqual : '>='; +Less : '<'; +LessEqual : '<='; +Minus : '-'; +MinusEqual : '-='; +NotEqual : '!='; +OrEqual : 'or='; +ParenLeft : '('; +ParenRight : ')'; +Percent : '%'; +PercentEqual : '%='; +Pipe : '|'; +Plus : '+'; +PlusEqual : '+='; +Question : '?'; +Semicolon : ';'; +Slash : '/'; +SlashEqual : '/='; +TripleAmpersand : '&&&'; +TripleAmpersandEqual : '&&&='; +TripleCaret : '^^^'; +TripleCaretEqual : '^^^='; +TripleGreater : '>>>'; +TripleGreaterEqual : '>>>='; +TripleLess : '<<<'; +TripleLessEqual : '<<<='; +TriplePipe : '|||'; +TriplePipeEqual : '|||='; +TripleTilde : '~~~'; +Underscore : '_'; +With : 'w/'; +WithEqual : 'w/='; + +// Literals + +fragment Digit : [0-9]; + +IntegerLiteral + : Digit+ + | ('0x' | '0X') [0-9a-fA-F]+ + | ('0o' | '0O') [0-7]+ + | ('0b' | '0B') [0-1]+ + ; + +BigIntegerLiteral : IntegerLiteral ('L' | 'l'); + +DoubleLiteral + : Digit+ '.' Digit+ + | '.' Digit+ + | Digit+ '.' { _input.LA(1) != '.' }? + | Digit+ ('e' | 'E') Digit+ + ; + +Identifier : IdentifierStart IdentifierContinuation*; + +IdentifierStart + : Underscore + | [\p{Letter}] + | [\p{Letter_Number}] + ; + +IdentifierContinuation + : [\p{Connector_Punctuation}] + | [\p{Decimal_Number}] + | [\p{Format}] + | [\p{Letter}] + | [\p{Letter_Number}] + | [\p{Nonspacing_Mark}] + | [\p{Spacing_Mark}] + ; + +TypeParameter : '\'' Identifier; + +Whitespace : (' ' | '\n' | '\r' | '\t')+ -> channel(HIDDEN); + +Comment : '//' ~('\n' | '\r')* -> channel(HIDDEN); + +Invalid : . -> channel(HIDDEN); + +// Strings + +mode STRING; + +StringEscape : '\\' .; + +StringText : ~('"' | '\\')+; + +StringDoubleQuote : '"' -> popMode; + +mode INTERPOLATED; + +InterpStringEscape : '\\' .; + +InterpBraceLeft : '{' -> pushMode(DEFAULT_MODE); + +InterpStringText : ~('\\' | '"' | '{')+; + +InterpDoubleQuote : '"' -> popMode; diff --git a/Specifications/Language/5_Grammar/QSharpParser.g4 b/Specifications/Language/5_Grammar/QSharpParser.g4 new file mode 100644 index 0000000..c093025 --- /dev/null +++ b/Specifications/Language/5_Grammar/QSharpParser.g4 @@ -0,0 +1,261 @@ +parser grammar QSharpParser; + +options { + tokenVocab = QSharpLexer; +} + +program : namespace* EOF; + +// Namespace + +namespace : 'namespace' qualifiedName BraceLeft namespaceElement* BraceRight; + +qualifiedName : Identifier ('.' Identifier)*; + +namespaceElement + : openDirective + | typeDeclaration + | callableDeclaration + ; + +// Open Directive + +openDirective : 'open' qualifiedName ('as' qualifiedName)? ';'; + +// Declaration + +attribute : '@' expression; + +access : 'internal'; + +declarationPrefix : attribute* access?; + +// Type Declaration + +typeDeclaration : declarationPrefix 'newtype' Identifier '=' underlyingType ';'; + +underlyingType + : typeDeclarationTuple + | type + ; + +typeDeclarationTuple : '(' (typeTupleItem (',' typeTupleItem)*)? ')'; + +typeTupleItem + : namedItem + | underlyingType + ; + +namedItem : Identifier ':' type; + +// Callable Declaration + +callableDeclaration : + declarationPrefix + ('function' | 'operation') + Identifier + typeParameterBinding? + parameterTuple + ':' + type + characteristics? + callableBody; + +typeParameterBinding : '<' (TypeParameter (',' TypeParameter)*)? '>'; + +parameterTuple : '(' (parameter (',' parameter)*)? ')'; + +parameter + : namedItem + | parameterTuple + ; + +characteristics : 'is' characteristicsExpression; + +characteristicsExpression + : 'Adj' # AdjointCharacteristic + | 'Ctl' # ControlledCharacteristic + | '(' characteristicsExpression ')' # CharacteristicsGroup + | characteristicsExpression '*' characteristicsExpression # IntersectCharacteristics + | characteristicsExpression '+' characteristicsExpression # UnionCharacteristics + ; + +callableBody + : BraceLeft specialization* BraceRight # CallableSpecialization + | scope # CallableScope + ; + +specialization : specializationName+ specializationGenerator; + +specializationName + : 'body' + | 'adjoint' + | 'controlled' + ; + +specializationGenerator + : 'auto' ';' # AutoGenerator + | 'self' ';' # SelfGenerator + | 'invert' ';' # InvertGenerator + | 'distribute' ';' # DistributeGenerator + | 'intrinsic' ';' # IntrinsicGenerator + | providedSpecialization # ProvidedGenerator + ; + +providedSpecialization : specializationParameterTuple? scope; + +specializationParameterTuple : '(' (specializationParameter (',' specializationParameter)*)? ')'; + +specializationParameter + : Identifier # SpecializationNamedParameter + | '...' # SpecializationImplicitParameter + ; + +// Type + +type + : '_' # MissingType + | TypeParameter # TypeParameter + | 'BigInt' # BigIntType + | 'Bool' # BoolType + | 'Double' # DoubleType + | 'Int' # IntType + | 'Pauli' # PauliType + | 'Qubit' # QubitType + | 'Range' # RangeType + | 'Result' # ResultType + | 'String' # StringType + | 'Unit' # UnitType + | qualifiedName # UserDefinedType + | '(' (type (',' type)* ','?)? ')' # TupleType + | '(' arrowType characteristics? ')' # CallableType + | type '[' ']' # ArrayType + ; + +arrowType + : '(' type ('->' | '=>') type ')' + | type ('->' | '=>') type + ; + +// Statement + +statement + : expression ';' # ExpressionStatement + | 'return' expression ';' # Return + | 'fail' expression ';' # Fail + | 'let' symbolBinding '=' expression ';' # Let + | 'mutable' symbolBinding '=' expression ';' # Mutable + | 'set' symbolBinding '=' expression ';' # Set + | 'set' Identifier updateOperator expression ';' # SetUpdate + | 'set' Identifier 'w/=' expression '<-' expression ';' # SetWith + | 'if' '(' expression ')' scope # If + | 'elif' '(' expression ')' scope # Elif + | 'else' scope # Else + | 'for' '(' symbolBinding 'in' expression ')' scope # For + | 'while' '(' expression ')' scope # While + | 'repeat' scope # Repeat + | 'until' '(' expression ')' (';' | 'fixup' scope) # UntilFixup + | 'within' scope # Within + | 'apply' scope # Apply + | 'using' '(' symbolBinding '=' qubitInitializer ')' scope # Using + | 'borrowing' '(' symbolBinding '=' qubitInitializer ')' scope # Borrowing + ; + +scope : BraceLeft statement* BraceRight; + +symbolBinding + : '_' # Discard + | Identifier # Symbol + | '(' (symbolBinding (',' symbolBinding)* ','?)? ')' # SymbolTuple + ; + +updateOperator + : '^=' + | '*=' + | '/=' + | '%=' + | '+=' + | '-=' + | '>>>=' + | '<<<=' + | '&&&=' + | '^^^=' + | '|||=' + | 'and=' + | 'or=' + ; + +qubitInitializer + : 'Qubit' '(' ')' # Qubit + | 'Qubit' '[' expression ']' # QubitArray + | '(' (qubitInitializer (',' qubitInitializer)* ','?)? ')' # QubitTuple + ; + +// Expression + +expression + : '_' # MissingExpression + | qualifiedName ('<' (type (',' type)* ','?)? '>')? # Identifier + | IntegerLiteral # Integer + | BigIntegerLiteral # BigInteger + | DoubleLiteral # Double + | DoubleQuote stringContent* StringDoubleQuote # String + | DollarQuote interpStringContent* InterpDoubleQuote # InterpolatedString + | boolLiteral # Bool + | resultLiteral # Result + | pauliLiteral # Pauli + | '(' (expression (',' expression)* ','?)? ')' # Tuple + | '[' (expression (',' expression)* ','?)? ']' # Array + | 'new' type '[' expression ']' # NewArray + | expression ('::' Identifier | '[' expression ']') # ItemAccess + | expression '!' # Unwrap + | 'Controlled' expression # ControlledFunctor + | 'Adjoint' expression # AdjointFunctor + | expression '(' (expression (',' expression)* ','?)? ')' # Call + | ('-' | 'not' | '~~~') expression # Negate + | expression '^' expression # Power + | expression ('*' | '/' | '%') expression # MultiplyDivideModulo + | expression ('+' | '-') expression # AddSubtract + | expression ('>>>' | '<<<') expression # Shift + | expression ('>' | '<' | '>=' | '<=') expression # GreaterLess + | expression ('==' | '!=') expression # Equal + | expression '&&&' expression # BitwiseAnd + | expression '^^^' expression # BitwiseXor + | expression '|||' expression # BitwiseOr + | expression 'and' expression # And + | expression 'or' expression # Or + | expression '?' expression '|' expression # Conditional + | expression '..' expression # Range + | expression '...' # RightOpenRange + | '...' expression # LeftOpenRange + | '...' # OpenRange + | expression 'w/' expression '<-' expression # With + ; + +boolLiteral + : 'false' + | 'true' + ; + +resultLiteral + : 'Zero' + | 'One' + ; + +pauliLiteral + : 'PauliI' + | 'PauliX' + | 'PauliY' + | 'PauliZ' + ; + +stringContent + : StringEscape # StringEscape + | StringText # StringText + ; + +interpStringContent + : InterpStringEscape # InterpStringEscape + | InterpBraceLeft expression BraceRight # InterpStringExpression + | InterpStringText # InterpStringText + ; diff --git a/Specifications/Language/5_Grammar/README.md b/Specifications/Language/5_Grammar/README.md new file mode 100644 index 0000000..a1265e0 --- /dev/null +++ b/Specifications/Language/5_Grammar/README.md @@ -0,0 +1,7 @@ +# Grammar + +A reference implementation of the Q# grammar is available in the [ANTLR4](https://www.antlr.org/) format. +The grammar source files are listed below: + +* [**QSharpLexer.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpLexer.g4) describes the lexical structure of Q#. +* [**QSharpParser.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpParser.g4) describes the syntax of Q#. diff --git a/Specifications/Language/README.md b/Specifications/Language/README.md index e27d4eb..9b031a0 100644 --- a/Specifications/Language/README.md +++ b/Specifications/Language/README.md @@ -62,3 +62,4 @@ programs are implemented in terms of statements and expressions, much like in cl 1. [Type Parameterizations](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeParameterizations.md#type-parameterizations) 1. [Type Inference](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/4_TypeSystem/TypeInference.md#type-inference) +1. [Grammar](https://github.com/microsoft/qsharp-language/tree/main/Specifications/Language/5_Grammar#grammar) From 7493d3e4230315bf736be3f1d49d59cb3011abb2 Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Mon, 26 Oct 2020 09:18:05 -0700 Subject: [PATCH 2/6] Add note about actions/semantic predicates --- Specifications/Language/5_Grammar/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Specifications/Language/5_Grammar/README.md b/Specifications/Language/5_Grammar/README.md index a1265e0..54dcc0f 100644 --- a/Specifications/Language/5_Grammar/README.md +++ b/Specifications/Language/5_Grammar/README.md @@ -5,3 +5,7 @@ The grammar source files are listed below: * [**QSharpLexer.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpLexer.g4) describes the lexical structure of Q#. * [**QSharpParser.g4**](https://github.com/microsoft/qsharp-language/blob/main/Specifications/Language/5_Grammar/QSharpParser.g4) describes the syntax of Q#. + +The Q# grammar uses [*actions*](https://github.com/antlr/antlr4/blob/master/doc/actions.md) and [*semantic predicates*](https://github.com/antlr/antlr4/blob/master/doc/predicates.md). +These features allow grammars to include custom source code in the ANTLR-generated parser, which means that the code needs to be written in the same language as the ANTLR target language. +If you are using the Q# grammar to generate parsers in a language other than Java, you may need to update the code used by the actions and semantic predicates to match the target language. From 1118ce6359d4509e9c3f6c766453bd019162354b Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Mon, 26 Oct 2020 09:20:18 -0700 Subject: [PATCH 3/6] Update formatting of callableDeclaration --- .../Language/5_Grammar/QSharpParser.g4 | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Specifications/Language/5_Grammar/QSharpParser.g4 b/Specifications/Language/5_Grammar/QSharpParser.g4 index c093025..50a423a 100644 --- a/Specifications/Language/5_Grammar/QSharpParser.g4 +++ b/Specifications/Language/5_Grammar/QSharpParser.g4 @@ -50,16 +50,12 @@ namedItem : Identifier ':' type; // Callable Declaration -callableDeclaration : - declarationPrefix - ('function' | 'operation') - Identifier - typeParameterBinding? - parameterTuple - ':' - type - characteristics? - callableBody; +callableDeclaration + : declarationPrefix ('function' | 'operation') + Identifier typeParameterBinding? parameterTuple + ':' type characteristics? + callableBody + ; typeParameterBinding : '<' (TypeParameter (',' TypeParameter)*)? '>'; From 9c2bb8f4a78dda83fa5575ba5ba5fdc1ecb6dc14 Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Tue, 27 Oct 2020 13:21:16 -0700 Subject: [PATCH 4/6] Remove labels --- .../Language/5_Grammar/QSharpParser.g4 | 194 +++++++++--------- 1 file changed, 97 insertions(+), 97 deletions(-) diff --git a/Specifications/Language/5_Grammar/QSharpParser.g4 b/Specifications/Language/5_Grammar/QSharpParser.g4 index 50a423a..ca91aa7 100644 --- a/Specifications/Language/5_Grammar/QSharpParser.g4 +++ b/Specifications/Language/5_Grammar/QSharpParser.g4 @@ -69,16 +69,16 @@ parameter characteristics : 'is' characteristicsExpression; characteristicsExpression - : 'Adj' # AdjointCharacteristic - | 'Ctl' # ControlledCharacteristic - | '(' characteristicsExpression ')' # CharacteristicsGroup - | characteristicsExpression '*' characteristicsExpression # IntersectCharacteristics - | characteristicsExpression '+' characteristicsExpression # UnionCharacteristics + : 'Adj' + | 'Ctl' + | '(' characteristicsExpression ')' + | characteristicsExpression '*' characteristicsExpression + | characteristicsExpression '+' characteristicsExpression ; callableBody - : BraceLeft specialization* BraceRight # CallableSpecialization - | scope # CallableScope + : BraceLeft specialization* BraceRight + | scope ; specialization : specializationName+ specializationGenerator; @@ -90,12 +90,12 @@ specializationName ; specializationGenerator - : 'auto' ';' # AutoGenerator - | 'self' ';' # SelfGenerator - | 'invert' ';' # InvertGenerator - | 'distribute' ';' # DistributeGenerator - | 'intrinsic' ';' # IntrinsicGenerator - | providedSpecialization # ProvidedGenerator + : 'auto' ';' + | 'self' ';' + | 'invert' ';' + | 'distribute' ';' + | 'intrinsic' ';' + | providedSpecialization ; providedSpecialization : specializationParameterTuple? scope; @@ -103,29 +103,29 @@ providedSpecialization : specializationParameterTuple? scope; specializationParameterTuple : '(' (specializationParameter (',' specializationParameter)*)? ')'; specializationParameter - : Identifier # SpecializationNamedParameter - | '...' # SpecializationImplicitParameter + : Identifier + | '...' ; // Type type - : '_' # MissingType - | TypeParameter # TypeParameter - | 'BigInt' # BigIntType - | 'Bool' # BoolType - | 'Double' # DoubleType - | 'Int' # IntType - | 'Pauli' # PauliType - | 'Qubit' # QubitType - | 'Range' # RangeType - | 'Result' # ResultType - | 'String' # StringType - | 'Unit' # UnitType - | qualifiedName # UserDefinedType - | '(' (type (',' type)* ','?)? ')' # TupleType - | '(' arrowType characteristics? ')' # CallableType - | type '[' ']' # ArrayType + : '_' + | TypeParameter + | 'BigInt' + | 'Bool' + | 'Double' + | 'Int' + | 'Pauli' + | 'Qubit' + | 'Range' + | 'Result' + | 'String' + | 'Unit' + | qualifiedName + | '(' (type (',' type)* ','?)? ')' + | '(' arrowType characteristics? ')' + | type '[' ']' ; arrowType @@ -136,33 +136,33 @@ arrowType // Statement statement - : expression ';' # ExpressionStatement - | 'return' expression ';' # Return - | 'fail' expression ';' # Fail - | 'let' symbolBinding '=' expression ';' # Let - | 'mutable' symbolBinding '=' expression ';' # Mutable - | 'set' symbolBinding '=' expression ';' # Set - | 'set' Identifier updateOperator expression ';' # SetUpdate - | 'set' Identifier 'w/=' expression '<-' expression ';' # SetWith - | 'if' '(' expression ')' scope # If - | 'elif' '(' expression ')' scope # Elif - | 'else' scope # Else - | 'for' '(' symbolBinding 'in' expression ')' scope # For - | 'while' '(' expression ')' scope # While - | 'repeat' scope # Repeat - | 'until' '(' expression ')' (';' | 'fixup' scope) # UntilFixup - | 'within' scope # Within - | 'apply' scope # Apply - | 'using' '(' symbolBinding '=' qubitInitializer ')' scope # Using - | 'borrowing' '(' symbolBinding '=' qubitInitializer ')' scope # Borrowing + : expression ';' + | 'return' expression ';' + | 'fail' expression ';' + | 'let' symbolBinding '=' expression ';' + | 'mutable' symbolBinding '=' expression ';' + | 'set' symbolBinding '=' expression ';' + | 'set' Identifier updateOperator expression ';' + | 'set' Identifier 'w/=' expression '<-' expression ';' + | 'if' '(' expression ')' scope + | 'elif' '(' expression ')' scope + | 'else' scope + | 'for' '(' symbolBinding 'in' expression ')' scope + | 'while' '(' expression ')' scope + | 'repeat' scope + | 'until' '(' expression ')' (';' | 'fixup' scope) + | 'within' scope + | 'apply' scope + | 'using' '(' symbolBinding '=' qubitInitializer ')' scope + | 'borrowing' '(' symbolBinding '=' qubitInitializer ')' scope ; scope : BraceLeft statement* BraceRight; symbolBinding - : '_' # Discard - | Identifier # Symbol - | '(' (symbolBinding (',' symbolBinding)* ','?)? ')' # SymbolTuple + : '_' + | Identifier + | '(' (symbolBinding (',' symbolBinding)* ','?)? ')' ; updateOperator @@ -182,50 +182,50 @@ updateOperator ; qubitInitializer - : 'Qubit' '(' ')' # Qubit - | 'Qubit' '[' expression ']' # QubitArray - | '(' (qubitInitializer (',' qubitInitializer)* ','?)? ')' # QubitTuple + : 'Qubit' '(' ')' + | 'Qubit' '[' expression ']' + | '(' (qubitInitializer (',' qubitInitializer)* ','?)? ')' ; // Expression expression - : '_' # MissingExpression - | qualifiedName ('<' (type (',' type)* ','?)? '>')? # Identifier - | IntegerLiteral # Integer - | BigIntegerLiteral # BigInteger - | DoubleLiteral # Double - | DoubleQuote stringContent* StringDoubleQuote # String - | DollarQuote interpStringContent* InterpDoubleQuote # InterpolatedString - | boolLiteral # Bool - | resultLiteral # Result - | pauliLiteral # Pauli - | '(' (expression (',' expression)* ','?)? ')' # Tuple - | '[' (expression (',' expression)* ','?)? ']' # Array - | 'new' type '[' expression ']' # NewArray - | expression ('::' Identifier | '[' expression ']') # ItemAccess - | expression '!' # Unwrap - | 'Controlled' expression # ControlledFunctor - | 'Adjoint' expression # AdjointFunctor - | expression '(' (expression (',' expression)* ','?)? ')' # Call - | ('-' | 'not' | '~~~') expression # Negate - | expression '^' expression # Power - | expression ('*' | '/' | '%') expression # MultiplyDivideModulo - | expression ('+' | '-') expression # AddSubtract - | expression ('>>>' | '<<<') expression # Shift - | expression ('>' | '<' | '>=' | '<=') expression # GreaterLess - | expression ('==' | '!=') expression # Equal - | expression '&&&' expression # BitwiseAnd - | expression '^^^' expression # BitwiseXor - | expression '|||' expression # BitwiseOr - | expression 'and' expression # And - | expression 'or' expression # Or - | expression '?' expression '|' expression # Conditional - | expression '..' expression # Range - | expression '...' # RightOpenRange - | '...' expression # LeftOpenRange - | '...' # OpenRange - | expression 'w/' expression '<-' expression # With + : '_' + | qualifiedName ('<' (type (',' type)* ','?)? '>')? + | IntegerLiteral + | BigIntegerLiteral + | DoubleLiteral + | DoubleQuote stringContent* StringDoubleQuote + | DollarQuote interpStringContent* InterpDoubleQuote + | boolLiteral + | resultLiteral + | pauliLiteral + | '(' (expression (',' expression)* ','?)? ')' + | '[' (expression (',' expression)* ','?)? ']' + | 'new' type '[' expression ']' + | expression ('::' Identifier | '[' expression ']') + | expression '!' + | 'Controlled' expression + | 'Adjoint' expression + | expression '(' (expression (',' expression)* ','?)? ')' + | ('-' | 'not' | '~~~') expression + | expression '^' expression + | expression ('*' | '/' | '%') expression + | expression ('+' | '-') expression + | expression ('>>>' | '<<<') expression + | expression ('>' | '<' | '>=' | '<=') expression + | expression ('==' | '!=') expression + | expression '&&&' expression + | expression '^^^' expression + | expression '|||' expression + | expression 'and' expression + | expression 'or' expression + | expression '?' expression '|' expression + | expression '..' expression + | expression '...' + | '...' expression + | '...' + | expression 'w/' expression '<-' expression ; boolLiteral @@ -246,12 +246,12 @@ pauliLiteral ; stringContent - : StringEscape # StringEscape - | StringText # StringText + : StringEscape + | StringText ; interpStringContent - : InterpStringEscape # InterpStringEscape - | InterpBraceLeft expression BraceRight # InterpStringExpression - | InterpStringText # InterpStringText + : InterpStringEscape + | InterpBraceLeft expression BraceRight + | InterpStringText ; From 62a7c78857fb92fe71c7942c3dc46468669b2dc9 Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Tue, 27 Oct 2020 13:35:24 -0700 Subject: [PATCH 5/6] Add comment about lookahead in DoubleLiteral --- Specifications/Language/5_Grammar/QSharpLexer.g4 | 1 + 1 file changed, 1 insertion(+) diff --git a/Specifications/Language/5_Grammar/QSharpLexer.g4 b/Specifications/Language/5_Grammar/QSharpLexer.g4 index 0abc948..3f54bc9 100644 --- a/Specifications/Language/5_Grammar/QSharpLexer.g4 +++ b/Specifications/Language/5_Grammar/QSharpLexer.g4 @@ -139,6 +139,7 @@ BigIntegerLiteral : IntegerLiteral ('L' | 'l'); DoubleLiteral : Digit+ '.' Digit+ | '.' Digit+ + // "n.." should be interpreted as an integer range, not the double "n." followed by a dot. | Digit+ '.' { _input.LA(1) != '.' }? | Digit+ ('e' | 'E') Digit+ ; From 7535a77b5a98ff2b38f221b1367f5f8e60ee7791 Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Tue, 27 Oct 2020 17:28:14 -0700 Subject: [PATCH 6/6] Target-specific is contained in { } --- Specifications/Language/5_Grammar/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Specifications/Language/5_Grammar/README.md b/Specifications/Language/5_Grammar/README.md index 54dcc0f..5ae103f 100644 --- a/Specifications/Language/5_Grammar/README.md +++ b/Specifications/Language/5_Grammar/README.md @@ -9,3 +9,4 @@ The grammar source files are listed below: The Q# grammar uses [*actions*](https://github.com/antlr/antlr4/blob/master/doc/actions.md) and [*semantic predicates*](https://github.com/antlr/antlr4/blob/master/doc/predicates.md). These features allow grammars to include custom source code in the ANTLR-generated parser, which means that the code needs to be written in the same language as the ANTLR target language. If you are using the Q# grammar to generate parsers in a language other than Java, you may need to update the code used by the actions and semantic predicates to match the target language. +Target-specific code is marked by curly braces `{` `}` in the grammar.