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 <empty> 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.
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 -> <empty> | 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 -> <empty> | 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" | "$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 doc? Comment? eol enum-value-body? enum-value-body -> Indent doc-line* Dedent doc -> Documentation 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 -> <empty> | 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? attribute -> "[" attribute-context? "$default"? snake-word ":" attribute-value "]" attribute-value -> expression | string-constant string-constant -> String attribute-context -> "(" snake-word ")" 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 -> <empty> | 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 -> <empty> | 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.
"$default"? -> <empty> | "$default" Comment? -> <empty> | Comment abbreviation? -> <empty> | abbreviation additive-expression-right* -> <empty> | additive-expression-right additive-expression-right* and-expression-right* -> <empty> | and-expression-right and-expression-right* and-expression-right+ -> and-expression-right and-expression-right* array-length-specifier* -> <empty> | array-length-specifier array-length-specifier* attribute* -> <empty> | attribute attribute* attribute-context? -> <empty> | attribute-context attribute-line* -> <empty> | attribute-line attribute-line* comma-then-expression* -> <empty> | comma-then-expression comma-then-expression* comment-line* -> <empty> | comment-line comment-line* delimited-argument-list? -> <empty> | delimited-argument-list delimited-parameter-definition-list? -> <empty> | delimited-parameter-definition-list doc-line* -> <empty> | doc-line doc-line* doc? -> <empty> | doc enum-value* -> <empty> | enum-value enum-value* enum-value+ -> enum-value enum-value* enum-value-body? -> <empty> | enum-value-body equality-expression-right* -> <empty> | equality-expression-right equality-expression-right* equality-expression-right+ -> equality-expression-right equality-expression-right* equality-or-greater-expression-right* -> <empty> | equality-or-greater-expression-right equality-or-greater-expression-right* equality-or-less-expression-right* -> <empty> | equality-or-less-expression-right equality-or-less-expression-right* field-body? -> <empty> | field-body field-reference-tail* -> <empty> | field-reference-tail field-reference-tail* import-line* -> <empty> | import-line import-line* or-expression-right* -> <empty> | or-expression-right or-expression-right* or-expression-right+ -> or-expression-right or-expression-right* parameter-definition-list-tail* -> <empty> | parameter-definition-list-tail parameter-definition-list-tail* times-expression-right* -> <empty> | times-expression-right times-expression-right* type-definition* -> <empty> | type-definition type-definition* type-size-specifier? -> <empty> | type-size-specifier unconditional-anonymous-bits-field* -> <empty> | unconditional-anonymous-bits-field unconditional-anonymous-bits-field* unconditional-anonymous-bits-field+ -> unconditional-anonymous-bits-field unconditional-anonymous-bits-field* unconditional-bits-field* -> <empty> | unconditional-bits-field unconditional-bits-field* unconditional-bits-field+ -> unconditional-bits-field unconditional-bits-field* unconditional-struct-field* -> <empty> | 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" |
\$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