1	package antlr;
2	
3	/**
4	 * <b>SOFTWARE RIGHTS</b>
5	 * <p>
6	 * ANTLR 2.5.0 MageLang Institute, 1998
7	 * <p>
8	 * We reserve no legal rights to the ANTLR--it is fully in the
9	 * public domain. An individual or company may do whatever
10	 * they wish with source code distributed with ANTLR or the
11	 * code generated by ANTLR, including the incorporation of
12	 * ANTLR, or its output, into commerical software.
13	 * <p>
14	 * We encourage users to develop software with ANTLR. However,
15	 * we do ask that credit is given to us for developing
16	 * ANTLR. By "credit", we mean that if you use ANTLR or
17	 * incorporate any source code into one of your programs
18	 * (commercial product, research project, or otherwise) that
19	 * you acknowledge this fact somewhere in the documentation,
20	 * research report, etc... If you like ANTLR and have
21	 * developed a nice tool with the output, please mention that
22	 * you developed it using ANTLR. In addition, we ask that the
23	 * headers remain intact in our source code. As long as these
24	 * guidelines are kept, we expect to continue enhancing this
25	 * system and expect to make other tools available as they are
26	 * completed.
27	 * <p>
28	 * The ANTLR gang:
29	 * @version ANTLR 2.5.0 MageLang Institute, 1998
30	 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
31	 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
32	 */
33	import java.util.Hashtable;
34	import java.util.Enumeration;
35	import java.io.IOException;
36	import antlr.collections.impl.BitSet;
37	import antlr.collections.impl.Vector;
38	
39	/** Lexer-specific grammar subclass */
40	class LexerGrammar extends Grammar {
41		// character set used by lexer
42		protected BitSet charVocabulary;
43		// true if the lexer generates literal testing code for nextToken
44		protected boolean testLiterals = true;
45		// true if the lexer generates case-sensitive LA(k) testing
46		protected boolean caseSensitiveLiterals = true;
47		/** true if the lexer generates case-sensitive literals testing */
48		protected boolean caseSensitive = true;
49		/** true if lexer is to ignore all unrecognized tokens */
50		protected boolean filterMode = false;
51	
52		/** if filterMode is true, then filterRule can indicate an optional
53		 *  rule to use as the scarf language.  If null, programmer used
54		 *  plain "filter=true" not "filter=rule".
55		 */
56		protected String filterRule = null;
57	
58		LexerGrammar(String className_, Tool tool_, String superClass) {
59			super(className_, tool_, superClass);
60			charVocabulary = new BitSet();
61	
62			// Lexer usually has no default error handling
63			defaultErrorHandler = false;
64		}
65		/** Top-level call to generate the code	 */
66		public void generate() throws IOException {
67			generator.gen(this);
68		}
69		public String getSuperClass() {
70			// If debugging, use debugger version of scanner
71			if (debuggingOutput)
72				return "debug.DebuggingCharScanner";
73			return "CharScanner";
74		}
75		// Get the testLiterals option value
76		public boolean getTestLiterals() {
77			return testLiterals;
78		}
79		/**Process command line arguments.
80		 * -trace			have all rules call traceIn/traceOut
81		 * -traceLexer		have lexical rules call traceIn/traceOut
82		 * -debug			generate debugging output for parser debugger
83		 */
84		public void processArguments(String[] args) {
85			for (int i=0; i<args.length; i++) {
86				if ( args[i].equals("-trace") ) {
87					traceRules = true;
88					Tool.setArgOK(i);
89				}
90				else if ( args[i].equals("-traceLexer") ) {
91					traceRules = true;
92					Tool.setArgOK(i);
93				}
94				else if ( args[i].equals("-debug") ) {
95					debuggingOutput = true;
96					Tool.setArgOK(i);
97				}
98			}
99		}
100		/** Set the character vocabulary used by the lexer */
101		public void setCharVocabulary(BitSet b) {
102			charVocabulary = b;
103		}
104		/** Set lexer options */
105		public boolean setOption(String key, Token value) {
106			String s = value.getText();
107			if (key.equals("buildAST")) {
108				tool.warning("buildAST option is not valid for lexer", value.getLine());
109				return true;
110			}
111			if (key.equals("testLiterals")) {
112				if (s.equals("true")) {
113					testLiterals = true;
114				} else if (s.equals("false")) {
115					testLiterals = false;
116				} else {
117					tool.warning("testLiterals option must be true or false", value.getLine());
118				}
119				return true;
120			}
121			if (key.equals("literal")) {
122				if (tokenManager == null) {
123					tool.error("Specify a tokenVocabulary before defining literals", value.getLine());
124					return false;
125				}
126				if ( tokenManager.getTokenSymbol(s) != null ) {
127					// string symbol is already defined
128					return true;
129				}
130				StringLiteralSymbol sl = new StringLiteralSymbol(value.getText());
131				int tt = tokenManager.nextTokenType();
132				if (tt != 0) {
133					sl.setTokenType(tt);
134					tokenManager.define(sl);
135				} else {
136					tool.error("You cannot define new string literals when using tokdef", value.getLine());
137					return false;
138				}
139				return true;
140			}
141			if (key.equals("interactive")) {
142				if (s.equals("true")) {
143					interactive = true;
144				} else if (s.equals("false")) {
145					interactive = false;
146				} else {
147					tool.error("interactive option must be true or false", value.getLine());
148				}
149				return true;
150			}
151			if (key.equals("caseSensitive")) {
152				if (s.equals("true")) {
153					caseSensitive = true;
154				} else if (s.equals("false")) {
155					caseSensitive = false;
156				} else {
157					tool.warning("caseSensitive option must be true or false", value.getLine());
158				}
159				return true;
160			}
161			if (key.equals("caseSensitiveLiterals")) {
162				if (s.equals("true")) {
163					caseSensitiveLiterals= true;
164				} else if (s.equals("false")) {
165					caseSensitiveLiterals= false;
166				} else {
167					tool.warning("caseSensitiveLiterals option must be true or false", value.getLine());
168				}
169				return true;
170			}
171			if (key.equals("filter")) {
172				if (s.equals("true")) {
173					filterMode = true;
174				} else if (s.equals("false")) {
175					filterMode = false;
176				} else if ( value.getType()==ANTLRTokenTypes.TOKEN_REF) {
177					filterMode = true;
178					filterRule = s;
179				}
180				else {
181					tool.warning("filter option must be true, false, or a lexer rule name", value.getLine());
182				}
183				return true;
184			}
185			if (key.equals("longestPossible")) {
186				tool.warning("longestPossible option has been deprecated; ignoring it...", value.getLine());
187				return true;
188			}
189			if (super.setOption(key, value)) {
190				return true;
191			}
192			tool.error("Invalid option: " + key, value.getLine());
193			return false;
194		}
195	}
196