001: /*
002: * ParseAdaptor.java --
003: *
004: * Temporary adaptor class that creates the interface from the
005: * current expression parser to the new Parser class.
006: *
007: * Copyright (c) 1997 by Sun Microsystems, Inc.
008: *
009: * See the file "license.terms" for information on usage and redistribution
010: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
011: *
012: * RCS: @(#) $Id: ParseAdaptor.java,v 1.6 2003/02/05 09:24:40 mdejong Exp $
013: */
014:
015: package tcl.lang;
016:
017: class ParseAdaptor {
018:
019: /*
020: *----------------------------------------------------------------------
021: *
022: * parseVar --
023: *
024: * Extract the variable from the String and return it's value.
025: * The current expr parser passes an index after $, while the
026: * new Parser.parseVar expects the index to be at the $. The
027: * ParseResult returned by Parser.parseVar contains a nextIndex
028: * relative to the beginning of the variable. Reset nextIndex
029: * to be from the beginning of the string.
030: *
031: * Results:
032: * A ParseResult that contains the value of the variable and an
033: * index to the character after the varaible.
034: *
035: * Side effects:
036: * None.
037: *
038: *----------------------------------------------------------------------
039: */
040:
041: static ParseResult parseVar(Interp interp, // The current Interp.
042: String string, // The script containing the variable.
043: int index, // An index into string that points to.
044: // the character just after the $.
045: int length) // The length of the string.
046: throws TclException {
047: ParseResult result;
048:
049: index--;
050: result = Parser.parseVar(interp, string
051: .substring(index, length));
052: result.nextIndex += index;
053: return (result);
054: }
055:
056: /*
057: *----------------------------------------------------------------------
058: *
059: * parseNestedCmd --
060: *
061: * Parse the nested command in string. The index points to the
062: * character after the [. Set the interp flag to denote a nested
063: * evaluation.
064: *
065: * Results:
066: * A ParseResult with the value of the executed command and an
067: * index into string that points to the character after the ].
068: *
069: * Side effects:
070: * The call to eval2 may alter the state of the interp.
071: *
072: *----------------------------------------------------------------------
073: */
074:
075: static ParseResult parseNestedCmd(Interp interp, // The current Interp.
076: String string, // The script containing the nested command.
077: int index, // An index into string that points to.
078: // the character just after the [.
079: int length) // The length of the string.
080: throws TclException {
081: CharPointer script;
082: TclObject obj;
083:
084: // Check for the easy case where the last character in the string is '['.
085: if (index == length) {
086: throw new TclException(interp, "missing close-bracket");
087: }
088:
089: script = new CharPointer(string);
090: script.index = index;
091:
092: interp.evalFlags |= Parser.TCL_BRACKET_TERM;
093: Parser.eval2(interp, script.array, script.index,
094: length - index, 0);
095: obj = interp.getResult();
096: obj.preserve();
097: return (new ParseResult(obj, index + interp.termOffset + 1));
098: }
099:
100: /*
101: *----------------------------------------------------------------------
102: *
103: * parseQuotes --
104: *
105: * Use the new Parser to parse the quoted string. Index points to
106: * the character in string just after the first double-quotes
107: *
108: * Note: Before the new parser, there used to be a specific
109: * function to parse quoted strings. Since this is gone now, we
110: * need to initialize a parse object before Parser.parseTokens
111: * is called. If this is not done, the call to Parser.evalTokens
112: * will fail.
113: *
114: * Results:
115: * A ParseResult with the value of the quoted string and an index
116: * into string that points to the character after the double-quotes.
117: *
118: * Side effects:
119: * If the quotes contain a command it will be evaluated.
120: *
121: *----------------------------------------------------------------------
122: */
123:
124: static ParseResult parseQuotes(Interp interp, // The current Interp.
125: String string, // The script containing the variable.
126: int index, // An index into string that points to.
127: // the character just after the double-qoute.
128: int length) // The length of the string.
129: throws TclException {
130: TclObject obj;
131: TclParse parse = null;
132: TclToken token;
133: CharPointer script;
134:
135: final boolean debug = false;
136:
137: try {
138:
139: script = new CharPointer(string);
140: script.index = index;
141:
142: parse = new TclParse(interp, script.array, length, null, 0);
143:
144: if (debug) {
145: System.out.println("string is \"" + string + "\"");
146: System.out.println("script.array is \""
147: + new String(script.array) + "\"");
148:
149: System.out.println("index is " + index);
150: System.out.println("length is " + length);
151:
152: System.out.println("parse.endIndex is "
153: + parse.endIndex);
154: }
155:
156: parse.commandStart = script.index;
157: token = parse.getToken(0);
158: token.type = Parser.TCL_TOKEN_WORD;
159: token.script_array = script.array;
160: token.script_index = script.index;
161: parse.numTokens++;
162: parse.numWords++;
163: parse = Parser.parseTokens(script.array, script.index,
164: Parser.TYPE_QUOTE, parse);
165:
166: // Check for the error condition where the parse did not end on
167: // a '"' char. Is this happened raise an error.
168:
169: if (script.array[parse.termIndex] != '"') {
170: throw new TclException(interp, "missing \"");
171: }
172:
173: // if there was no error then parsing will continue after the
174: // last char that was parsed from the string
175:
176: script.index = parse.termIndex + 1;
177:
178: // Finish filling in the token for the word and check for the
179: // special case of a word consisting of a single range of
180: // literal text.
181:
182: token = parse.getToken(0);
183: token.size = script.index - token.script_index;
184: token.numComponents = parse.numTokens - 1;
185: if ((token.numComponents == 1)
186: && (parse.getToken(1).type == Parser.TCL_TOKEN_TEXT)) {
187: token.type = Parser.TCL_TOKEN_SIMPLE_WORD;
188: }
189: parse.commandSize = script.index - parse.commandStart;
190: if (parse.numTokens > 0) {
191: obj = Parser.evalTokens(interp, parse.tokenList, 1,
192: parse.numTokens - 1);
193: } else {
194: throw new TclRuntimeError(
195: "parseQuotes error: null obj result");
196: }
197:
198: } finally {
199: parse.release();
200: }
201:
202: return (new ParseResult(obj, script.index));
203: }
204:
205: /*
206: *----------------------------------------------------------------------
207: *
208: * parseBraces --
209: *
210: * The new Parser dosen't handle simple parsing of braces. This
211: * method extracts tokens until a close brace is found.
212: *
213: * Results:
214: * A ParseResult with the contents inside the brace and an index
215: * after the closing brace.
216: *
217: * Side effects:
218: * None.
219: *
220: *----------------------------------------------------------------------
221: */
222:
223: static ParseResult parseBraces(Interp interp, // The current Interp.
224: String str, // The script containing the variable.
225: int index, // An index into string that points to.
226: // the character just after the {.
227: int length) // The length of the string.
228: throws TclException {
229: char[] arr = str.toCharArray();
230: int level = 1;
231:
232: for (int i = index; i < length;) {
233: if (Parser.charType(arr[i]) == Parser.TYPE_NORMAL) {
234: i++;
235: } else if (arr[i] == '}') {
236: level--;
237: if (level == 0) {
238: str = new String(arr, index, i - index);
239: return new ParseResult(str, i + 1);
240: }
241: i++;
242: } else if (arr[i] == '{') {
243: level++;
244: i++;
245: } else if (arr[i] == '\\') {
246: BackSlashResult bs = Parser.backslash(arr, i);
247: i = bs.nextIndex;
248: } else {
249: i++;
250: }
251: }
252:
253: //if you run off the end of the string you went too far
254: throw new TclException(interp, "missing close-brace");
255: }
256: } // end ParseAdaptor
|