Clinical Quality Language Specification, published by Clinical Decision Support WG. This guide is not an authorized publication; it is the continuous build for version 1.5.3 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/cql/ and changes regularly. See the Directory of published versions
grammar fhirpath;
// Grammar rules
// [FHIRPath](http://hl7.org/fhirpath/N1) Normative Release
//prog: line (line)*;
//line: ID ( '(' expr ')') ':' expr '\r'? '\n';
expression
: term #termExpression
| expression '.' invocation #invocationExpression
| expression '[' expression ']' #indexerExpression
| ('+' | '-') expression #polarityExpression
| expression ('*' | '/' | 'div' | 'mod') expression #multiplicativeExpression
| expression ('+' | '-' | '&') expression #additiveExpression
| expression ('is' | 'as') typeSpecifier #typeExpression
| expression '|' expression #unionExpression
| expression ('<=' | '<' | '>' | '>=') expression #inequalityExpression
| expression ('=' | '~' | '!=' | '!~') expression #equalityExpression
| expression ('in' | 'contains') expression #membershipExpression
| expression 'and' expression #andExpression
| expression ('or' | 'xor') expression #orExpression
| expression 'implies' expression #impliesExpression
//| (IDENTIFIER)? '=>' expression #lambdaExpression
;
term
: invocation #invocationTerm
| literal #literalTerm
| externalConstant #externalConstantTerm
| '(' expression ')' #parenthesizedTerm
;
literal
: '{' '}' #nullLiteral
| ('true' | 'false') #booleanLiteral
| STRING #stringLiteral
| NUMBER #numberLiteral
| DATE #dateLiteral
| DATETIME #dateTimeLiteral
| TIME #timeLiteral
| quantity #quantityLiteral
;
externalConstant
: '%' ( identifier | STRING )
;
invocation // Terms that can be used after the function/member invocation '.'
: identifier #memberInvocation
| function #functionInvocation
| '$this' #thisInvocation
| '$index' #indexInvocation
| '$total' #totalInvocation
;
function
: identifier '(' paramList? ')'
;
paramList
: expression (',' expression)*
;
quantity
: NUMBER unit?
;
unit
: dateTimePrecision
| pluralDateTimePrecision
| STRING // UCUM syntax for units of measure
;
dateTimePrecision
: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'
;
pluralDateTimePrecision
: 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds'
;
typeSpecifier
: qualifiedIdentifier
;
qualifiedIdentifier
: identifier ('.' identifier)*
;
identifier
: IDENTIFIER
| DELIMITEDIDENTIFIER
| 'as'
| 'contains'
| 'in'
| 'is'
;
/****************************************************************
Lexical rules
*****************************************************************/
/*
NOTE: The goal of these rules in the grammar is to provide a date
token to the parser. As such it is not attempting to validate that
the date is a correct date, that task is for the parser or interpreter.
*/
DATE
: '@' DATEFORMAT
;
DATETIME
: '@' DATEFORMAT 'T' (TIMEFORMAT TIMEZONEOFFSETFORMAT?)?
;
TIME
: '@' 'T' TIMEFORMAT
;
fragment DATEFORMAT
: [0-9][0-9][0-9][0-9] ('-'[0-9][0-9] ('-'[0-9][0-9])?)?
;
fragment TIMEFORMAT
: [0-9][0-9] (':'[0-9][0-9] (':'[0-9][0-9] ('.'[0-9]+)?)?)?
;
fragment TIMEZONEOFFSETFORMAT
: ('Z' | ('+' | '-') [0-9][0-9]':'[0-9][0-9])
;
IDENTIFIER
: ([A-Za-z] | '_')([A-Za-z0-9] | '_')* // Added _ to support CQL (FHIR could constrain it out)
;
DELIMITEDIDENTIFIER
: '`' (ESC | .)*? '`'
;
STRING
: '\'' (ESC | .)*? '\''
;
// Also allows leading zeroes now (just like CQL and XSD)
NUMBER
: [0-9]+('.' [0-9]+)?
;
// Pipe whitespace to the HIDDEN channel to support retrieving source text through the parser.
WS
: [ \r\n\t]+ -> channel(HIDDEN)
;
COMMENT
: '/*' .*? '*/' -> channel(HIDDEN)
;
LINE_COMMENT
: '//' ~[\r\n]* -> channel(HIDDEN)
;
fragment ESC
: '\\' ([`'\\/fnrt] | UNICODE) // allow \`, \', \\, \/, \f, etc. and \uXXX
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;