librdesc
Loading...
Searching...
No Matches
Macros
rule_macros.h File Reference

DSL macros for defining grammar production rules. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PREFIX_TK(tk)   TK_ ## tk
 See Name Mapping for Identifiers

 
#define PREFIX_NT(nt)   NT_ ## nt
 See Name Mapping for Identifiers

 
#define POSTFIX_NT_REST(nt)   nt ## _REST
 See Name Mapping for Identifiers

 
#define EOA   -1
 Sentinel for end of alternative.
 
#define EOP   -2
 Sentinel for end of production body.
 
#define TK(tk)   { .ty = RDESC_TOKEN, .id = PREFIX_TK(tk) }
 Macro to create a terminal (token) production symbol.
 
#define NT(nt)   { .ty = RDESC_NONTERMINAL, .id = PREFIX_NT(nt) }
 Macro to create a nonterminal production symbol.
 
#define EPSILON   SEOA
 Epsilon production (empty/null production). Use to represent an empty alternative that matches nothing. This is equivalent to ε in BNF notation.
 
#define r(...)   { { __VA_ARGS__, SEOA }, SEOP }
 Macro to define a grammar rule. Adds end of alternative and end of production body sentinels to grammar rules.
 
#define ropt(...)    r(__VA_ARGS__ alt EPSILON)
 Macro to define an optional grammar rule (epsilon production).
 
#define rrr(head, base, suffix)
 Defines right-recursive list rules. base and suffix parameters should wrapped with parenthesis (()).
 
#define alt   , SEOA, }, {
 Separates grammar alternatives (alternative separator).
 

Detailed Description

DSL macros for defining grammar production rules.

Provides macros to define production rules in a more readable way.

Name Mapping for Identifiers

POSTFIX_NT_REST, PREFIX_TK, and PREFIX_NT macros determine how a raw token name passed to TK(X)/NT(X) is expanded into a C identifier (typically an enum member).

Macro Definition Documentation

◆ alt

#define alt   , SEOA, }, {

Separates grammar alternatives (alternative separator).

Expands to end-of-body sentinel and new alternative initialization.

Use between alternatives. For example, r(α alt β alt γ) is equivalent to α / β / γ, where / is ordered choice operator.

◆ ropt

#define ropt (   ...)     r(__VA_ARGS__ alt EPSILON)

Macro to define an optional grammar rule (epsilon production).

This is a shortcut for a rule with two alternative: an alternative with the symbols provided and an empty (epsilon) one.

ropt(A, α) is equivalent to:

A → α / ε

For example, ropt(STMT, STMTS) defines:

<stmts> ::= <stmt> <stmts>
/ E

◆ rrr

#define rrr (   head,
  base,
  suffix 
)
Value:
r(_rdesc_priv_trim_paren base, NT(POSTFIX_NT_REST(head))), \
ropt(_rdesc_priv_trim_paren suffix, NT(POSTFIX_NT_REST(head)))
#define NT(nt)
Macro to create a nonterminal production symbol.
Definition rule_macros.h:58
#define r(...)
Macro to define a grammar rule. Adds end of alternative and end of production body sentinels to gramm...
Definition rule_macros.h:72
#define POSTFIX_NT_REST(nt)
See Name Mapping for Identifiers
Definition rule_macros.h:40

Defines right-recursive list rules. base and suffix parameters should wrapped with parenthesis (()).

Defines two nonterminals: the list head and its rest continuation. rrr(A, (β), (α)) is equivalent to:

A → β A'
A' → α A' / ε

For example, rrr(EXPR_LS, (NT(EXPR)), (TK(COMMA), NT(EXPR))) defines:

1. <expr_ls> ::= <expr> <expr_ls_rest>
2. <expr_ls_rest> ::= "," <expr> <expr_ls_rest>
/ E
Warning
rrr(X, ...) expands into two production rules defining nonterminals NT_X and NT_X_REST. You must explicitly define NT_X_REST right after NT_X in your nonterminal enum definition. See Name Mapping for Identifiers.
Parameters
headThe base nonterminal.
baseThe initial production sequence (beta).
suffixThe repeating production sequence (alpha).