Skip to content

Latest commit

Β 

History

History
415 lines (288 loc) Β· 23.2 KB

expression-grammar.md

File metadata and controls

415 lines (288 loc) Β· 23.2 KB

Expression Grammar

NOTE: Microsoft Power Fx is the new name for canvas apps formula language. These articles are work in progress as we extract the language from canvas apps, integrate it with other products of the Power Platform, and make available as open source. Start with the Power Fx Overview for an introduction to the language.

Microsoft Power Fx is based on formulas that binds a name to an expression. Just like in spreadsheet, 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 spreadsheets, the binding syntax is not exposed and is implied by where the expression is written, for example typing =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 in Power Apps Studio with a serialization format based on YAML for use outside Power Apps Studio.

This article is an annotated version of the grammar. The raw grammar, suitable for use with tools, is also available as a .grammar file.

Grammar conventions

The lexical and syntactic grammars are presented 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 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. A subscripted suffix "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" may precede a list of expansions given on a single line. This is simply shorthand for listing each of the alternatives on a separate line.

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
    Token

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 may 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 do not nest. 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 are not processed within text-literal.

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 produces a logical value.

  LogicalLiteral : one of
    true false

Number literals

A number literal is used to write a numeric value and produces 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

  Sign : one of
    + -

Text literals

A text literal is used to write a sequence of Unicode characters and produces a text value. Text literals are enclosed in double quotes. To include double quotes in the text value, the double quote mark is repeated:

"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 classes Uppercase letter (Lu), Lowercase letter (Ll)
    any Unicode character of the class Titlecase letter (Lt)
    any Unicode character of the classes Letter modifier (Lm), Letter other (Lo)
    any Unicode character of the class Number letter (Nl)

  CombiningCharacter :
    any Unicode character of the classes Non-spacing mark (Mn), 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 SingleQuotedIdentifier can contain any sequence of Unicode characters to be used as an identifier, including keywords, whitespace, comments, and operators. Single quote characters are supported with a double single quote escape sequence.

  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 auto correct to the correct case when a formula is being written.

Separators

  DecimalSeparator:
    . (dot) for language that uses 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)
    ; (semi-colon) if DecimalSeparator is , (comma)

  ChainingSeparator:
    ; (semi-colon) if DecimalSeparator is . (dot)
    ;; (double semi-colon) 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

  PrefixOperator:
    !

  PrefixOperatorRequiresWhitespace:
    Not Whitespace

  PostfixOperator:
    %

Reference operator

  ReferenceOperator: one of
    . !

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