The revised syntax is an alternative syntax for OCaml. Its
purpose is to b/DTD HTMA>
Entries are stream parsers improved. Streams use recursive descendant
parsing (something close to LL(1)). Each precedence level can be seen
as an independent extensible stream parser.
In a precedence level, the rules are factorized, i.e. several rules
can start with the same symbols, and the parser is represented by a
tree of symbols where leaves are either semantic actions, or dead
ends.
When an extension is done, the new rules are inserted in the
precedence level tree. The system does not check whether the entry
precedence level will ``work'', nor whether it would work together
with the other levels and the other entries.
This insertion is generally done at the end of the rules list. The
special cases are for symbols of type token, which are always inserted
before the other symbols (non terminals, lists, options, etc),
tokens with parameters before tokens without parameters (parameter is
the empty string).
There is no factorization of rules between different levels nor, a fortiori,
with other entries.
While parsing an entry, the system tries the first precedence
level. Then, if it fails, it tries the second one, etc. If the last
one fails, the entry fails and the caller of this entry resumes,
either by raising a parse error (the parsing is then stopped), or
by trying other rules.
Entries rules can be deleted using the function
``Grammar.delete_rule''. But, like for
``Grammar.extend'', it is not documented. One must use the
instruction ``DELETE_RULE'', generating a call to this
function. This instruction is a syntax extension, loaded together with
the instruction ``EXTEND'' by the file
``pa_extend.cmo''.
The syntax of ``DELETE_RULE'' is:
DELETE_RULE |
| entry : symbol ; ... symbol |
END |
The rule defined by the list of symbols (semantic actions forgotten),
if found, is deleted.
The lexers have to create tokens of any type you want. In the lexer
interface (see below), you have to provide the way a token pattern
(which is of type (string * string)) has to be compared with
a token value of your token type.
A simple token type is (string * string) like the token pattern
type. Its advantage is that a default function is provided in the
module Token for the way the token patterns are parsed.
The token patterns are defined in the EXTEND statement, as
terminal symbols in the rules. In a rule, an identifier in uppercase
character not among the reserved ones (LIST0, OPT, and so on) is
a token pattern. The identifier is the first string in the token
pattern type. If the symbol is followed by a string, it is the second
string of the token pattern type; if not, the string is
empty. Moreover a string alone is also a token pattern with the first
string being empty.
Examples: the following symbol rules in an EXTEND statement:
IDENT "bar"
INT "32"
x = IDENT
i = INT
"let"
correspond (resp.) to the following token patterns:
("IDENT", "bar")
("INT", "32")
("IDENT", "")
("INT", "")
("", "let")
A lexer appropriate for the Grammar.gcreate function is a record
of type Token.glexer which is a record with the following fields:
tok_func: it is the main lexing function. It is called once
when calling Grammar.Entry.parse with the input character
stream. The simplest way to create this function is to use either the
function Token.lexer_func_of_parser if you use a stream parser,
or Token.lexer_func_of_ocamllex if you prefer use an ocamllex
function. Notice that in both cases, your lexer function must return
a couple of a token value (of your token type) and a token location
(a couple of integers).
tok_using: it is a function taking a token pattern as
parameter. When EXTEND statement first scans all symbols in all
rules, it calls this function with the token patterns encountered (a
token pattern is of type (string * string)). This function
allows you to check the pattern (that the constructor is among the
ones the lexer generates: raise an exception if not) and enter
keywords (if you have keywords) in your keyword table (if you use a
keyword table).
tok_removing: like tok_using but used when a rule is
removed.
tok_match: tells how a token pattern is parsed. It must
return a function taking a token as parameter, returning either the
resulting string or the exception Stream.Failure. Use the
function Token.default_match for a default behavior when your
token type is (string * string). Remark: for efficiency, if you
write your own version, write is as a function taking a token pattern
and returning a function for each case, *not* as a function with two
parameters.
tok_text: give the name of a token pattern to be used in
error messages. You can use the function named lexer_text
provided in the module Token.
For remarks about Camlp4, write to: