coco.use
来自「一个Pascal语言分析器」· USE 代码 · 共 453 行 · 第 1/2 页
USE
453 行
Grammar checks
==============
Coco/R performs several tests to check if the grammar is well-formed. If one
of the following error messages is produced, no compiler parts are generated.
NO PRODUCTION FOR X
The nonterminal X has been used, but there is no production for it.
X CANNOT BE REACHED
There is a production for nonterminal X, but X cannot be derived from the
start symbol.
X CANNOT BE DERIVED TO TERMINALS
For example, if there is a production X = "(" X ")" .
X - Y, Y - X
X and Y are nonterminals with circular derivations.
TOKENS X AND Y CANNOT BE DISTINGUISHED
The terminal symbols X and Y are declared to have the same structure,
e.g.
integer = digit { digit } .
real = digit { digit } ["." { digit } ].
In this example, a digit string appears ambiguously to be recognized as
an integer or as a real.
The following messages are warnings. They may indicate an error but they may
also describe desired effects. The generated compiler parts may still be
valid. If an LL(1) error is reported for a construct X, one must be aware
that the generated parser will choose the first of several possible
alternatives for X.
X DELETABLE
X can be derived to the empty string, e.g. X = { Y } .
LL(1) ERROR IN X:Y IS START OF MORE THAN ONE ALTERNATIVE
Several alternatives in the production of X start with the terminal Y
e.g.
Statement = ident ":=" Expression | ident [ ActualParameters ] .
LL(1) ERROR IN X:Y IS START AND SUCCESSOR OF DELETABLE STRUCTURE
Deletable structures are [ ... ] and { ... }
e.g.
qualident = [ ident "." ] ident .
Statement = "IF" Expression "THEN" Statement [ "ELSE" Statement ] .
The ELSE at the start of the else part may also be a successor of a
statement. This LL(1) conflict is known under the name "dangling else".
The Parser Interface
====================
A parser generated by Coco/R for Pascal has the following simple interface:
UNIT grammarP;
(* Parser generated by Coco/R - Pascal version *)
INTERFACE
PROCEDURE Parse;
(* Parse the source *)
FUNCTION Successful : BOOLEAN;
(* Returns TRUE if no errors have been recorded while parsing *)
PROCEDURE SynError (errNo: INTEGER);
(* Report syntax error with specified errNo *)
PROCEDURE SemError (errNo: INTEGER);
(* Report semantic error with specified errNo *)
PROCEDURE LexString (VAR Lex : STRING);
(* Retrieves Lex as exact spelling of current token *)
PROCEDURE LexName (VAR Lex : STRING);
(* Retrieves Lex as name of current token (capitalized if IGNORE CASE) *)
PROCEDURE LookAheadString (VAR Lex : STRING);
(* Retrieves Lex as exact spelling of lookahead token *)
PROCEDURE LookAheadName (VAR Lex : STRING);
(* Retrieves Lex as name of lookahead token (capitalized if IGNORE CASE) *)
The functionality provides for the parser to
- initiate the parse for the goal symbol by calling Parse.
- investigate whether the parse succeeded by calling Successful.
- report on the presence of syntactic and semantic errors by calling SynError
and SemError.
- obtain the lexeme value of a particular token in one of four ways
(LexString, LexName, LookAheadString and LookAheadName). Calls to
LexString are most common; the others are used for special variations.
A tailored frame file can be supplied, from which Coco/R can generate a main
program if the $C pragma/option is used. Examples of this can be found in the
kit as well.
The Scanner Interface
=====================
The scanner generated by Coco/R has the following interface:
UNIT grammarS;
(* Scanner generated by Coco/R (Pascal version) *)
INTERFACE
VAR
src: FILE; (* source/list files *)
lst: TEXT; (* to be opened by the main program *)
directory: STRING; (* of source file *)
line, col: INTEGER; (* line and column of current symbol *)
len: INTEGER; (* length of current symbol *)
pos: LONGINT; (* file position of current symbol *)
nextLine: INTEGER; (* line of lookahead symbol *)
nextCol: INTEGER; (* column of lookahead symbol *)
nextLen: INTEGER; (* length of lookahead symbol *)
nextPos: LONGINT; (* file position of lookahead symbol *)
errors: INTEGER; (* number of detected errors *)
Error: PROCEDURE (nr, line, col: INTEGER; pos: LONGINT);
PROCEDURE Get (VAR sym: INTEGER);
(* Gets next symbol from source file *)
PROCEDURE GetString (pos: LONGINT; len: INTEGER; VAR s: STRING);
(* Retrieves exact string of max length len from position pos in source
file *)
PROCEDURE GetName (pos: LONGINT; len: INTEGER; VAR s: STRING);
(* Retrieves name of symbol of max length len from position pos in source
file. Capitalized if IGNORE CASE was specified *)
FUNCTION CharAt (pos: LONGINT): CHAR;
(* Returns exact character at position pos in source file *)
PROCEDURE _Reset;
(* Reads and stores source file internally *)
Notes
-----
It is rarely necessary to make use of any of this interface directly. The
parser interface discussed above exports most of the functionality that is
required when actions are required to retrieve token information.
The variables src, lst and directory are exported from this module simply for
convenience. src is assumed to be opened before parsing begins.
The variables line, col, pos, len are apposite for the most recently parsed
token.
The variables nextLine, nextCol, nextPos, nextLen are apposite for the most
recently scanned token (the look-ahead token retrieved by the most recent call
to Get).
PROCEDURE _Reset is called by the parser to initialize the scanner. Note that
the main module is responsible for opening the source file src prior to
calling the parser. _Reset reads the entire source into a large internal
buffer, thus improving the efficiency of the scanner very markedly.
PROCEDURE Get is called repeatedly from the parser, to get the next token from
the source text.
PROCEDURE CharAt can be used to retrieve a single character from the source
text at a known position.
PROCEDURE GetName can be used to obtain the text of the token at position pos
with length len. PROCEDURE GetString does the same thing, but returns the
exact string as found in the source. (GetName returns the string converted to
uppercase if the scanner was generated so as to IGNORE CASE).
Procedure variable Error is called by the parser for every syntax error
detected, with an appropriate error number and an error position as
parameters. The user can install any procedure that prints a message, or that
saves the error information for later output, subject to the restraint that
after parsing is completed, variable grammarS.errors should contain a
count of the total number of errors detected.
Procedure variable Error can also be used to report semantic errors. If you
use it for this purpose, make sure that you use semantic error numbers that do
not clash with automatically generated syntax error numbers (i.e. start
semantic error numbers at a high number like 200.)
The error numbers together with an explanatory text are written to a file
grammar.ERR by Coco/R in the following form:
0: Msg("EOF expected")
| 1: Msg("ident expected")
| 2: Msg("string expected")
| 3: Msg("number expected")
...
This text can then be merged into a CASE statement within a procedure that
prints textual error messages. This is done automatically if the $C pragma
(/C command line option) is used.
Bootstrapping Coco
==================
The parser and scanner used by Coco/R were themselves generated by a bootstrap
process; if Coco/R is given the grammar CR.atg as input, it will reproduce the
files CRS.PAS and CRP.PAS and MOD. It can also regenerate its own
main program from the file SOURCES\CR.FRM and CR.ATG if the $C pragma is used.
This means that Coco/R can be extended and corrected by changing its grammar
and recompiling itself. If you feel tempted to do this, please make sure that
you have kept copies of the original system in case you destroy or corrupt the
scanner and parser!
The FileIO module is not required for Pascal scanners and parsers. It will
only be needed if you wish to modify or bootstrap Coco/R itself.
Trademarks
==========
All trademarks are acknowledged.
=END=
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?