KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JFlex > SemCheck


1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * JFlex 1.4.1 *
3  * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
4  * All rights reserved. *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License. See the file *
8  * COPYRIGHT for more information. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License along *
16  * with this program; if not, write to the Free Software Foundation, Inc., *
17  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
18  * *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

20 package JFlex;
21
22 import java.io.File JavaDoc;
23
24 /**
25  * Performs simple semantic analysis on regular expressions.
26  *
27  * (used for checking if trailing contexts are legal)
28  *
29  * @author Gerwin Klein
30  * @version JFlex 1.4.1, $Revision: 2.5 $, $Date: 2004/11/06 23:03:32 $
31  */

32 public final class SemCheck {
33
34   // stored globally since they are used as constants in all checks
35
private static Macros macros;
36   private static char maxChar;
37
38
39   /**
40    * Performs semantic analysis for all expressions.
41    *
42    * Currently: illegal lookahead check only
43    * [fixme: more checks possible]
44    *
45    * @param rs the reg exps to be checked
46    * @param m the macro table (in expanded form)
47    * @param max max character of the used charset (for negation)
48    * @param f the spec file containing the rules [fixme]
49    */

50   public static void check(RegExps rs, Macros m, char max, File JavaDoc f) {
51     macros = m;
52     maxChar = max;
53     
54     int num = rs.getNum();
55     for (int i = 0; i < num; i++) {
56       RegExp r = rs.getRegExp(i);
57       RegExp l = rs.getLookAhead(i);
58      
59       if (!checkLookAhead(r,l)) {
60         Out.warning(f, ErrorMessages.LOOKAHEAD_ERROR, rs.getLine(i), -1);
61       }
62     }
63   }
64
65
66   /**
67    * Checks for illegal lookahead expressions.
68    *
69    * Lookahead in JFlex only works when the first expression has fixed
70    * length or when the intersection of the last set of the first expression
71    * and the first set of the second expression is empty.
72    *
73    * FIXME: this check is much too weak
74    *
75    *
76    * @param r1 first regexp
77    * @param r2 second regexp (the lookahead)
78    *
79    * @return true iff JFlex can generate code for the lookahead expression
80    */

81   private static boolean checkLookAhead(RegExp r1, RegExp r2) {
82     return r2 == null || length(r1) > 0;
83   }
84
85
86   /**
87    * Returns length if expression has fixed length, -1 otherwise.
88    *
89    * Negation operators are treated as always variable length.
90    */

91   private static int length(RegExp re) {
92     RegExp2 r;
93
94     switch (re.type) {
95
96     case sym.BAR: {
97       r = (RegExp2) re;
98       int l1 = length(r.r1);
99       if (l1 < 0) return -1;
100       int l2 = length(r.r2);
101
102       if (l1 == l2)
103         return l1;
104       else
105         return -1;
106     }
107
108     case sym.CONCAT: {
109       r = (RegExp2) re;
110       int l1 = length(r.r1);
111       if (l1 < 0) return -1;
112       int l2 = length(r.r2);
113       if (l2 < 0) return -1;
114       return l1+l2;
115     }
116
117     case sym.STAR:
118     case sym.PLUS:
119     case sym.QUESTION:
120       return -1;
121
122     case sym.CCLASS:
123     case sym.CCLASSNOT:
124     case sym.CHAR:
125     case sym.CHAR_I:
126       return 1;
127
128     case sym.STRING:
129     case sym.STRING_I: {
130       String JavaDoc content = (String JavaDoc) ((RegExp1) re).content;
131       return content.length();
132     }
133
134     case sym.TILDE:
135     case sym.BANG:
136        // too hard to caculate at this level, use safe approx
137
return -1;
138
139     case sym.MACROUSE:
140       return length(macros.getDefinition((String JavaDoc) ((RegExp1) re).content));
141     }
142
143     throw new Error JavaDoc("Unkown expression type "+re.type+" in "+re); //$NON-NLS-1$ //$NON-NLS-2$
144
}
145 }
146
Popular Tags