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" | "$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 -> <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? 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" |
\$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