1
// This file is part of PUMA.
2
// Copyright (C) 1999-2003 The PUMA developer team.
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
#include "Puma/Syntax.h"
20
#include "Puma/CTree.h"
21
#include "Puma/CTokens.h"
22
#include "Puma/Semantic.h"
27
CTree *Syntax::run (TokenProvider &tp) {
30
_problem_token = (Token*)0;
32
return parse (&Syntax::trans_unit) ? builder ().Top () : (CTree*)0;
36
Token *Syntax::locate_token () {
38
while ((token = token_provider->current ()) && ! token->is_core ()) {
39
if (token->is_directive ())
42
token_provider->next ();
47
bool Syntax::look_ahead (int token_type, unsigned n) {
54
token = token_provider->current ();
55
result = (token && token->type () == token_type);
57
state = token_provider->get_state ();
59
token_provider->next ();
60
token = token_provider->current ();
61
result = (token && token->type () == token_type);
62
token_provider->set_state (state);
67
bool Syntax::look_ahead (int *token_types, unsigned n) {
74
token = token_provider->current ();
76
while (*token_types) {
77
if (*token_types == token->type ()) {
85
state = token_provider->get_state ();
87
token_provider->next ();
88
token = token_provider->current ();
90
while (*token_types) {
91
if (*token_types == token->type ()) {
98
token_provider->set_state (state);
103
Syntax::State Syntax::save_state () {
104
builder ().save_state ();
105
semantic ().save_state ();
106
return token_provider->get_state ();
109
void Syntax::forget_state () {
110
builder ().forget_state ();
111
semantic ().forget_state ();
114
void Syntax::restore_state () {
116
for (long i = builder ().Length () - 1; i >= 0; i--)
117
semantic ().undo (builder ().Get (i));
119
builder ().restore_state ();
120
semantic ().restore_state ();
123
void Syntax::restore_state (State state) {
124
token_provider->set_state (state);
126
for (long i = builder ().Length () - 1; i >= 0; i--)
127
semantic ().undo (builder ().Get (i));
129
builder ().restore_state ();
130
semantic ().restore_state ();
133
void Syntax::set_state (State state) {
134
token_provider->set_state (state);
137
bool Syntax::accept (CTree *result, State s) {
140
builder ().Push (result);
149
bool Syntax::parse_token (int token_type) {
150
Token *t = token_provider->current ();
154
cout<<t->location()<<": `"<<t->text()<<"'"<<endl;
157
if (t && t->type () == token_type) {
158
_problem_token = (Token*)0;
159
token_provider->next ();
161
builder ().Push (builder ().token (t));
164
if (! _problem_token)
165
_problem_token = token_provider->current ();
171
bool Syntax::parse (int *token) {
181
void Syntax::skip_block (int open, int close) {
185
while ((current = token_provider->current ())) {
186
token = current->type ();
187
token_provider->next ();
191
else if (token == close)
198
void Syntax::skip_round_block () {
199
skip_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND);
202
void Syntax::skip_curly_block () {
203
skip_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY);
206
void Syntax::parse_block (int open, int close) {
209
while ((token = look_ahead ())) {
213
else if (token == close)
220
void Syntax::parse_round_block () {
221
parse_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND);
224
void Syntax::parse_curly_block () {
225
parse_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY);
228
bool Syntax::skip (int *stop_tokens, bool inclusive) {
232
while ((current = token_provider->current ())) {
233
token = current->type ();
235
if (is_in (token, stop_tokens))
238
if (token == TOK_OPEN_CURLY)
240
else if (token == TOK_OPEN_ROUND)
243
token_provider->next ();
248
if (current && inclusive && current->type () != TOK_CLOSE_CURLY) {
249
token_provider->next ();
256
bool Syntax::skip (int stop_token, bool inclusive) {
260
while ((current = token_provider->current ())) {
261
token = current->type ();
263
if (token == stop_token)
266
if (token == TOK_OPEN_CURLY)
268
else if (token == TOK_OPEN_ROUND)
271
token_provider->next ();
276
if (current && inclusive && current->type () != TOK_CLOSE_CURLY) {
277
token_provider->next ();
284
void Syntax::skip () {
285
token_provider->next ();
289
bool Syntax::is_in (int token, int *set) const {
291
while (set[i] && set[i] != token)
293
return (set[i] != 0);