Expression grammar
Note
Microsoft Power Fx is the new name for the formula language for canvas apps. These articles are a work in progress as we extract the language from canvas apps, integrate it with other Microsoft Power Platform products, and make it available as open source. Start with the Microsoft Power Fx overview for an introduction to the language.
Microsoft Power Fx is based on formulas that bind a name to an expression. Just like in Excel worksheets, as inbound dependencies to the expression change, the expression is recalculated and the value of the name changes, possibly cascading the recalculation into other formulas.
This grammar covers the expression part of the formula. Binding to a name to create a formula is dependent on how Power Fx is integrated. In worksheets, the binding syntax isn't exposed, it's implied by the location where the expression is written—for example, entering =B1
in the A1 cell. In some cases, no binding is required at all and Power Fx is used as an expression evaluator, for example in supporting calculated columns of a database table. For Power Apps, the binding is implied when working in Power Apps Studio with a serialization format based on YAML for use outside Power Apps Studio.
Grammar conventions
The lexical and syntactic grammars are presented by using grammar productions. Each grammar production defines a non-terminal symbol and the possible expansions of that non-terminal symbol into sequences of non-terminal or terminal symbols. In grammar productions, non-terminal symbols are shown in italic type, and terminal symbols are shown in a fixed-width font.
The first line of a grammar production is the name of the non-terminal symbol being defined, followed by a colon. Each successive indented line contains a possible expansion of the non-terminal symbol given as a sequence of non-terminal or terminal symbols. For example, the production:
GlobalIdentifier :
[@
Identifier ]
defines a GlobalIdentifier to consist of the token [@
, followed by an Identifier, followed by the token ]
.
When there is more than one possible expansion of a non-terminal symbol, the alternatives are listed on separate lines. The subscript "opt" is used to indicate an optional symbol. For example, the production:
FunctionCall :
FunctionIdentifier (
FunctionArgumentsopt )
is shorthand for:
FunctionCall :
FunctionIdentifier (
)
FunctionIdentifier (
FunctionArguments )
Alternatives are normally listed on separate lines, though in cases where there are many alternatives, the phrase "one of" might precede a list of expansions given on a single line. This is simply shorthand for listing each of the alternatives on separate lines.
For example, the production:
DecimalDigit : one of
0
1
2
3
4
5
6
7
8
9
is shorthand for:
DecimalDigit :
0
1
2
3
4
5
6
7
8
9
Lexical analysis
The lexical-unit production defines the lexical grammar for a Power Fx expression. Every valid Power Fx expression conforms to this grammar.
ExpressionUnit :
ExpressionElementsopt
ExpressionElements :
ExpressionElement
ExpressionElement ExpressionElementsopt
ExpressionElement :
Whitespace
Comment
At the lexical level, a Power Fx expression consists of a stream of Whitespace, Comment, and Token elements. Each of these productions is covered in the following sections. Only Token elements are significant in the syntactic grammar.
Whitespace
Whitespace is used to separate comments and tokens within a Power Apps document.
Whitespace :
any Unicode Space separator (class Zs)
any Unicode Line separator (class Zl)
any Unicode Paragraph separator (class Zp)
Horizontal tab character (U+0009)
Line feed character (U+000A)
Vertical tab character (U+000B)
Form feed character (U+000C)
Carriage return character (U+000D)
Next line character (U+0085)
Comments
Two forms of comments are supported:
- Single-line comments that start with the characters
//
and extend to the end of the source line. - Delimited comments that start with the characters
/*
and end with the characters*/
. Delimited comments can span multiple lines.
Comment :
DelimitedComment
SingleLineComment
SingleLineComment :
//
SingleLineCommentCharactersopt
SingleLineCommentCharacters :
SingleLineCommentCharacter
SingleLineCommentCharacter SingleLineCommentCharactersopt
SingleLineCommentCharacter :
any Unicode characters except a NewLineCharacter
DelimitedComment :
/*
DelimitedCommentCharactersopt */
DelimitedCommentCharacters :
DelimitedCommentCharactersNoAsterisk DelimitedCommentCharactersopt
*
DelimitedCommentAfterAsteriskCharacters
DelimitedCommentAfterAsteriskCharacters :
DelimitedCommentNoSlashAsteriskCharacter DelimitedCommentCharactersopt
*
DelimitedCommentAfterAsteriskCharacters
DelimitedCommentCharactersNoAsterisk :
any Unicode character except * (asterisk)
DelimitedCommentNoSlashAsteriskCharacter :
any Unicode character except a / (slash) or * (asterisk)
Comments aren't nested. The character sequences /*
and */
have no special meaning within a single-line comment, and the character sequences //
and /*
have no special meaning within a delimited comment.
Comments aren't processed within text-literal strings.
The following example includes two delimited comments:
/* Hello, world
*/
"Hello, world" /* This is an example of a text literal */
The following examples include three single-line comments:
// Hello, world
//
"Hello, world" // This is an example of a text literal
Literals
A literal is a source code representation of a value.
Literal :
LogicalLiteral
NumberLiteral
TextLiteral
Logical literals
A logical literal is used to write the values true and false, and produce a logical value.
LogicalLiteral : one of
true
false
Number literals
A number literal is used to write a numeric value and produce a number value.
NumberLiteral :
DecimalDigits ExponentPartopt
DecimalDigits DecimalSeparator DecimalDigitsopt ExponentPartopt
DecimalSeparator DecimalDigits ExponentPartopt
DecimalDigits :
DecimalDigit
DecimalDigits DecimalDigit
DecimalDigit : one of
0
1
2
3
4
5
6
7
8
9
ExponentPart :
ExponentIndicator Signopt DecimalDigits
ExponentIndicator : one of
e
E
Text literals
A text literal is used to write a sequence of Unicode characters and produce a text value. Text literals are enclosed in double quotation marks. To include double quotation marks in the text value, repeat the double quotation marks, as shown in the following example:
"The ""quoted"" text" // The "quoted" text
TextLiteral :
"
TextLiteralCharactersopt "
TextLiteralCharacters :
TextLiteralCharacter TextLiteralCharactersopt
TextLiteralCharacter :
TextCharacterNoDoubleQuote
DoubleQuoteEscapeSequence
TextCharacterNoDoubleQuote :
any Unicode code point except double quote
DoubleQuoteEscapeSequence :
"
"
Identifiers
An identifier is a name used to refer to a value. Identifiers can either be regular identifiers or single quoted identifiers.
Identifier :
IdentifierName but not Operator or ContextKeyword
IdentifierName :
IdentifierStartCharacter IdentifierContinueCharactersopt
'
SingleQuotedIdentifier '
IdentifierStartCharacter :
LetterCharacter
_
IdentifierContinueCharacter :
IdentifierStartCharacter
DecimalDigitCharacter
ConnectingCharacter
CombiningCharacter
FormattingCharacter
IdentifierContinueCharacters :
IdentifierContinueCharacter IdentifierContinueCharactersopt
LetterCharacter :
any Unicode character of the class Uppercase letter (Lu) or Lowercase letter (Ll)
any Unicode character of the class Titlecase letter (Lt)
any Unicode character of the class Letter modifier (Lm) or Letter other (Lo)
any Unicode character of the class Number letter (Nl)
CombiningCharacter :
any Unicode character of the class Non-spacing mark (Mn) or Spacing combining mark (Mc)
DecimalDigitCharacter :
any Unicode character of the class Decimal digit (Nd)
ConnectingCharacter :
any Unicode character of the class Connector punctuation (Pc)
FormattingCharacter :
any Unicode character of the class Format (Cf)
Single quoted identifiers
A single quoted identifier can contain any sequence of Unicode characters to be used as an identifier, including keywords, whitespace, comments, and operators. Single quotation mark characters are supported with an escape sequence of two single quotation marks.
SingleQuotedIdentifier :
SingleQuotedIdentifierCharacters
SingleQuotedIdentifierCharacters :
SingleQuotedIdentifierCharacter SingleQuotedIdentifierCharactersopt
SingleQuotedIdentifierCharacter :
TextCharactersNoSingleQuote
SingleQuoteEscapeSequence
TextCharactersNoSingleQuote :
any Unicode character except ' (U+0027)
SingleQuoteEscapeSequence :
'
'
Disambiguated identifier
DisambiguatedIdentifier:
TableColumnIdentifier
GlobalIdentifier
TableColumnIdentifier :
Identifier [@
Identifier ]
GlobalIdentifier:
[@
Identifier ]
Context keywords
ContextKeyword:
Parent
Self
ThisItem
ThisRecord
Case sensitivity
Power Apps identifiers are case-sensitive. The authoring tool will automatically change them to the correct case when a formula is being written.
Separators
DecimalSeparator:
.
(dot) for languages that use a dot as the separator for decimal numbers, for example 1.23
,
(comma) for languages that use a comma as the separator for decimal numbers, for example 1,23
ListSeparator:
,
(comma) if DecimalSeparator is .
(dot)
;
(semicolon) if DecimalSeparator is ,
(comma)
ChainingSeparator:
;
(semicolon) if DecimalSeparator is .
(dot)
;;
(double semicolon) if DecimalSeparator is ,
(comma)
Operators
Operators are used in formulas to describe operations involving one or more operands. For example, the expression a + b
uses the +
operator to add the two operands a
and b
.
Operator:
BinaryOperator
BinaryOperatorRequiresWhitespace
PrefixOperator
PrefixOperatorRequiresWhitespace
PostfixOperator
BinaryOperator: one of
=
<
<=
>
>=
<>
+
-
*
/
^
&
&&
||
in
exactin
BinaryOperatorRequiresWhitespace:
And
Whitespace
Or
Whitespace
PrefixOperatorRequiresWhitespace:
Not
Whitespace
Reference operator
Object reference
Reference:
BaseReference
BaseReference ReferenceOperator ReferenceList
BaseReference:
Identifier
DisambiguatedIdentifier
ContextKeyword
ReferenceList:
Identifier
Identifier ReferenceOperator ReferenceList
Inline record
InlineRecord:
{
InlineRecordListopt }
InlineRecordList:
Identifier :
Expression
Identifier :
Expression ListSeparator InlineRecordList
Inline table
InlineTable:
[
InlineTableListopt ]
InlineTableList:
Expression
Expression ListSeparator InlineTableList
Expression
Expression:
Literal
Reference
InlineRecord
InlineTable
FunctionCall
(
Expression )
PrefixOperator Expression
Expression PostfixOperator
Expression BinaryOperator Expression
Chained expressions
ChainedExpression:
Expression
Expression ChainingSeparator ChainedExpressionopt
Function call
FunctionCall:
FunctionIdentifier (
FunctionArgumentsopt )
FunctionIdentifier:
Identifier
Identifier .
FunctionIdentifier
FunctionArguments:
ChainedExpression
ChainedExpression ListSeparator FunctionArguments