1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
25 #ifndef LL1_parser_driver_h
26 #define LL1_parser_driver_h
28 #include <AD/automata/ll1.h>
31 // The following template is used to instantiate a new version
35 template< class InputStream
, // Class for retrieving a character
36 class SemanticType
, // The contents of the semantics stack
37 int stackSize
, // The size of the semantics stack
38 class ActionFunction
, // Action function class
39 class ErrorHandler
// Error handler class
42 ( LL1
& parser
, InputStream
& stream
, SemanticType stack
[],
43 ActionFunction
& action
, ErrorHandler
& errorHandler
46 Grammar::Symbol symbol
;
49 ParseStack parseStack
[stackSize
];
50 register ParseStack
* SP
= parseStack
;
51 SemanticType
* top
, * current
, * lhs
, * rhs
;
52 register Grammar::Symbol lookahead
;
54 lhs
= rhs
= stack
; top
= lhs
+ 1;
55 lookahead
= stream
.get();
56 for ( (SP
++)->symbol
= parser
.grammar
.start(); SP
> parseStack
; ) {
57 Grammar::Symbol symbol
= (--SP
)->symbol
;
58 if (symbol
== Grammar::END_PRODUCTION
) {
61 current
= SP
[-3].entry
;
64 } else if (parser
.grammar
.isTerminal(symbol
)) {
65 if (symbol
== lookahead
) {
66 lookahead
= stream
.get();
68 errorHandler(lookahead
);
70 } else if (parser
.grammar
.isAction(symbol
)) {
73 register Grammar::Production production
=
74 parser
.grammar
.productions
+
75 parser
.next
[parser
.base
[symbol
] + lookahead
];
76 if (production
[0] == symbol
) {
78 sp
[1].entry
= current
;
81 sp
[4].symbol
= Grammar::END_PRODUCTION
;
83 lhs
= current
; current
= rhs
= top
;
84 for (register Grammar::Production P
=
85 production
+ production
[-1]; production
< P
; )
86 if (! parser
.grammar
.isAction((sp
++)->symbol
= *P
--))
89 errorHandler(lookahead
);