; Yul Library
;
; Copyright (C) 2021 Kestrel Institute (http://www.kestrel.edu)
;
; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
;
; Author: Alessandro Coglio (coglio@kestrel.edu)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; This file contains an ABNF grammar of Yul,
; derived from the official grammar in the Solidity specification
; (https://docs.soliditylang.org/en/latest/grammar.html).
; This is the new grammar of Yul; see :DOC CONCRETE-SYNTAX.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Most of the ABNF rules below correspond exactly
; to the rules in the Solidity/Yul grammar.
; We add some additional rules here,
; which correspond to some regex constructs used in the Solidity/Yul grammar,
; as indicated by the comments below saying 'corresponds to ...'.
; We omit the 'yul-' prefix since the context is Yul here.
; We organize the rules bottom-up.
; We leave out the yul-evm-builtin rule because that seems to belong
; more to the EVM dialect of Yul than to generic Yul.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

boolean = %s"true" / %s"false"

; corresponds to '"':
dquote = %x22

; corresponds to '\'':
squote = %x27

; corresponds to '\n':
lf = %xA;

; corresponds to '\r':
cr = %xD;

; corresponds to [0-9]:
decimal-digit = %x30-39

; corresponds to [1-9]:
nonzero-decimal-digit = %x31-39

; corresponds to [0-9a-fA-F]:
hex-digit = decimal-digit / %i"a" / %i"b" / %i"c" / %i"d" / %i"e" / %i"f"

decimal-number = "0" / nonzero-decimal-digit *decimal-digit

hex-number = %s"0x" *hex-digit

hex-string = dquote [ 2hex-digit *( [ "_" ] 2hex-digit ) ] dquote
           / squote [ 2hex-digit *( [ "_" ] 2hex-digit ) ] squote

double-quoted-printable = %x20-21 / %x23-5B / %x5D-7E ; anything but " or \

single-quoted-printable = %x20-26 / %x28-5B / %x5D-7E ; anything but ' or \

escape-sequence = "\"
                  ( ( squote / dquote / %s"n" / %s"r" / %s"t" / lf / cr )
                  / %s"u" 4hex-digit
                  / %s"x" 2hex-digit )

string-literal = dquote *( double-quoted-printable / escape-sequence ) dquote
               / squote *( single-quoted-printable / escape-sequence ) squote

literal = decimal-number
        / hex-number
        / boolean
        / string-literal
        / hex-string

; corresponds to [a-z]:
lowercase-letter = %x61-7A

; corresponds to [A-Z]:
uppercase-letter = %x41-5A

; corresponds to [a-zA-Z$_]:
identifier-start = lowercase-letter / uppercase-letter / "$" / "_"

; corresponds to [a-zA-Z0-9$_]:
identifier-rest = identifier-start / decimal-digit

identifier = identifier-start *identifier-rest

path = identifier *( "." identifier )

expression = path / function-call / literal

function-call = identifier "(" [ expression *( "," expression ) ] ")"

function-definition = %s"function" identifier
                      "(" [ identifier *( "," identifier ) ] ")"
                      "->" identifier *( "," identifier )
                      block

if-statement = %s"if" expression block

for-statement = %s"for" block expression block block

switch-statement = expression
                   ( 1*( %s"case" literal block ) [ %s"default" block ]
                   / %s"default" block )

assignment = path ":=" expression
           / path 1*( "," path ) ":=" function-call

variable-declaration = %s"let" identifier [ ":=" expression ]
                     / %s"let" identifier *( "," identifier )
                       [ ":=" function-call ]

block = "{" *statement "}"

statement = block
          / variable-declaration
          / assignment
          / function-call
          / if-statement
          / for-statement
          / switch-statement
          / %s"leave"
          / %s"break"
          / %s"continue"
          / function-definition
