Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursively expand defcals #1270

Merged
merged 15 commits into from
Nov 19, 2020
2 changes: 1 addition & 1 deletion pyquil/_parser/PyQuilListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def exitGate(self, ctx: QuilParser.GateContext):
gate_name = ctx.name().getText()
modifiers = [mod.getText() for mod in ctx.modifier()]
params = list(map(_param, ctx.param()))
qubits = list(map(_qubit, ctx.qubit()))
qubits = list(map(_qubitOrFormal, ctx.qubitOrFormal()))

# The parsed string 'DAGGER CONTROLLED X 0 1' gives
# modifiers ['DAGGER', 'CONTROLLED']
Expand Down
1 change: 0 additions & 1 deletion pyquil/_parser/Quil.g4

This file was deleted.

354 changes: 354 additions & 0 deletions pyquil/_parser/Quil.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,354 @@
grammar Quil;

////////////////////
// PARSER
////////////////////

quil : allInstr? ( NEWLINE+ allInstr )* NEWLINE* EOF ;

allInstr : defGate
| defGateAsPauli
| defCircuit
| defFrame
| defWaveform
| defCalibration
| defMeasCalibration
| instr
;

instr : fence
| fenceAll
| delay
| gate
| measure
| defLabel
| halt
| jump
| jumpWhen
| jumpUnless
| resetState
| wait
| classicalUnary
| classicalBinary
| classicalComparison
| load
| store
| nop
| include
| pragma
| pulse
| setFrequency
| shiftFrequency
| setPhase
| shiftPhase
| swapPhase
| setScale
| capture
| rawCapture
| memoryDescriptor // this is a little unusual, but it's in steven's example
;

// C. Static and Parametric Gates

gate : modifier* name ( LPAREN param ( COMMA param )* RPAREN )? qubitOrFormal+ ;

name : IDENTIFIER ;
qubit : INT ;

param : expression ;

modifier : CONTROLLED
| DAGGER
| FORKED ;

// D. Gate Definitions

defGate : DEFGATE name (( LPAREN variable ( COMMA variable )* RPAREN ) | ( AS gatetype ))? COLON NEWLINE matrix ;
defGateAsPauli : DEFGATE name ( LPAREN variable ( COMMA variable )* RPAREN )? qubitVariable+ AS PAULISUM COLON NEWLINE pauliTerms ;

variable : PERCENTAGE IDENTIFIER ;
gatetype : MATRIX
| PERMUTATION ;

matrix : ( matrixRow NEWLINE )* matrixRow ;
matrixRow : TAB expression ( COMMA expression )* ;

pauliTerms : ( pauliTerm NEWLINE )* pauliTerm;
pauliTerm : TAB IDENTIFIER LPAREN expression RPAREN qubitVariable+ ;

// E. Circuits

defCircuit : DEFCIRCUIT name ( LPAREN variable ( COMMA variable )* RPAREN )? qubitVariable* COLON NEWLINE circuit ;

qubitVariable : IDENTIFIER ;

circuitQubit : qubit | qubitVariable ;
circuitGate : name ( LPAREN param ( COMMA param )* RPAREN )? circuitQubit+ ;
circuitMeasure : MEASURE circuitQubit addr? ;
circuitResetState : RESET circuitQubit? ;
circuitInstr : circuitGate | circuitMeasure | circuitResetState | instr ;
circuit : ( TAB circuitInstr NEWLINE )* TAB circuitInstr ;

// F. Measurement

measure : MEASURE qubit addr? ;
addr : IDENTIFIER | ( IDENTIFIER? LBRACKET INT RBRACKET );

// G. Program control

defLabel : LABEL label ;
label : AT IDENTIFIER ;
halt : HALT ;
jump : JUMP label ;
jumpWhen : JUMPWHEN label addr ;
jumpUnless : JUMPUNLESS label addr ;

// H. Zeroing the Quantum State

resetState : RESET qubit? ; // NB: cannot be named "reset" due to conflict with Antlr implementation

// I. Classical/Quantum Synchronization

wait : WAIT ;

// J. Classical Instructions

memoryDescriptor : DECLARE IDENTIFIER IDENTIFIER ( LBRACKET INT RBRACKET )? ( SHARING IDENTIFIER ( offsetDescriptor )* )? ;
offsetDescriptor : OFFSET INT IDENTIFIER ;

