; dt-macro is the top level nonterminal. It defines the possible
; macros generated by gen_defines.py.
;
; A dt-macro starts with uppercase "DT_" followed by either:
;
; - a property-macro, generated for a particular node
;   property
; - some other-macro, a catch-all for other types of macros,
;   which contain either global information about the tree or
;   are special cases
;
; This does *not* cover macros pulled out of DT via Kconfig,
; like CONFIG_SRAM_BASE_ADDRESS, etc.
dt-macro = %s"DT_" ( property-macro / other-macro )

; --------------------------------------------------------------------
; A property-macro is a sequence of:
;
; - node-id: a way to identify a node
; - property-id: a way to identify one of the node's properties
; - property-suf: an optional property-specific suffix
property-macro    = node-id "_" property-id ["_" property-suf]

; A node-id is a way to refer to a node within the devicetree.
; There are a few different flavors.

node-id           = compat-unit-id / inst-id / alias-id

compat-unit-id    = [bus-id-part "_"] compat-id-part "_" unit-addr-id-part
inst-id           = %s"INST_" 1*DIGIT "_" compat-id-part
alias-id          = %s"ALIAS_" alias-id-part

; Various components of a property-macro are just c-idents,
; which are made of uppercase letters, numbers, and underscores.
;
; This is a problem, because it makes it possible for different nodes
; or properties in a devicetree to generate the same macro twice
; with different values.

bus-id-part       = c-ident     ; ID for information about a node's bus
compat-id-part    = c-ident     ; ID for a node's compatible
unit-addr-id-part = c-ident     ; ID for a node's unit-address
alias-id-part     = c-ident     ; ID for an /aliases node property
property-id       = c-ident     ; ID for a node property -- this also
                                ; covers special cases like "reg",
                                ; "interrupts", and "cs-gpios" for now,
                                ; as they all collide with non-special
                                ; cases.
property-suf      = c-ident     ; a suffix for part of a property value,
                                ; like an array index or a phandle
                                ; specifier name converted to a c-ident

; --------------------------------------------------------------------
; An other-macro is a grab bag for everything that isn't a
; property-macro. It reuses some of the nonterminals (namely node-id
; and compat-id-part) defined above.
other-macro     = existence-flag / bus-macro / flash-macro / chosen-macro

existence-flag  = compat-existence-flag / inst-existence-flag
compat-flag     = %s"COMPAT_" c-ident
inst-flag       = %s"INST_" 1*DIGIT "_" c-ident

bus-macro       = bus-name-macro / on-bus-macro
bus-name-macro  = node-id %s"_BUS_NAME"
on-bus-macro    = compat-id-part %s"_BUS_" bus-name
bus-name        = c-ident       ; a bus name ("i2c") to a DT C
                                ; identifier ("I2C")

flash-macro     = %s"FLASH_AREA_" node-label-ident "_" flash-suf
flash-suf       = %s"ID" / %s"READ_ONLY" / (%s"OFFSET" ["_" 1*DIGIT]) /
                  (%s"SIZE" ["_" 1*DIGIT]) / %s"DEV"

; Macros generated from /chosen node properties.
chosen-macro    = chosen-flash /
                  %s"CODE_PARTITION_OFFSET" / %s"CODE_PARTITION_SIZE" /
                  %s"CCM_BASE_ADDRESS" / %s"CCM_SIZE" /
                  %s"DTCM_BASE_ADDRESS" / %s"DTCM_SIZE" /
                  %s"IPC_SHM_BASE_ADDRESS" / %s"IPC_SHM_SIZE"
; These come from the /chosen/zephyr,flash property.
chosen-flash    = %s"FLASH_BASE_ADDRESS" /
                  %s"FLASH_SIZE" /
                  %s"FLASH_ERASE_BLOCK_SIZE" /
                  %s"FLASH_WRITE_BLOCK_SIZE"

; --------------------------------------------------------------------
; Helper definitions.

; A c-ident is one or more:
; - uppercase letters (A-Z)
; - numbers (0-9)
; - underscores ("_")
;
; They are the result of converting names or combinations of names
; from devicetree to a valid component of a C identifier by
; uppercasing letters and converting non-alphanumeric characters to
; underscores.
c-ident = 1*( UPPER / DIGIT / "_" )

; a node's "label" property value, as an identifier
node-label-ident = c-ident

; "uppercase ASCII letter" turns out to be pretty annoying to specify
; in RFC-7405 syntax.
;
; This is just ASCII letters A (0x41) through Z (0x5A).
UPPER = %x41-5A
