Skip to content

Tact 规范

Tact 编译器中使用的 Tact 语法是用 Ohm 语言编写的,该语言基于解析表达式语法(PEGs),这是一种形式化描述语法的方式,类似于正则表达式和上下文无关文法。

ts
Tact {
 
    // 程序的起始点
    Program = ProgramItem*
    ProgramItem = Struct
                | Contract
                | Primitive
                | StaticFunction
                | NativeFunction
                | ProgramImport
                | Trait
                | Constant
    ProgramImport = import stringLiteral ";"
 
    // 内置声明
    Primitive = "primitive" Type ";"
 
    // 静态函数
    StaticFunction = Function
    NativeFunction = nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ")" ";" --withVoid
                   | nameAttribute "(" funcId ")" FunctionAttribute* native id "(" ListOf<FunctionArg,","> ")" ":" Type ";" --withType
 
    // 字段声明
    Type = typeLiteral "?" --optional
         | typeLiteral --required
         | "map" "<" typeLiteral (as id)? "," typeLiteral (as id)? ">" --map
         | "bounced" "<" typeLiteral ">" --bounced
    Field = id ":" Type ";" --default
          | id ":" Type "=" Expression ";" --defaultWithInit
          | id ":" Type as id ";" --withSerialization
          | id ":" Type as id "=" Expression ";" --withSerializationAndInit
 
    // 常量
    ConstantAttribute = virtual    --virtual
                      | override   --override
                      | abstract   --abstract
    Constant = ConstantAttribute* ~fun const id ":" Type "=" Expression ";" --withValue
             | ConstantAttribute* ~fun const id ":" Type ";"                --withEmpty
 
    // 结构体
    Struct = "struct" typeLiteral "{" StructBody* "}" --originary
           | "message" typeLiteral "{" StructBody* "}" --message
           | "message" "(" integerLiteral ")" typeLiteral "{" StructBody* "}" --messageWithId
    StructBody = Field
 
    // 合约
    Contract = ContractAttribute* contract id "{" ContractBody* "}" --simple
             | ContractAttribute* contract id with ListOf<id,","> "{" ContractBody* "}" --withTraits
    ContractInit = "init" "(" ListOf<FunctionArg,","> ")" "{" Statement* "}"
    ContractBody = Field
                 | ContractInit
                 | ReceiveFunction
                 | Function
                 | Constant
 
    // 特性
    Trait = ContractAttribute* trait id "{" TraitBody* "}" --originary
          | ContractAttribute* trait id with ListOf<id,","> "{" TraitBody* "}" --withTraits
    TraitBody = Field
              | ReceiveFunction
              | Function
              | Constant
 
    // 合约属性
    ContractAttribute = "@interface" "(" stringLiteral ")" --interface
 
    // 函数
    FunctionAttribute = "get"     --getter
                      | mutates   --mutates
                      | extends   --extends
                      | virtual   --virtual
                      | override  --override
                      | inline    --inline
                      | abstract  --abstract
    Function = FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" "{" Statement* "}" --withVoid
             | FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ":" Type "{" Statement* "}" --withType
             | FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ";" --abstractVoid
             | FunctionAttribute* fun id "(" ListOf<FunctionArg,","> ")" ":" Type ";" --abstractType
    FunctionArg = id ":" Type
 
    ReceiveFunction = "receive" "(" FunctionArg ")" "{" Statement* "}" --simple
                    | "receive" "(" ")" "{" Statement* "}" --empty
                    | "receive" "(" stringLiteral ")" "{" Statement* "}" --comment
                    | "bounced" "(" FunctionArg ")" "{" Statement* "}" --bounced
                    | "external" "(" FunctionArg ")" "{" Statement* "}" --externalSimple
                    | "external" "(" stringLiteral ")" "{" Statement* "}" --externalComment
                    | "external" "(" ")" "{" Statement* "}" --externalEmpty
 
    // 语句
    Statement = StatementLet
              | StatementBlock
              | StatementReturn
              | StatementExpression
              | StatementAssign
              | StatementAugmentedAssign
              | StatementCondition
              | StatementWhile
              | StatementRepeat
              | StatementUntil
    StatementBlock = "{" Statement* "}"
    StatementLet = let id ":" Type "=" Expression ";"
    StatementReturn = return Expression ";" --withExpression
                    | return ";" --withoutExpression    
    StatementExpression = Expression ";"
    StatementAssign = LValue "=" Expression ";"
    StatementAugmentedAssign = StatementAugmentedAssignAdd
                             | StatementAugmentedAssignSub
                             | StatementAugmentedAssignMul
                             | StatementAugmentedAssignDiv
                             | StatementAugmentedAssignRem
    StatementAugmentedAssignAdd = LValue "+=" Expression ";"
    StatementAugmentedAssignSub = LValue "-=" Expression ";"
    StatementAugmentedAssignMul = LValue "*=" Expression ";"
    StatementAugmentedAssignDiv = LValue "/=" Expression ";"
    StatementAugmentedAssignRem = LValue "%=" Expression ";"
    StatementCondition = if Expression "{" Statement* "}" ~else --simple
                       | if Expression "{" Statement* "}" else "{" Statement* "}" --withElse
                       | if Expression "{" Statement* "}" else StatementCondition --withElseIf
    StatementWhile = while "(" Expression ")" "{" Statement* "}"
    StatementRepeat = repeat "(" Expression ")" "{" Statement* "}"
    StatementUntil = do "{" Statement* "}" until "(" Expression ")" ";"
 
    // 左值
    LValue = id "." LValue --more
           | id --single
 
    // 表达式
    Expression = ExpressionConditional
    ExpressionConditional = ExpressionOr "?" ExpressionOr ":" ExpressionConditional --ternary
                          | ExpressionOr
    ExpressionOr = ExpressionOr "||" ExpressionAnd --or
                 | ExpressionAnd
    ExpressionAnd = ExpressionAnd "&&" ExpressionCompare --and
                  | ExpressionCompare
    ExpressionCompare = ExpressionCompare "!=" ExpressionBinary --not
                      | ExpressionCompare "==" ExpressionBinary --eq
                      | ExpressionCompare ">" ExpressionBinary --gt
                      | ExpressionCompare ">=" ExpressionBinary --gte
                      | ExpressionCompare "<" ExpressionBinary --lt
                      | ExpressionCompare "<=" ExpressionBinary --lte
                      | ExpressionBinary
    ExpressionBinary = ExpressionBinary ">>" ExpressionAdd --shr
                    | ExpressionBinary "<<" ExpressionAdd --shl
                    | ExpressionBinary "&" ExpressionAdd --bin_and
                    | ExpressionBinary "|" ExpressionAdd --bin_or
                    | ExpressionAdd
    ExpressionAdd = ExpressionAdd "+" ~"+" ExpressionMul --add
                  | ExpressionAdd "-" ~"-" ExpressionMul --sub
                  | ExpressionMul
    ExpressionMul = ExpressionMul "*" ExpressionUnary --mul
                  | ExpressionMul "/" ExpressionUnary --div
                  | ExpressionMul "%" ExpressionUnary --rem
                  | ExpressionUnary
    ExpressionUnary = "-" ExpressionUnarySuffix --neg
                    | "+" ExpressionUnarySuffix --add
                    | "!" ExpressionUnarySuffix --not
                    | ExpressionUnarySuffix
    ExpressionUnarySuffix = ExpressionValue "!!" --notNull
                          | ExpressionValue
    ExpressionBracket = "(" Expression ")"
 
    // 顺序很重要
    ExpressionValue = ExpressionCall
                    | ExpressionField
                    | ExpressionStaticCall
                    | ExpressionBracket
                    | ExpressionNew
                    | integerLiteral
                    | boolLiteral
                    | id
                    | null
                    | ExpressionInitOf
                    | ExpressionString
    ExpressionString = stringLiteral
    ExpressionField = ExpressionValue "." id ~"("
    ExpressionCall = ExpressionValue "." id "(" ListOf<Expression, ","> ")"
    ExpressionNew = id "{" ListOf<NewParameter, ","> "}"
    NewParameter = id ":" Expression
    ExpressionStaticCall = id "(" ListOf<Expression, ","> ")"
    ExpressionInitOf = initOf id "(" ListOf<Expression, ","> ")"
 
    // 类型字面量
    typeLiteral = letterAsciiUC typeLiteralPart*
    typeLiteralPart = letterAscii | digit | "_"
 
    // 整数字面量
    // hexDigit 在 Ohm 的内置规则中已定义(否则:hexDigit = "0".."9" | "a".."f" | "A".."F")
    // digit 在 Ohm 的内置规则中已定义(否则:digit = "0".."9")
    integerLiteral = integerLiteralHex | integerLiteralBin | integerLiteralOct | integerLiteralDec // 顺序很重要
    integerLiteralDec = nonZeroDigit ("_"? digit)*  --nonZeroIntegerLiteralDec
                      | "0" digit*                  --integerLiteralWithLeadingZero
    integerLiteralHex = ("0x" | "0X") hexDigit ("_"? hexDigit)*
    integerLiteralBin = ("0b" | "0B") binDigit ("_"? binDigit)*
    integerLiteralOct = ("0o" | "0O") octDigit ("_"? octDigit)*
    binDigit = "0" | "1"
    octDigit = "0".."7"
    nonZeroDigit = "1".."9"
 
    // 字母
    letterAsciiLC = "a".."z"
    letterAsciiUC = "A".."Z"
    letterAscii = letterAsciiLC | letterAsciiUC
    letterComment = letterAsciiLC | letterAsciiUC | digit | "_"
 
    // ID 字面量
    idStart = letterAscii | "_"
    idPart = letterAscii | digit | "_"
    id = ~reservedWord #idStart #(idPart*)
 
    // FunC id
    funcLetter = letterAscii | "_" | "'" | "?" | "!" | "::" | "&"
    funcId = funcLetter #(funcLetter | digit)*
 
    // 布尔字面量
    boolLiteral = ("true" | "false") ~idPart
 
    // 字符串字面量
    stringLiteralCharacter = ~("\"" | "\\" | lineTerminator) any
    stringLiteral = "\"" stringLiteralCharacter* "\""
 
    // 关键词
    // 注意顺序很重要
    keyword = fun
            | let
            | return
            | extend
            | native
            | public
            | null
            | if
            | else
            | while
            | repeat
            | do
            | until
            | as
            | mutates
            | extends
            | import
            | with
            | trait
            | initOf
            | override
            | abstract
            | virtual
            | inline
            | const
    contract = "contract" ~idPart
    let = "let" ~idPart
    fun = "fun" ~idPart
    return = "return" ~idPart
    extend = "extend" ~idPart
    native = "native" ~idPart
    public = "public" ~idPart
    null = "null" ~idPart
    if = "if" ~idPart
    else = "else" ~idPart
    while = "while" ~idPart
    repeat = "repeat" ~idPart
    do = "do" ~idPart
    until = "until" ~idPart
    as = "as" ~idPart
    mutates = "mutates" ~idPart
    extends = "extends" ~idPart
    import = "import" ~idPart
    with = "with" ~idPart
    trait = "trait" ~idPart
    initOf = "initOf" ~idPart
    virtual = "virtual" ~idPart
    override = "override" ~idPart
    inline = "inline" ~idPart
    const = "const" ~idPart
    abstract = "abstract" ~idPart
 
    // 属性
    nameAttribute = "@name"
 
    // 保留字
    reservedWord = keyword
 
    // 注释
    space += comment | lineTerminator
    comment = multiLineComment | singleLineComment
    lineTerminator = "\n" | "\r" | "\u2028" | "\u2029"
    multiLineComment = "/*" (~"*/" any)* "*/"
    singleLineComment = "//" (~lineTerminator any)*
}