/*******************************************************************************
* Copyright (c) 2008 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.tcl.internal.tclchecker.v5;
import java.util.List;
import org.eclipse.dltk.tcl.internal.parser.raw.BracesSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.CodeScanner;
import org.eclipse.dltk.tcl.internal.parser.raw.ErrorDescription;
import org.eclipse.dltk.tcl.internal.parser.raw.ICodeScanner;
import org.eclipse.dltk.tcl.internal.parser.raw.ISubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.MagicBackslashSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.NormalBackslashSubstitution;
import org.eclipse.dltk.tcl.internal.parser.raw.SimpleTclParser;
import org.eclipse.dltk.tcl.internal.parser.raw.TclCommand;
import org.eclipse.dltk.tcl.internal.parser.raw.TclElement;
import org.eclipse.dltk.tcl.internal.parser.raw.TclParseException;
import org.eclipse.dltk.tcl.internal.parser.raw.TclScript;
import org.eclipse.dltk.tcl.internal.parser.raw.TclWord;
public final class TclDictionaryParser extends SimpleTclParser {
@Override
public ISubstitution getCVB(ICodeScanner input) throws TclParseException {
if (NormalBackslashSubstitution.iAm(input))
return new NormalBackslashSubstitution();
if (MagicBackslashSubstitution.iAm(input))
return new MagicBackslashSubstitution();
return null;
}
private static class UnexpectedError extends RuntimeException {
private static final long serialVersionUID = 1L;
}
@Override
public boolean handleError(ErrorDescription error) {
throw new UnexpectedError();
}
@Override
public TclScript parse(String content) {
try {
return parse(new CodeScanner(content), false, null);
} catch (UnexpectedError e) {
// e.printStackTrace();
return null;
} catch (TclParseException e) {
// e.printStackTrace();
return null;
}
}
public List<IToken> parseDictionary(String input) {
TclScript script = parse(input);
if (script != null) {
return convert(0, input, script.getCommands()).getChildren();
} else {
return null;
}
}
private ListToken convert(int offset, String content,
List<TclCommand> commands) {
final ListToken result = new ListToken();
for (int i = 0; i < commands.size(); ++i) {
final TclCommand command = commands.get(i);
final List<TclWord> words = command.getWords();
for (int j = 0; j < words.size(); ++j) {
final TclWord word = words.get(j);
final List<Object> contents = word.getContents();
if (contents.size() == 1
&& contents.get(0) instanceof BracesSubstitution) {
final String substText = content.substring(offset
+ word.getStart() + 1, offset + word.getEnd());
result.addChild(new RawToken(this, substText));
} else {
boolean join = false;
final List<IToken> children = result.getChildren();
final int startChildrentCount = children.size();
for (Object item : contents) {
if (item instanceof String) {
if (join) {
IToken prev = children.get(children.size() - 1);
assert (prev instanceof WordToken);
children.set(children.size() - 1,
new WordToken(prev.getText() + item));
} else {
result.addChild(new WordToken((String) item));
}
} else if (item instanceof TclElement) {
final TclElement element = (TclElement) item;
final String wordText = content.substring(offset
+ element.getStart(), offset
+ element.getEnd() + 1);
if (element instanceof NormalBackslashSubstitution) {
if (!children.isEmpty()
&& children.size() > startChildrentCount) {
IToken prev = children
.get(children.size() - 1);
if (prev instanceof WordToken) {
children.set(children.size() - 1,
new WordToken(prev.getText()
+ wordText));
join = true;
continue;
}
}
}
join = false;
result.addChild(new WordToken(wordText));
}
}
}
}
}
return result;
}
}