This is the context-free grammar for Emboss. Terminal symbols are in `"quotes"` or are named in `CamelCase`; nonterminal symbols are named in `snake_case`. The term `` to the right of the `->` indicates an empty production (a rule where the left-hand-side may be parsed from an empty string). This listing is auto-generated from the grammar defined in `module_ir.py`. Note that, unlike in many languages, comments are included in the grammar. This is so that comments can be handled more easily by the autoformatter; comments are ignored by the compiler. This is distinct from *documentation*, which is included in the IR for use by documentation generators. ```shell module -> comment-line* doc-line* import-line* attribute-line* type-definition* type-definition -> bits | enum | external | struct struct -> "struct" type-name delimited-parameter-definition-list? ":" Comment? eol struct-body struct-body -> Indent doc-line* attribute-line* type-definition* struct-field-block Dedent struct-field-block -> | conditional-struct-field-block struct-field-block | unconditional-struct-field struct-field-block unconditional-struct-field -> anonymous-bits-field-definition | field | inline-bits-field-definition | inline-enum-field-definition | inline-struct-field-definition | virtual-field virtual-field -> "let" snake-name "=" expression Comment? eol field-body? field-body -> Indent doc-line* attribute-line* Dedent expression -> choice-expression choice-expression -> logical-expression | logical-expression "?" logical-expression ":" logical-expression logical-expression -> and-expression | comparison-expression | or-expression or-expression -> comparison-expression or-expression-right+ or-expression-right -> or-operator comparison-expression or-operator -> "||" comparison-expression -> additive-expression | additive-expression equality-expression-right+ | additive-expression greater-expression-right-list | additive-expression inequality-operator additive-expression | additive-expression less-expression-right-list less-expression-right-list -> equality-expression-right* less-expression-right equality-or-less-expression-right* equality-or-less-expression-right -> equality-expression-right | less-expression-right less-expression-right -> less-operator additive-expression less-operator -> "<" | "<=" inequality-operator -> "!=" greater-expression-right-list -> equality-expression-right* greater-expression-right equality-or-greater-expression-right* equality-or-greater-expression-right -> equality-expression-right | greater-expression-right greater-expression-right -> greater-operator additive-expression greater-operator -> ">" | ">=" equality-expression-right -> equality-operator additive-expression equality-operator -> "==" additive-expression -> times-expression additive-expression-right* additive-expression-right -> additive-operator times-expression additive-operator -> "+" | "-" times-expression -> negation-expression times-expression-right* times-expression-right -> multiplicative-operator negation-expression multiplicative-operator -> "*" negation-expression -> additive-operator bottom-expression | bottom-expression bottom-expression -> "(" expression ")" | boolean-constant | builtin-reference | constant-reference | field-reference | function-name "(" argument-list ")" | numeric-constant numeric-constant -> Number argument-list -> | expression comma-then-expression* comma-then-expression -> "," expression function-name -> "$lower_bound" | "$max" | "$present" | "$upper_bound" field-reference -> snake-reference field-reference-tail* field-reference-tail -> "." snake-reference snake-reference -> builtin-field-word | snake-word snake-word -> SnakeWord builtin-field-word -> "$max_size_in_bits" | "$max_size_in_bytes" | "$min_size_in_bits" | "$min_size_in_bytes" | "$size_in_bits" | "$size_in_bytes" constant-reference -> constant-reference-tail | snake-reference "." constant-reference-tail constant-reference-tail -> constant-word | type-word "." constant-reference-tail | type-word "." snake-reference type-word -> CamelWord constant-word -> ShoutyWord builtin-reference -> builtin-word builtin-word -> "$is_statically_sized" | "$next" | "$static_size_in_bits" boolean-constant -> BooleanConstant and-expression -> comparison-expression and-expression-right+ and-expression-right -> and-operator comparison-expression and-operator -> "&&" snake-name -> snake-word inline-struct-field-definition -> field-location "struct" snake-name abbreviation? ":" Comment? eol struct-body abbreviation -> "(" snake-word ")" field-location -> expression "[" "+" expression "]" inline-enum-field-definition -> field-location "enum" snake-name abbreviation? ":" Comment? eol enum-body enum-body -> Indent doc-line* attribute-line* enum-value+ Dedent enum-value -> constant-name "=" expression attribute* doc? Comment? eol enum-value-body? enum-value-body -> Indent doc-line* attribute-line* Dedent doc -> Documentation attribute -> "[" attribute-context? "$default"? snake-word ":" attribute-value "]" attribute-value -> expression | string-constant string-constant -> String attribute-context -> "(" snake-word ")" constant-name -> constant-word inline-bits-field-definition -> field-location "bits" snake-name abbreviation? ":" Comment? eol bits-body bits-body -> Indent doc-line* attribute-line* type-definition* bits-field-block Dedent bits-field-block -> | conditional-bits-field-block bits-field-block | unconditional-bits-field bits-field-block unconditional-bits-field -> unconditional-anonymous-bits-field | virtual-field unconditional-anonymous-bits-field -> field | inline-bits-field-definition | inline-enum-field-definition conditional-bits-field-block -> "if" expression ":" Comment? eol Indent unconditional-bits-field+ Dedent field -> field-location type snake-name abbreviation? attribute* doc? Comment? eol field-body? type -> type-reference delimited-argument-list? type-size-specifier? array-length-specifier* array-length-specifier -> "[" "]" | "[" expression "]" type-size-specifier -> ":" numeric-constant delimited-argument-list -> "(" argument-list ")" type-reference -> snake-word "." type-reference-tail | type-reference-tail type-reference-tail -> type-word | type-word "." type-reference-tail anonymous-bits-field-definition -> field-location "bits" ":" Comment? eol anonymous-bits-body anonymous-bits-body -> Indent attribute-line* anonymous-bits-field-block Dedent anonymous-bits-field-block -> | conditional-anonymous-bits-field-block anonymous-bits-field-block | unconditional-anonymous-bits-field anonymous-bits-field-block conditional-anonymous-bits-field-block -> "if" expression ":" Comment? eol Indent unconditional-anonymous-bits-field+ Dedent conditional-struct-field-block -> "if" expression ":" Comment? eol Indent unconditional-struct-field+ Dedent eol -> "\n" comment-line* delimited-parameter-definition-list -> "(" parameter-definition-list ")" parameter-definition-list -> | parameter-definition parameter-definition-list-tail* parameter-definition-list-tail -> "," parameter-definition parameter-definition -> snake-name ":" type type-name -> type-word external -> "external" type-name ":" Comment? eol external-body external-body -> Indent doc-line* attribute-line* Dedent enum -> "enum" type-name ":" Comment? eol enum-body bits -> "bits" type-name delimited-parameter-definition-list? ":" Comment? eol bits-body attribute-line -> attribute Comment? eol import-line -> "import" string-constant "as" snake-word Comment? eol doc-line -> doc Comment? eol comment-line -> Comment? "\n" ``` The following productions are automatically generated to handle zero-or-more, one-or-more, and zero-or-one repeated lists (`foo*`, `foo+`, and `foo?` nonterminals) in LR(1). They are included for completeness, but may be ignored if you just want to understand the grammar. ```shell "$default"? -> | "$default" Comment? -> | Comment abbreviation? -> | abbreviation additive-expression-right* -> | additive-expression-right additive-expression-right* and-expression-right* -> | and-expression-right and-expression-right* and-expression-right+ -> and-expression-right and-expression-right* array-length-specifier* -> | array-length-specifier array-length-specifier* attribute* -> | attribute attribute* attribute-context? -> | attribute-context attribute-line* -> | attribute-line attribute-line* comma-then-expression* -> | comma-then-expression comma-then-expression* comment-line* -> | comment-line comment-line* delimited-argument-list? -> | delimited-argument-list delimited-parameter-definition-list? -> | delimited-parameter-definition-list doc-line* -> | doc-line doc-line* doc? -> | doc enum-value* -> | enum-value enum-value* enum-value+ -> enum-value enum-value* enum-value-body? -> | enum-value-body equality-expression-right* -> | equality-expression-right equality-expression-right* equality-expression-right+ -> equality-expression-right equality-expression-right* equality-or-greater-expression-right* -> | equality-or-greater-expression-right equality-or-greater-expression-right* equality-or-less-expression-right* -> | equality-or-less-expression-right equality-or-less-expression-right* field-body? -> | field-body field-reference-tail* -> | field-reference-tail field-reference-tail* import-line* -> | import-line import-line* or-expression-right* -> | or-expression-right or-expression-right* or-expression-right+ -> or-expression-right or-expression-right* parameter-definition-list-tail* -> | parameter-definition-list-tail parameter-definition-list-tail* times-expression-right* -> | times-expression-right times-expression-right* type-definition* -> | type-definition type-definition* type-size-specifier? -> | type-size-specifier unconditional-anonymous-bits-field* -> | unconditional-anonymous-bits-field unconditional-anonymous-bits-field* unconditional-anonymous-bits-field+ -> unconditional-anonymous-bits-field unconditional-anonymous-bits-field* unconditional-bits-field* -> | unconditional-bits-field unconditional-bits-field* unconditional-bits-field+ -> unconditional-bits-field unconditional-bits-field* unconditional-struct-field* -> | unconditional-struct-field unconditional-struct-field* unconditional-struct-field+ -> unconditional-struct-field unconditional-struct-field* ``` The following regexes are used to tokenize input into the corresponding symbols. Note that the `Indent`, `Dedent`, and `EndOfLine` symbols are generated using separate logic. Pattern | Symbol ------------------------------------------ | ------------------------------ `\[` | `"["` `\]` | `"]"` `\(` | `"("` `\)` | `")"` `\:` | `":"` `\=` | `"="` `\+` | `"+"` `\-` | `"-"` `\*` | `"*"` `\.` | `"."` `\?` | `"?"` `\=\=` | `"=="` `\!\=` | `"!="` `\&\&` | `"&&"` `\|\|` | `"||"` `\<` | `"<"` `\>` | `">"` `\<\=` | `"<="` `\>\=` | `">="` `\,` | `","` `\$static_size_in_bits` | `"$static_size_in_bits"` `\$is_statically_sized` | `"$is_statically_sized"` `\$max` | `"$max"` `\$present` | `"$present"` `\$upper_bound` | `"$upper_bound"` `\$lower_bound` | `"$lower_bound"` `\$next` | `"$next"` `\$size_in_bits` | `"$size_in_bits"` `\$size_in_bytes` | `"$size_in_bytes"` `\$max_size_in_bits` | `"$max_size_in_bits"` `\$max_size_in_bytes` | `"$max_size_in_bytes"` `\$min_size_in_bits` | `"$min_size_in_bits"` `\$min_size_in_bytes` | `"$min_size_in_bytes"` `\$default` | `"$default"` `struct` | `"struct"` `bits` | `"bits"` `enum` | `"enum"` `external` | `"external"` `import` | `"import"` `as` | `"as"` `if` | `"if"` `let` | `"let"` `EmbossReserved[A-Za-z0-9]*` | `BadWord` `emboss_reserved[_a-z0-9]*` | `BadWord` `EMBOSS_RESERVED[_A-Z0-9]*` | `BadWord` `"(?:[^"\n\\]\|\\[n\\"])*"` | `String` `[0-9]+` | `Number` `[0-9]{1,3}(?:_[0-9]{3})*` | `Number` `0x[0-9a-fA-F]+` | `Number` `0x_?[0-9a-fA-F]{1,4}(?:_[0-9a-fA-F]{4})*` | `Number` `0x_?[0-9a-fA-F]{1,8}(?:_[0-9a-fA-F]{8})*` | `Number` `0b[01]+` | `Number` `0b_?[01]{1,4}(?:_[01]{4})*` | `Number` `0b_?[01]{1,8}(?:_[01]{8})*` | `Number` `true\|false` | `BooleanConstant` `[a-z][a-z_0-9]*` | `SnakeWord` `[A-Z][A-Z_0-9]*[A-Z_][A-Z_0-9]*` | `ShoutyWord` `[A-Z][a-zA-Z0-9]*[a-z][a-zA-Z0-9]*` | `CamelWord` `-- .*` | `Documentation` `--$` | `Documentation` `--.*` | `BadDocumentation` `\s+` | *no symbol emitted* `#.*` | `Comment` `[0-9][bxBX]?[0-9a-fA-F_]*` | `BadNumber` `[a-zA-Z_$0-9]+` | `BadWord` The following 534 keywords are reserved, but not used, by Emboss. They may not be used as field, type, or enum value names. `ATOMIC_BOOL_LOCK_FREE` `ATOMIC_CHAR16_T_LOCK_FREE` `ATOMIC_CHAR32_T_LOCK_FREE` `ATOMIC_CHAR_LOCK_FREE` `ATOMIC_FLAG_INIT` `ATOMIC_INT_LOCK_FREE` `ATOMIC_LLONG_LOCK_FREE` `ATOMIC_LONG_LOCK_FREE` `ATOMIC_POINTER_LOCK_FREE` `ATOMIC_SHORT_LOCK_FREE` `ATOMIC_VAR_INIT` `ATOMIC_WCHAR_T_LOCK_FREE` `BUFSIZ` `CGFloat` `CHAR_BIT` `CHAR_MAX` `CHAR_MIN` `CLOCKS_PER_SEC` `CMPLX` `CMPLXF` `CMPLXL` `DBL_DECIMAL_DIG` `DBL_DIG` `DBL_EPSILON` `DBL_HAS_SUBNORM` `DBL_MANT_DIG` `DBL_MAX` `DBL_MAX_10_EXP` `DBL_MAX_EXP` `DBL_MIN` `DBL_MIN_10_EXP` `DBL_MIN_EXP` `DBL_TRUE_MIN` `DECIMAL_DIG` `DOMAIN` `EDOM` `EILSEQ` `EOF` `ERANGE` `EXIT_FAILURE` `EXIT_SUCCESS` `FE_ALL_EXCEPT` `FE_DFL_ENV` `FE_DIVBYZERO` `FE_DOWNWARD` `FE_INEXACT` `FE_INVALID` `FE_OVERFLOW` `FE_TONEAREST` `FE_TOWARDZERO` `FE_UNDERFLOW` `FE_UPWARD` `FILENAME_MAX` `FLT_DECIMAL_DIG` `FLT_DIG` `FLT_EPSILON` `FLT_EVAL_METHOD` `FLT_HAS_SUBNORM` `FLT_MANT_DIG` `FLT_MAX` `FLT_MAX_10_EXP` `FLT_MAX_EXP` `FLT_MIN` `FLT_MIN_10_EXP` `FLT_MIN_EXP` `FLT_RADIX` `FLT_ROUNDS` `FLT_TRUE_MIN` `FOPEN_MAX` `FP_FAST_FMA` `FP_FAST_FMAF` `FP_FAST_FMAL` `FP_ILOGB0` `FP_ILOGBNAN` `FP_INFINITE` `FP_NAN` `FP_NORMAL` `FP_SUBNORMAL` `FP_ZERO` `False` `HUGE_VAL` `HUGE_VALF` `HUGE_VALL` `INFINITY` `INT16_C` `INT16_MAX` `INT16_MIN` `INT32_C` `INT32_MAX` `INT32_MIN` `INT64_C` `INT64_MAX` `INT64_MIN` `INT8_C` `INT8_MAX` `INT8_MIN` `INTMAX_C` `INTMAX_MAX` `INTMAX_MIN` `INTPTR_MAX` `INTPTR_MIN` `INT_FAST16_MAX` `INT_FAST16_MIN` `INT_FAST32_MAX` `INT_FAST32_MIN` `INT_FAST64_MAX` `INT_FAST64_MIN` `INT_FAST8_MAX` `INT_FAST8_MIN` `INT_LEAST16_MAX` `INT_LEAST16_MIN` `INT_LEAST32_MAX` `INT_LEAST32_MIN` `INT_LEAST64_MAX` `INT_LEAST64_MIN` `INT_LEAST8_MAX` `INT_LEAST8_MIN` `INT_MAX` `INT_MIN` `LC_ALL` `LC_COLLATE` `LC_CTYPE` `LC_MONETARY` `LC_NUMERIC` `LC_TIME` `LDBL_DECIMAL_DIG` `LDBL_DIG` `LDBL_EPSILON` `LDBL_HAS_SUBNORM` `LDBL_MANT_DIG` `LDBL_MAX` `LDBL_MAX_10_EXP` `LDBL_MAX_EXP` `LDBL_MIN` `LDBL_MIN_10_EXP` `LDBL_MIN_EXP` `LDBL_TRUE_MIN` `LLONG_MAX` `LLONG_MIN` `LONG_MAX` `LONG_MIN` `MATH_ERREXCEPT` `MATH_ERRNO` `MAXFLOAT` `MB_CUR_MAX` `MB_LEN_MAX` `M_1_PI` `M_2_PI` `M_2_SQRTPI` `M_3PI_4` `M_E` `M_INVLN2` `M_IVLN10` `M_LN10` `M_LN2` `M_LN2HI` `M_LN2LO` `M_LOG10E` `M_LOG2E` `M_LOG2_E` `M_PI` `M_PI_2` `M_PI_4` `M_SQRT1_2` `M_SQRT2` `M_SQRT3` `M_SQRTPI` `M_TWOPI` `NAN` `NDEBUG` `NSInteger` `NSNumber` `NSObject` `NULL` `None` `ONCE_FLAG_INIT` `OVERFLOW` `PLOSS` `PTRDIFF_MAX` `PTRDIFF_MIN` `RAND_MAX` `SCHAR_MAX` `SCHAR_MIN` `SEEK_CUR` `SEEK_END` `SEEK_SET` `SHRT_MAX` `SHRT_MIN` `SIGABRT` `SIGFPE` `SIGILL` `SIGINT` `SIGSEGV` `SIGTERM` `SIG_ATOMIC_MAX` `SIG_ATOMIC_MIN` `SIG_DFL` `SIG_ERR` `SIG_IGN` `SING` `SIZE_MAX` `Self` `TIME_UTC` `TLOSS` `TMP_MAX` `TMP_MAX_S` `TSS_DTOR_ITERATIONS` `True` `UCHAR_MAX` `UINT16_C` `UINT16_MAX` `UINT32_C` `UINT32_MAX` `UINT64_C` `UINT64_MAX` `UINT8_C` `UINT8_MAX` `UINTMAX_C` `UINTMAX_MAX` `UINTPTR_MAX` `UINT_FAST16_MAX` `UINT_FAST32_MAX` `UINT_FAST64_MAX` `UINT_FAST8_MAX` `UINT_LEAST16_MAX` `UINT_LEAST32_MAX` `UINT_LEAST64_MAX` `UINT_LEAST8_MAX` `UINT_MAX` `ULLONG_MAX` `ULONG_MAX` `UNDERFLOW` `USHRT_MAX` `WCHAR_MAX` `WCHAR_MIN` `WEOF` `WINT_MAX` `WINT_MIN` `abstract` `acos` `acosh` `after` `alignas` `alignof` `and` `and_eq` `andalso` `asin` `asinh` `asm` `assert` `atan` `atan2` `atanh` `atomic_compare_exchange_strong` `atomic_compare_exchange_strong_explicit` `atomic_compare_exchange_weak` `atomic_compare_exchange_weak_explicit` `atomic_exchange` `atomic_exchange_explicit` `atomic_fetch_add` `atomic_fetch_add_explicit` `atomic_fetch_and` `atomic_fetch_and_explicit` `atomic_fetch_or` `atomic_fetch_or_explicit` `atomic_fetch_sub` `atomic_fetch_sub_explicit` `atomic_fetch_xor` `atomic_fetch_xor_explicit` `atomic_init` `atomic_is_lock_free` `atomic_load` `atomic_load_explicit` `atomic_store` `atomic_store_explicit` `auto` `band` `become` `begin` `bitand` `bitor` `bnot` `bool` `boolean` `bor` `box` `break` `bsl` `bsr` `bxor` `byte` `carg` `case` `catch` `cbrt` `ceil` `chan` `char` `char16_t` `char32_t` `cimag` `class` `classdef` `compl` `complex` `concept` `cond` `conj` `const` `const_cast` `constexpr` `continue` `copysign` `cos` `cosh` `cproj` `crate` `creal` `decltype` `def` `default` `defer` `del` `delete` `div` `do` `double` `dynamic_cast` `elif` `else` `elseif` `end` `erf` `erfc` `errno` `except` `exec` `exp` `exp2` `explicit` `expm1` `export` `extends` `extern` `fabs` `fallthrough` `fdim` `final` `finally` `float` `floor` `fma` `fmax` `fmin` `fmod` `fn` `for` `fortran` `fpclassify` `frexp` `friend` `from` `fun` `func` `function` `global` `go` `goto` `hypot` `ilogb` `imaginary` `impl` `implementation` `implements` `in` `inline` `instanceof` `int` `interface` `is` `isfinite` `isgreater` `isgreaterequal` `isinf` `isless` `islessequal` `islessgreater` `isnan` `isnormal` `isunordered` `kill_dependency` `lambda` `ldexp` `lgamma` `llrint` `llround` `log` `log10` `log1p` `log2` `logb` `long` `loop` `lrint` `lround` `macro` `map` `match` `math_errhandling` `mod` `move` `mut` `mutable` `namespace` `native` `nearbyint` `new` `nextafter` `nexttoward` `noexcept` `nonatomic` `nonlocal` `noreturn` `not` `not_eq` `null` `nullptr` `of` `offsetof` `operator` `or` `or_eq` `orelse` `otherwise` `override` `package` `parfor` `pass` `persistent` `pow` `print` `priv` `private` `proc` `property` `protected` `protocol` `pub` `public` `pure` `raise` `range` `readonly` `readwrite` `receive` `ref` `register` `reinterpret_cast` `rem` `remainder` `remquo` `requires` `restrict` `retain` `rethrow` `return` `rint` `round` `scalbln` `scalbn` `select` `self` `setjmp` `short` `signbit` `signed` `sin` `sinh` `sizeof` `spmd` `sqrt` `static` `static_assert` `static_cast` `stderr` `stdin` `stdout` `strictfp` `strong` `super` `switch` `synchronized` `tan` `tanh` `template` `tgamma` `this` `thread_local` `throw` `throws` `trait` `transient` `trunc` `try` `type` `typedef` `typeid` `typename` `typeof` `union` `unsafe` `unsafe_unretained` `unsigned` `unsized` `use` `using` `va_arg` `va_copy` `va_end` `va_start` `var` `virtual` `void` `volatile` `wchar_t` `weak`