classicalUnary : ( NEG | NOT | TRUE | FALSE ) addr ;
classicalBinary : logicalBinaryOp | arithmeticBinaryOp | move | exchange | convert ;
logicalBinaryOp : ( AND | OR | IOR | XOR ) addr ( addr | INT ) ;
arithmeticBinaryOp : ( ADD | SUB | MUL | DIV ) addr ( addr | number ) ;
move : MOVE addr ( addr | number );
exchange : EXCHANGE addr addr ;
convert : CONVERT addr addr ;
load : LOAD addr IDENTIFIER addr ;
store : STORE IDENTIFIER addr ( addr | number );
classicalComparison : ( EQ | GT | GE | LT | LE ) addr addr ( addr | number );

// K. The No-Operation Instruction

nop : NOP ;

// L. File Inclusion

include : INCLUDE STRING ;

// M. Pragma Support

pragma : PRAGMA ( IDENTIFIER | keyword ) pragma_name* STRING? ;
pragma_name : IDENTIFIER | keyword | INT ;

// Expressions (in order of precedence)

expression : LPAREN expression RPAREN #parenthesisExp
| sign expression #signedExp
| <assoc=right> expression POWER expression #powerExp
| expression ( TIMES | DIVIDE ) expression #mulDivExp
| expression ( PLUS | MINUS ) expression #addSubExp
| function LPAREN expression RPAREN #functionExp
| number #numberExp
| variable #variableExp
| addr #addrExp
;

function : SIN | COS | SQRT | EXP | CIS ;
sign : PLUS | MINUS ;

// Numbers
// We suffix -N onto these names so they don't conflict with already defined Python types

number : MINUS? ( realN | imaginaryN | I | PI ) ;
imaginaryN : realN I ;
realN : FLOAT | INT ;

// Analog control

waveformName : name (DIVIDE name)? ;

defFrame : DEFFRAME frame ( COLON frameSpec+ )? ;
frameSpec : NEWLINE TAB frameAttr COLON ( expression | STRING ) ;
frameAttr : SAMPLERATE | INITIALFREQUENCY | DIRECTION | HARDWAREOBJECT | CENTERFREQUENCY;

defWaveform : DEFWAVEFORM waveformName ( LPAREN param (COMMA param)* RPAREN )? COLON NEWLINE matrix ;
defCalibration : DEFCAL name (LPAREN param ( COMMA param )* RPAREN)? qubitOrFormal+ COLON ( NEWLINE TAB instr)* ;
defMeasCalibration : DEFCAL MEASURE qubitOrFormal ( name )? COLON ( NEWLINE TAB instr )* ;

pulse : NONBLOCKING? PULSE frame waveform ;
capture : NONBLOCKING? CAPTURE frame waveform addr ;
rawCapture : NONBLOCKING? RAWCAPTURE frame expression addr ;

setFrequency : SETFREQUENCY frame expression ;
shiftFrequency : SHIFTFREQUENCY frame expression ;
setPhase : SETPHASE frame expression ;
shiftPhase : SHIFTPHASE frame expression ;
swapPhase : SWAPPHASE frame frame ;
setScale : SETSCALE frame expression ;

delay : DELAY qubitOrFormal+ STRING* expression ;
fenceAll : FENCE ;
fence : FENCE qubitOrFormal+ ;

qubitOrFormal : qubit | qubitVariable ;
namedParam : IDENTIFIER COLON expression ;
waveform : waveformName (LPAREN namedParam ( COMMA namedParam )* RPAREN)? ;
frame : qubitOrFormal+ STRING ;

// built-in waveform types include: "flat", "gaussian", "draggaussian", "erfsquare"


////////////////////
// LEXER
////////////////////

keyword : DEFGATE | DEFCIRCUIT | MEASURE | LABEL | HALT | JUMP | JUMPWHEN | JUMPUNLESS
| RESET | WAIT | NOP | INCLUDE | PRAGMA | DECLARE | SHARING | OFFSET | AS | MATRIX
| PERMUTATION | NEG | NOT | TRUE | FALSE | AND | IOR | XOR | OR | ADD | SUB | MUL
| DIV | MOVE | EXCHANGE | CONVERT | EQ | GT | GE | LT | LE | LOAD | STORE | PI | I
| SIN | COS | SQRT | EXP | CIS | CAPTURE | DEFCAL | DEFFRAME | DEFWAVEFORM
| DELAY | DIRECTION | FENCE | INITIALFREQUENCY | CENTERFREQUENCY | NONBLOCKING | PULSE | SAMPLERATE
| SETFREQUENCY | SETPHASE | SETSCALE | SHIFTPHASE | SWAPPHASE | RAWCAPTURE
| CONTROLLED | DAGGER | FORKED ;

