001: package antlr;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.cs.usfca.edu
005: * Software rights: http://www.antlr.org/license.html
006: */
007:
008: import java.util.Hashtable;
009: import java.util.Enumeration;
010: import java.io.IOException;
011:
012: import antlr.collections.impl.BitSet;
013: import antlr.collections.impl.Vector;
014:
015: /** Lexer-specific grammar subclass */
016: class LexerGrammar extends Grammar {
017: // character set used by lexer
018: protected BitSet charVocabulary;
019: // true if the lexer generates literal testing code for nextToken
020: protected boolean testLiterals = true;
021: // true if the lexer generates case-sensitive LA(k) testing
022: protected boolean caseSensitiveLiterals = true;
023: /** true if the lexer generates case-sensitive literals testing */
024: protected boolean caseSensitive = true;
025: /** true if lexer is to ignore all unrecognized tokens */
026: protected boolean filterMode = false;
027:
028: /** if filterMode is true, then filterRule can indicate an optional
029: * rule to use as the scarf language. If null, programmer used
030: * plain "filter=true" not "filter=rule".
031: */
032: protected String filterRule = null;
033:
034: LexerGrammar(String className_, Tool tool_, String super Class) {
035: super (className_, tool_, super Class);
036: // by default, use 0..127 for ASCII char vocabulary
037: BitSet cv = new BitSet();
038: for (int i = 0; i <= 127; i++) {
039: cv.add(i);
040: }
041: setCharVocabulary(cv);
042:
043: // Lexer usually has no default error handling
044: defaultErrorHandler = false;
045: }
046:
047: /** Top-level call to generate the code */
048: public void generate() throws IOException {
049: generator.gen(this );
050: }
051:
052: public String getSuperClass() {
053: // If debugging, use debugger version of scanner
054: if (debuggingOutput)
055: return "debug.DebuggingCharScanner";
056: if (!MatchExceptionState.throwRecExceptions)
057: return "CharScannerNoEx";
058: return "CharScanner";
059: }
060:
061: // Get the testLiterals option value
062: public boolean getTestLiterals() {
063: return testLiterals;
064: }
065:
066: /**Process command line arguments.
067: * -trace have all rules call traceIn/traceOut
068: * -traceLexer have lexical rules call traceIn/traceOut
069: * -debug generate debugging output for parser debugger
070: */
071: public void processArguments(String[] args) {
072: for (int i = 0; i < args.length; i++) {
073: if (args[i].equals("-trace")) {
074: traceRules = true;
075: antlrTool.setArgOK(i);
076: } else if (args[i].equals("-traceLexer")) {
077: traceRules = true;
078: antlrTool.setArgOK(i);
079: } else if (args[i].equals("-debug")) {
080: debuggingOutput = true;
081: antlrTool.setArgOK(i);
082: }
083: }
084: }
085:
086: /** Set the character vocabulary used by the lexer */
087: public void setCharVocabulary(BitSet b) {
088: charVocabulary = b;
089: }
090:
091: /** Set lexer options */
092: public boolean setOption(String key, Token value) {
093: String s = value.getText();
094: if (key.equals("buildAST")) {
095: antlrTool.warning("buildAST option is not valid for lexer",
096: getFilename(), value.getLine(), value.getColumn());
097: return true;
098: }
099: if (key.equals("testLiterals")) {
100: if (s.equals("true")) {
101: testLiterals = true;
102: } else if (s.equals("false")) {
103: testLiterals = false;
104: } else {
105: antlrTool.warning(
106: "testLiterals option must be true or false",
107: getFilename(), value.getLine(), value
108: .getColumn());
109: }
110: return true;
111: }
112: if (key.equals("interactive")) {
113: if (s.equals("true")) {
114: interactive = true;
115: } else if (s.equals("false")) {
116: interactive = false;
117: } else {
118: antlrTool.error(
119: "interactive option must be true or false",
120: getFilename(), value.getLine(), value
121: .getColumn());
122: }
123: return true;
124: }
125: if (key.equals("caseSensitive")) {
126: if (s.equals("true")) {
127: caseSensitive = true;
128: } else if (s.equals("false")) {
129: caseSensitive = false;
130: } else {
131: antlrTool.warning(
132: "caseSensitive option must be true or false",
133: getFilename(), value.getLine(), value
134: .getColumn());
135: }
136: return true;
137: }
138: if (key.equals("caseSensitiveLiterals")) {
139: if (s.equals("true")) {
140: caseSensitiveLiterals = true;
141: } else if (s.equals("false")) {
142: caseSensitiveLiterals = false;
143: } else {
144: antlrTool
145: .warning(
146: "caseSensitiveLiterals option must be true or false",
147: getFilename(), value.getLine(), value
148: .getColumn());
149: }
150: return true;
151: }
152: if (key.equals("filter")) {
153: if (s.equals("true")) {
154: filterMode = true;
155: } else if (s.equals("false")) {
156: filterMode = false;
157: } else if (value.getType() == ANTLRTokenTypes.TOKEN_REF) {
158: filterMode = true;
159: filterRule = s;
160: } else {
161: antlrTool
162: .warning(
163: "filter option must be true, false, or a lexer rule name",
164: getFilename(), value.getLine(), value
165: .getColumn());
166: }
167: return true;
168: }
169: if (key.equals("longestPossible")) {
170: antlrTool
171: .warning(
172: "longestPossible option has been deprecated; ignoring it...",
173: getFilename(), value.getLine(), value
174: .getColumn());
175: return true;
176: }
177: if (key.equals("className")) {
178: super .setOption(key, value);
179: return true;
180: }
181: if (super .setOption(key, value)) {
182: return true;
183: }
184: antlrTool.error("Invalid option: " + key, getFilename(), value
185: .getLine(), value.getColumn());
186: return false;
187: }
188: }
|