program: { K_PROGRAM } (declaration)* (function)+;
This says that a program optionally starts with the token K_PROGRAM, followed
by zero or more declarations, followed by one or more functions.
When translating a syntax diagram to a grammar rule, we write name of the
non-terminal at the start of the diagram as the rule's label.
Each rectangle is replaced by a non-terminal whose name matches the name inside
the rectangle (except that the grammar non-terminal must start with a lowercase
letter).
Each rounded-off rectangle is replaced with a terminal whose name matches the
name inside the rounded-off rectangle (except that the grammar terminal must
start with an uppercase letter). After doing this to the above rule, we have:
/-----------\ --------------- ------------ program --> --{ | K_PROGRAM | }-- | declaration | * --- | function | + ---> \-----------/ --------------- ------------This isn't done yet, because we need to do something about the '{', '}', '*' and '+'. We'll talk about these next. Whenever we see a subrule with an alternative path around it as follows:
------------------------ | | | ----------- \|/ ---> -----------| subrule |---------------> -----------we enclose the grammar subrule in a brace pair '{' and '}':
{ subrule }
Following the arrows, we see that we can either skip the subrule altogether, or
go through it exactly one time before leaving. Thus, a brace pair enclosing a
subrule indicates that we execute the subrule zero or one times.
Whenever we see a subrule with an alternative path which loops from its exit
to its entrance as follows:
----------- ---> ------------| subrule |---------------> /|\ ----------- | | | -------------------------we enclose the grammar subrule in a parenthesis pair '(' and ')', and follow this pair with a plus sign '+':
( subrule )+
Following the arrows, we see that we have to go through the subrule at least
once, but can then leave or loop back to go through it again. Thus, a plus
sign following a parenthesis-enclosed subrule indicates that we execute the
subrule one or more times.
Whenever we see a subrule with an alternative path which loops from its exit to its entrance, and an alternative path around this entire construct as follows:
----------------------------------- | | | ----------- \|/ ---> ------------| subrule |---------------> /|\ ----------- | | | -------------------------we enclose the grammar subrule in a parenthesis pair '(' and ')', and follow this pair with a multiplication sign '*':
( subrule )*
Following the arrows, we see that we have can completely skip over the
subrule and leave, otherwise, we have to go through the subrule at least
once, after which, we can then leave or loop back to go through it again.
Thus, a multiplication sign following a parenthesis-enclosed subrule indicates
that we execute the subrule zero or more times. Examining these diagrams
makes it clear that "(subrule)*" is equivalent to "{(subrule)+}".
Now we need to go back and use these constructs to build a syntax diagram for
the above rule. Let's look at the rule again:
To make a diagram for "program", we need to combine a diagram for zero or one
K_PROGRAMs followed by a diagram for zero or more declarations, followed by
one or more functions. Because these parts are sequential parts of the rule
(i.e. not alternatives), we just connect their diagrams serially:
program: { K_PROGRAM } (declaration)* (function)+;
------------------------- | | | ------------- \|/ program ---> ------------| K_PROGRAM |--------------->---- ------------- | | ------<----------------------------------------------<---- | | ----------------------------------- | | | | | --------------- \|/ -----------> ----------| declaration |------------->------ /|\ --------------- | | | | | ------------------------- | | ------<----------------------------------------------<---- | | ------------ -----------> -----------| function |--------------->--------------> /|\ ------------ | | | -------------------------
Alternates for the same rule are written in the grammar as "alt1 | alt2". To convert this a syntax diagram, we first draw the diagrams for the alternates, then connect them in parallel:
-------- ------| alt1 |------ | -------- | | \|/ rule ---> --| X--------> | /|\ | -------- | ------| alt2 |------ --------Following the arrows, we see that we have can choose to go through alt1 once and leave or go through alt2 once and leave. Thus, we execute one alternative of the other: not both.