2
* STANDARD ML OF NEW JERSEY COPYRIGHT NOTICE, LICENSE AND DISCLAIMER.
4
* Copyright (c) 1989-1998 by Lucent Technologies
6
* Permission to use, copy, modify, and distribute this software and its
7
* documentation for any purpose and without fee is hereby granted, provided
8
* that the above copyright notice appear in all copies and that both the
9
* copyright notice and this permission notice and warranty disclaimer appear
10
* in supporting documentation, and that the name of Lucent Technologies, Bell
11
* Labs or any Lucent entity not be used in advertising or publicity pertaining
12
* to distribution of the software without specific, written prior permission.
14
* Lucent disclaims all warranties with regard to this software, including all
15
* implied warranties of merchantability and fitness. In no event shall Lucent
16
* be liable for any special, indirect or consequential damages or any damages
17
* whatsoever resulting from loss of use, data or profits, whether in an action
18
* of contract, negligence or other tortious action, arising out of or in
19
* connection with the use or performance of this software.
21
* Taken from this URL:
22
* http://www.smlnj.org/license.html
24
* This license is compatible with the GNU GPL (see section "Standard ML of New
25
* Jersey Copyright License"):
26
* http://www.gnu.org/licenses/license-list.html#StandardMLofNJ
30
* Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian
33
package weka.core.parser.java_cup;
35
import java.util.Hashtable;
36
import java.util.Enumeration;
38
/** This class represents a non-terminal symbol in the grammar. Each
39
* non terminal has a textual name, an index, and a string which indicates
40
* the type of object it will be implemented with at runtime (i.e. the class
41
* of object that will be pushed on the parse stack to represent it).
43
* @version last updated: 11/25/95
44
* @author Scott Hudson
47
public class non_terminal extends symbol {
49
/*-----------------------------------------------------------*/
50
/*--- Constructor(s) ----------------------------------------*/
51
/*-----------------------------------------------------------*/
54
* @param nm the name of the non terminal.
55
* @param tp the type string for the non terminal.
57
public non_terminal(String nm, String tp)
59
/* super class does most of the work */
62
/* add to set of all non terminals and check for duplicates */
63
Object conflict = _all.put(nm,this);
65
// can't throw an exception here because these are used in static
66
// initializers, so we crash instead
68
// throw new internal_error("Duplicate non-terminal ("+nm+") created");
69
(new internal_error("Duplicate non-terminal ("+nm+") created")).crash();
71
/* assign a unique index */
72
_index = next_index++;
74
/* add to by_index set */
75
_all_by_index.put(new Integer(_index), this);
78
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
80
/** Constructor with default type.
81
* @param nm the name of the non terminal.
83
public non_terminal(String nm)
88
/*-----------------------------------------------------------*/
89
/*--- (Access to) Static (Class) Variables ------------------*/
90
/*-----------------------------------------------------------*/
92
/** Table of all non-terminals -- elements are stored using name strings
95
protected static Hashtable _all = new Hashtable();
97
//Hm Added clear to clear all static fields
98
public static void clear() {
100
_all_by_index.clear();
105
/** Access to all non-terminals. */
106
public static Enumeration all() {return _all.elements();}
108
/** lookup a non terminal by name string */
109
public static non_terminal find(String with_name)
111
if (with_name == null)
114
return (non_terminal)_all.get(with_name);
117
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
119
/** Table of all non terminals indexed by their index number. */
120
protected static Hashtable _all_by_index = new Hashtable();
122
/** Lookup a non terminal by index. */
123
public static non_terminal find(int indx)
125
Integer the_indx = new Integer(indx);
127
return (non_terminal)_all_by_index.get(the_indx);
130
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
132
/** Total number of non-terminals. */
133
public static int number() {return _all.size();}
135
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
137
/** Static counter to assign unique indexes. */
138
protected static int next_index = 0;
140
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
142
/** Static counter for creating unique non-terminal names */
143
static protected int next_nt = 0;
145
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
147
/** special non-terminal for start symbol */
148
public static final non_terminal START_nt = new non_terminal("$START");
150
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
152
/** flag non-terminals created to embed action productions */
153
public boolean is_embedded_action = false; /* added 24-Mar-1998, CSA */
155
/*-----------------------------------------------------------*/
156
/*--- Static Methods ----------------------------------------*/
157
/*-----------------------------------------------------------*/
159
/** Method for creating a new uniquely named hidden non-terminal using
160
* the given string as a base for the name (or "NT$" if null is passed).
161
* @param prefix base name to construct unique name from.
163
static non_terminal create_new(String prefix) throws internal_error
165
return create_new(prefix,null); // TUM 20060608 embedded actions patch
168
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
170
/** static routine for creating a new uniquely named hidden non-terminal */
171
static non_terminal create_new() throws internal_error
173
return create_new(null);
176
* TUM 20060608 bugfix for embedded action codes
178
static non_terminal create_new(String prefix, String type) throws internal_error{
179
if (prefix==null) prefix = "NT$";
180
return new non_terminal(prefix + next_nt++,type);
182
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
184
/** Compute nullability of all non-terminals. */
185
public static void compute_nullability() throws internal_error
187
boolean change = true;
192
/* repeat this process until there is no change */
195
/* look for a new change */
198
/* consider each non-terminal */
199
for (e=all(); e.hasMoreElements(); )
201
nt = (non_terminal)e.nextElement();
203
/* only look at things that aren't already marked nullable */
206
if (nt.looks_nullable())
215
/* do one last pass over the productions to finalize all of them */
216
for (e=production.all(); e.hasMoreElements(); )
218
prod = (production)e.nextElement();
219
prod.set_nullable(prod.check_nullable());
223
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
225
/** Compute first sets for all non-terminals. This assumes nullability has
228
public static void compute_first_sets() throws internal_error
230
boolean change = true;
235
terminal_set prod_first;
237
/* repeat this process until we have no change */
240
/* look for a new change */
243
/* consider each non-terminal */
244
for (n = all(); n.hasMoreElements(); )
246
nt = (non_terminal)n.nextElement();
248
/* consider every production of that non terminal */
249
for (p = nt.productions(); p.hasMoreElements(); )
251
prod = (production)p.nextElement();
253
/* get the updated first of that production */
254
prod_first = prod.check_first_set();
256
/* if this going to add anything, add it */
257
if (!prod_first.is_subset_of(nt._first_set))
260
nt._first_set.add(prod_first);
267
/*-----------------------------------------------------------*/
268
/*--- (Access to) Instance Variables ------------------------*/
269
/*-----------------------------------------------------------*/
271
/** Table of all productions with this non terminal on the LHS. */
272
protected Hashtable _productions = new Hashtable(11);
274
/** Access to productions with this non terminal on the LHS. */
275
public Enumeration productions() {return _productions.elements();}
277
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
279
/** Total number of productions with this non terminal on the LHS. */
280
public int num_productions() {return _productions.size();}
282
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
284
/** Add a production to our set of productions. */
285
public void add_production(production prod) throws internal_error
287
/* catch improper productions */
288
if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
289
throw new internal_error(
290
"Attempt to add invalid production to non terminal production table");
292
/* add it to the table, keyed with itself */
293
_productions.put(prod,prod);
296
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
298
/** Nullability of this non terminal. */
299
protected boolean _nullable;
301
/** Nullability of this non terminal. */
302
public boolean nullable() {return _nullable;}
304
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
306
/** First set for this non-terminal. */
307
protected terminal_set _first_set = new terminal_set();
309
/** First set for this non-terminal. */
310
public terminal_set first_set() {return _first_set;}
312
/*-----------------------------------------------------------*/
313
/*--- General Methods ---------------------------------------*/
314
/*-----------------------------------------------------------*/
316
/** Indicate that this symbol is a non-terminal. */
317
public boolean is_non_term()
322
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
324
/** Test to see if this non terminal currently looks nullable. */
325
protected boolean looks_nullable() throws internal_error
327
/* look and see if any of the productions now look nullable */
328
for (Enumeration e = productions(); e.hasMoreElements(); )
329
/* if the production can go to empty, we are nullable */
330
if (((production)e.nextElement()).check_nullable())
333
/* none of the productions can go to empty, so we are not nullable */
337
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
339
/** convert to string */
340
public String toString()
342
return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");
345
/*-----------------------------------------------------------*/