.PP
We can describe the syntax of an ECF syntax with an ECF syntax :
.DS
-.ft 5
+.ft CW
grammar : rule +
;
.ft R
This grammar rule states that a grammar consists of one or more
rules.
.DS
-.ft 5
+.ft CW
rule : nonterminal ':' productionrule ';'
;
.ft R
the \fBproduce symbol\fR, followed by a production rule, followed by a
";", in\%di\%ca\%ting the end of the rule.
.DS
-.ft 5
+.ft CW
productionrule : production [ '|' production ]*
;
.ft R
more alternative productions separated by "|". This symbol is called the
\fBalternation symbol\fR.
.DS
-.ft 5
+.ft CW
production : term *
;
.ft R
A production consists of a possibly empty list of terms.
So, empty productions are allowed.
.DS
-.ft 5
+.ft CW
term : element repeats
;
.ft R
.DE
A term is an element, possibly with a repeat specification.
.DS
-.ft 5
+.ft CW
element : LITERAL
| IDENTIFIER
| '[' productionrule ']'
nonterminal or a token, and it can be a production rule
between square parentheses.
.DS
-.ft 5
+.ft CW
repeats : '?'
| [ '*' | '+' ] NUMBER ?
| NUMBER ?
This can be done using the "\fB%token\fR" keyword,
by writing
.nf
-.ft 5
+.ft CW
.sp 1
%token name1, name2, . . . ;
.ft R
"\fB%start\fR" keyword. It can be used whenever a declaration is
legal, f.i.:
.nf
-.ft 5
+.ft CW
.sp 1
%start LLparse, specification ;
.ft R
\fILLparse\fR,
the parsing routines can be given C-like parameters. So, for example
.nf
-.ft 5
+.ft CW
.sp 1
expr(int *pval;) { int fact; } :
/*
"?" the default choice is to continue with the rest of the rule
in which the term appears, and
.sp 1
-.ft 5
+.ft CW
.nf
term+
.fi
is treated as
.sp 1
.nf
-.ft 5
+.ft CW
term term* .
.ft R
.fi
using the keyword "\fB%persistent\fR".
For instance, the rule
.sp 1
-.ft 5
+.ft CW
.nf
commandlist : command* ;
.fi
.sp 1
could be changed to
.sp 1
-.ft 5
+.ft CW
.nf
commandlist : [ %persistent command ]* ;
.fi
nonterminal, f.i.:
.sp 1
.nf
-.ft 5
+.ft CW
%first fmac, nonterm ;
.ft R
.sp 1
only once in the grammar specification, f.i.:
.sp 1
.nf
-.ft 5
+.ft CW
%lexical scanner ;
.ft R
.fi
as a \fILLgen\fR specification. As a matter of fact, the current
version of \fILLgen\fR is written with \fILLgen\fR.
.nf
-.ft 5
+.ft CW
.sp 2
/*
* First the declarations of the terminals
nonterminal, no matter how many priority levels there are.
.sp 1
.nf
-.ft 5
+.ft CW
{
#include <stdio.h>
#include <ctype.h>
As usual, there is a way around this problem.
A sample makefile follows:
.sp 1
-.ft 5
+.ft CW
.nf
# The grammar exists of the files decl.g, stat.g and expr.g.
# The ".o"-files are the result of a C-compilation.