// Keywords

DEFGATE : 'DEFGATE' ;
DEFCIRCUIT : 'DEFCIRCUIT' ;
MEASURE : 'MEASURE' ;

LABEL : 'LABEL' ;
HALT : 'HALT' ;
JUMP : 'JUMP' ;
JUMPWHEN : 'JUMP-WHEN' ;
JUMPUNLESS : 'JUMP-UNLESS' ;

RESET : 'RESET' ;
WAIT : 'WAIT' ;
NOP : 'NOP' ;
INCLUDE : 'INCLUDE' ;
PRAGMA : 'PRAGMA' ;

DECLARE : 'DECLARE' ;
SHARING : 'SHARING' ;
OFFSET : 'OFFSET' ;

AS : 'AS' ;
MATRIX : 'MATRIX' ;
PERMUTATION : 'PERMUTATION' ;
PAULISUM : 'PAULI-SUM';

NEG : 'NEG' ;
NOT : 'NOT' ;
TRUE : 'TRUE' ; // Deprecated
FALSE : 'FALSE' ; // Deprecated

AND : 'AND' ;
IOR : 'IOR' ;
XOR : 'XOR' ;
OR : 'OR' ; // Deprecated

ADD : 'ADD' ;
SUB : 'SUB' ;
MUL : 'MUL' ;
DIV : 'DIV' ;

MOVE : 'MOVE' ;
EXCHANGE : 'EXCHANGE' ;
CONVERT : 'CONVERT' ;

EQ : 'EQ';
GT : 'GT';
GE : 'GE';
LT : 'LT';
LE : 'LE';

LOAD : 'LOAD' ;
STORE : 'STORE' ;

PI : 'pi' ;
I : 'i' ;

SIN : 'SIN' ;
COS : 'COS' ;
SQRT : 'SQRT' ;
EXP : 'EXP' ;
CIS : 'CIS' ;

// Operators

PLUS : '+' ;
MINUS : '-' ;
TIMES : '*' ;
DIVIDE : '/' ;
POWER : '^' ;

// analog keywords

CAPTURE : 'CAPTURE' ;
DEFCAL : 'DEFCAL' ;
DEFFRAME : 'DEFFRAME' ;
DEFWAVEFORM : 'DEFWAVEFORM' ;
DELAY : 'DELAY' ;
DIRECTION : 'DIRECTION' ;
FENCE : 'FENCE' ;
HARDWAREOBJECT : 'HARDWARE-OBJECT' ;
INITIALFREQUENCY : 'INITIAL-FREQUENCY' ;
CENTERFREQUENCY : 'CENTER-FREQUENCY' ;
NONBLOCKING : 'NONBLOCKING' ;
PULSE : 'PULSE' ;
SAMPLERATE : 'SAMPLE-RATE' ;
SETFREQUENCY : 'SET-FREQUENCY' ;
SHIFTFREQUENCY : 'SHIFT-FREQUENCY' ;
SETPHASE : 'SET-PHASE' ;
SETSCALE : 'SET-SCALE' ;
SHIFTPHASE : 'SHIFT-PHASE' ;
SWAPPHASE : 'SWAP-PHASE' ;
RAWCAPTURE : 'RAW-CAPTURE' ;

// Modifiers

CONTROLLED : 'CONTROLLED' ;
DAGGER : 'DAGGER' ;
FORKED : 'FORKED' ;

// Identifiers

IDENTIFIER : ( ( [A-Za-z_] ) | ( [A-Za-z_] [A-Za-z0-9\-_]* [A-Za-z0-9_] ) ) ;

// Numbers

INT : [0-9]+ ;
FLOAT : [0-9]+ ( '.' [0-9]+ )? ( ( 'e'|'E' ) ( '+' | '-' )? [0-9]+ )? ;

// String

STRING : '"' ~( '\n' | '\r' | '"' )* '"';

// Punctuation

PERIOD : '.' ;
COMMA : ',' ;
LPAREN : '(' ;
RPAREN : ')' ;
LBRACKET : '[' ;
RBRACKET : ']' ;
COLON : ':' ;
PERCENTAGE : '%' ;
AT : '@' ;
QUOTE : '"' ;
UNDERSCORE : '_' ;

// Whitespace

TAB : ' ' ;
NEWLINE : (' ' | '\t' )* ( '\r'? '\n' | '\r' )+ ;

// Skips

COMMENT : (' ' | '\t' )* '#' ~( '\n' | '\r' )* -> skip ;
SPACE : ' ' -> skip ;

// Error

INVALID : . ;
Loading