diff options
author | Uwe Stieber | 2012-06-13 06:26:26 +0000 |
---|---|---|
committer | Uwe Stieber | 2012-06-13 06:26:26 +0000 |
commit | 3f34408239e538ab5944e86ffef37f3768e71a1b (patch) | |
tree | 7f74773efc87d2599f79a54ae6af82b27ad65fe9 /target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting | |
parent | d268863bdd3e14a937cac51d5de46324e36e1bc4 (diff) | |
download | org.eclipse.tcf-3f34408239e538ab5944e86ffef37f3768e71a1b.tar.gz org.eclipse.tcf-3f34408239e538ab5944e86ffef37f3768e71a1b.tar.xz org.eclipse.tcf-3f34408239e538ab5944e86ffef37f3768e71a1b.zip |
Target Explorer: String token handling in script parser
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting')
-rw-r--r-- | target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/parser/Parser.java | 500 |
1 files changed, 250 insertions, 250 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/parser/Parser.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/parser/Parser.java index ead77d97b..7db81909e 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/parser/Parser.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/parser/Parser.java @@ -1,250 +1,250 @@ -/*******************************************************************************
- * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. 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:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.tcf.core.scripting.parser;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.tcf.protocol.JSON;
-
-/**
- * Script parser implementation.
- */
-public class Parser {
- // Reference to the script to parse
- private final String script;
-
- // Define some patterns to match the lines against
- private static final Pattern EMPTY_LINE = Pattern.compile("\\s*"); //$NON-NLS-1$
- private static final Pattern COMMENT_LINE = Pattern.compile("\\s*#.*"); //$NON-NLS-1$
- private static final Pattern CONNECT_LINE = Pattern.compile("\\s*connect\\s+.*"); //$NON-NLS-1$
- private static final Pattern COMMAND_LINE = Pattern.compile("\\s*tcf\\s+(\\w+)\\s+(\\w+)(.*)"); //$NON-NLS-1$
-
- /**
- * Constructor.
- */
- public Parser(String script) {
- Assert.isNotNull(script);
- this.script = script;
- }
-
- /**
- * Parse the given script and returns the extracted command tokens.
- *
- * @return The list of command tokens found in the script, or an empty list.
- * @throws IOException - if the script parsing fails.
- */
- public Token[] parse() throws IOException {
- List<Token> tokens = new ArrayList<Token>();
-
- BufferedReader reader = new BufferedReader(new StringReader(script));
-
- String line;
- while ((line = reader.readLine()) != null) {
- // All the following lines are ignored if matched
- if (EMPTY_LINE.matcher(line).matches()) continue;
- if (COMMENT_LINE.matcher(line).matches()) continue;
- if (CONNECT_LINE.matcher(line).matches()) continue;
-
- // If it is a command line, get the groups from it
- Matcher matcher = COMMAND_LINE.matcher(line);
- if (matcher.matches()) {
- String serviceName = matcher.group(1).trim();
- String commandName = matcher.group(2).trim();
- String arguments = matcher.group(3);
-
- // Create a new token
- Token token = new Token();
- token.setServiceName(serviceName);
- token.setCommandName(commandName);
-
- // Parse the arguments
- parseArguments(token, arguments);
-
- // Add the token to the list
- tokens.add(token);
- }
- }
-
- reader.close();
-
- return tokens.toArray(new Token[tokens.size()]);
- }
-
- /**
- * Parse the arguments string and add the extracted arguments
- * to the given token.
- *
- * @param token The token. Must not be <code>null</code>.
- * @param arguments The arguments string or <code>null</code>.
- */
- protected void parseArguments(Token token, String arguments) {
- Assert.isNotNull(token);
-
- if (arguments == null || "".equals(arguments.trim())) { //$NON-NLS-1$
- return;
- }
-
- // Tokenize by space, but do special handling for maps and lists
- StringTokenizer tokenizer = new StringTokenizer(arguments, " "); //$NON-NLS-1$
- while (tokenizer.hasMoreTokens()) {
- String tok = tokenizer.nextToken();
- if (tok == null || "".equals(tok.trim())) continue; //$NON-NLS-1$
-
- if (tok.equals("null")) { //$NON-NLS-1$
- token.addArgument(null);
- continue;
- }
-
- if (tok.startsWith("\"")) { //$NON-NLS-1$
- // String type
-
- StringBuilder fullTok = new StringBuilder(tok);
- boolean complete = isComplete(fullTok.toString(), '"', '"');
- while (!complete && tokenizer.hasMoreTokens()) {
- fullTok.append(" "); //$NON-NLS-1$
- fullTok.append(tokenizer.nextToken());
- complete = isComplete(fullTok.toString(), '"', '"');
- }
-
- if (complete) {
- String fullTokStr = fullTok.toString().trim();
- if (fullTokStr.startsWith("\"")) fullTokStr = fullTokStr.substring(1); //$NON-NLS-1$
- if (fullTokStr.endsWith("\"")) fullTokStr = fullTokStr.substring(0, fullTok.length() - 1); //$NON-NLS-1$
- token.addArgument(fullTokStr);
- continue;
- }
- }
-
- if ("true".equalsIgnoreCase(tok) || "false".equalsIgnoreCase(tok)) { //$NON-NLS-1$ //$NON-NLS-2$
- token.addArgument(Boolean.valueOf(tok));
- continue;
- }
-
- try {
- Integer i = Integer.decode(tok);
- token.addArgument(i);
- continue;
- } catch (NumberFormatException e) { /* ignored on purpose */ }
-
- try {
- Long l = Long.decode(tok);
- token.addArgument(l);
- continue;
- } catch (NumberFormatException e) { /* ignored on purpose */ }
-
- try {
- Float f = Float.valueOf(tok);
- token.addArgument(f);
- continue;
- } catch (NumberFormatException e) { /* ignored on purpose */ }
-
- try {
- Double d = Double.valueOf(tok);
- token.addArgument(d);
- continue;
- } catch (NumberFormatException e) { /* ignored on purpose */ }
-
- // If it starts with '{' or '[', it's a map or list type
- if (tok.startsWith("{")) { //$NON-NLS-1$
- // Map type
-
- StringBuilder fullTok = new StringBuilder(tok);
- boolean complete = isComplete(fullTok.toString(), '{', '}');
- while (!complete && tokenizer.hasMoreTokens()) {
- fullTok.append(" "); //$NON-NLS-1$
- fullTok.append(tokenizer.nextToken());
- complete = isComplete(fullTok.toString(), '{', '}');
- }
-
- if (complete) {
- String fullTokStr = fullTok.toString() + "\0"; //$NON-NLS-1$
- try {
- Object[] args = JSON.parseSequence(fullTokStr.getBytes());
- if (args != null) {
- for (Object arg : args) {
- if (arg != null) token.addArgument(arg);
- }
- continue;
- }
- } catch (IOException e) { /* ignored on purpose */ e.printStackTrace(); }
- }
- }
-
- if (tok.startsWith("[")) { //$NON-NLS-1$
- // List type
-
- StringBuilder fullTok = new StringBuilder(tok);
- boolean complete = isComplete(fullTok.toString(), '[', ']');
- while (!complete && tokenizer.hasMoreTokens()) {
- fullTok.append(" "); //$NON-NLS-1$
- fullTok.append(tokenizer.nextToken());
- complete = isComplete(fullTok.toString(), '[', ']');
- }
-
- if (complete) {
- String fullTokStr = fullTok.toString() + "\0"; //$NON-NLS-1$
- try {
- Object[] args = JSON.parseSequence(fullTokStr.getBytes());
- if (args != null) {
- for (Object arg : args) {
- if (arg != null) token.addArgument(arg);
- }
- continue;
- }
- } catch (IOException e) { /* ignored on purpose */ }
- }
- }
-
- // Add the argument token as is
- token.addArgument(tok);
- }
- }
-
- /**
- * Counts the number of opening and closing characters inside the given
- * string and returns <code>true</code> if the number matches.
- *
- * @param tok The arguments token. Must not be <code>null</code>.
- * @param opening The opening character.
- * @param closing The closing character.
- *
- * @return <code>True</code> if the number of opening characters matches the number of closing characters, <code>false</code> otherwise.
- */
- protected boolean isComplete(String tok, char opening, char closing) {
- Assert.isNotNull(tok);
-
- int countOpening = 0;
- int countClosing = 0;
-
- boolean same = opening == closing;
-
- for (int i = 0; i < tok.length(); i++) {
- char c = tok.charAt(i);
-
- if (c == opening && same) {
- if (countOpening > countClosing) countClosing++;
- else countOpening++;
- } else {
- if (c == opening) { countOpening++; continue; }
- if (c == closing) { countClosing++; continue; }
- }
- }
-
- return countOpening > 0 && countOpening == countClosing;
- }
-}
+/******************************************************************************* + * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.core.scripting.parser; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.tcf.protocol.JSON; + +/** + * Script parser implementation. + */ +public class Parser { + // Reference to the script to parse + private final String script; + + // Define some patterns to match the lines against + private static final Pattern EMPTY_LINE = Pattern.compile("\\s*"); //$NON-NLS-1$ + private static final Pattern COMMENT_LINE = Pattern.compile("\\s*#.*"); //$NON-NLS-1$ + private static final Pattern CONNECT_LINE = Pattern.compile("\\s*connect\\s+.*"); //$NON-NLS-1$ + private static final Pattern COMMAND_LINE = Pattern.compile("\\s*tcf\\s+(\\w+)\\s+(\\w+)(.*)"); //$NON-NLS-1$ + + /** + * Constructor. + */ + public Parser(String script) { + Assert.isNotNull(script); + this.script = script; + } + + /** + * Parse the given script and returns the extracted command tokens. + * + * @return The list of command tokens found in the script, or an empty list. + * @throws IOException - if the script parsing fails. + */ + public Token[] parse() throws IOException { + List<Token> tokens = new ArrayList<Token>(); + + BufferedReader reader = new BufferedReader(new StringReader(script)); + + String line; + while ((line = reader.readLine()) != null) { + // All the following lines are ignored if matched + if (EMPTY_LINE.matcher(line).matches()) continue; + if (COMMENT_LINE.matcher(line).matches()) continue; + if (CONNECT_LINE.matcher(line).matches()) continue; + + // If it is a command line, get the groups from it + Matcher matcher = COMMAND_LINE.matcher(line); + if (matcher.matches()) { + String serviceName = matcher.group(1).trim(); + String commandName = matcher.group(2).trim(); + String arguments = matcher.group(3); + + // Create a new token + Token token = new Token(); + token.setServiceName(serviceName); + token.setCommandName(commandName); + + // Parse the arguments + parseArguments(token, arguments); + + // Add the token to the list + tokens.add(token); + } + } + + reader.close(); + + return tokens.toArray(new Token[tokens.size()]); + } + + /** + * Parse the arguments string and add the extracted arguments + * to the given token. + * + * @param token The token. Must not be <code>null</code>. + * @param arguments The arguments string or <code>null</code>. + */ + protected void parseArguments(Token token, String arguments) { + Assert.isNotNull(token); + + if (arguments == null || "".equals(arguments.trim())) { //$NON-NLS-1$ + return; + } + + // Tokenize by space, but do special handling for maps and lists + StringTokenizer tokenizer = new StringTokenizer(arguments, " "); //$NON-NLS-1$ + while (tokenizer.hasMoreTokens()) { + String tok = tokenizer.nextToken(); + if (tok == null || "".equals(tok.trim())) continue; //$NON-NLS-1$ + + if (tok.equals("null")) { //$NON-NLS-1$ + token.addArgument(null); + continue; + } + + if (tok.startsWith("\"")) { //$NON-NLS-1$ + // String type + + StringBuilder fullTok = new StringBuilder(tok); + boolean complete = isComplete(fullTok.toString(), '"', '"'); + while (!complete && tokenizer.hasMoreTokens()) { + fullTok.append(" "); //$NON-NLS-1$ + fullTok.append(tokenizer.nextToken()); + complete = isComplete(fullTok.toString(), '"', '"'); + } + + if (complete) { + String fullTokStr = fullTok.toString().trim(); + if (fullTokStr.startsWith("\"")) fullTokStr = fullTokStr.substring(1); //$NON-NLS-1$ + if (fullTokStr.endsWith("\"")) fullTokStr = fullTokStr.substring(0, fullTok.length() - 2); //$NON-NLS-1$ + token.addArgument(fullTokStr); + continue; + } + } + + if ("true".equalsIgnoreCase(tok) || "false".equalsIgnoreCase(tok)) { //$NON-NLS-1$ //$NON-NLS-2$ + token.addArgument(Boolean.valueOf(tok)); + continue; + } + + try { + Integer i = Integer.decode(tok); + token.addArgument(i); + continue; + } catch (NumberFormatException e) { /* ignored on purpose */ } + + try { + Long l = Long.decode(tok); + token.addArgument(l); + continue; + } catch (NumberFormatException e) { /* ignored on purpose */ } + + try { + Float f = Float.valueOf(tok); + token.addArgument(f); + continue; + } catch (NumberFormatException e) { /* ignored on purpose */ } + + try { + Double d = Double.valueOf(tok); + token.addArgument(d); + continue; + } catch (NumberFormatException e) { /* ignored on purpose */ } + + // If it starts with '{' or '[', it's a map or list type + if (tok.startsWith("{")) { //$NON-NLS-1$ + // Map type + + StringBuilder fullTok = new StringBuilder(tok); + boolean complete = isComplete(fullTok.toString(), '{', '}'); + while (!complete && tokenizer.hasMoreTokens()) { + fullTok.append(" "); //$NON-NLS-1$ + fullTok.append(tokenizer.nextToken()); + complete = isComplete(fullTok.toString(), '{', '}'); + } + + if (complete) { + String fullTokStr = fullTok.toString() + "\0"; //$NON-NLS-1$ + try { + Object[] args = JSON.parseSequence(fullTokStr.getBytes()); + if (args != null) { + for (Object arg : args) { + if (arg != null) token.addArgument(arg); + } + continue; + } + } catch (IOException e) { /* ignored on purpose */ e.printStackTrace(); } + } + } + + if (tok.startsWith("[")) { //$NON-NLS-1$ + // List type + + StringBuilder fullTok = new StringBuilder(tok); + boolean complete = isComplete(fullTok.toString(), '[', ']'); + while (!complete && tokenizer.hasMoreTokens()) { + fullTok.append(" "); //$NON-NLS-1$ + fullTok.append(tokenizer.nextToken()); + complete = isComplete(fullTok.toString(), '[', ']'); + } + + if (complete) { + String fullTokStr = fullTok.toString() + "\0"; //$NON-NLS-1$ + try { + Object[] args = JSON.parseSequence(fullTokStr.getBytes()); + if (args != null) { + for (Object arg : args) { + if (arg != null) token.addArgument(arg); + } + continue; + } + } catch (IOException e) { /* ignored on purpose */ } + } + } + + // Add the argument token as is + token.addArgument(tok); + } + } + + /** + * Counts the number of opening and closing characters inside the given + * string and returns <code>true</code> if the number matches. + * + * @param tok The arguments token. Must not be <code>null</code>. + * @param opening The opening character. + * @param closing The closing character. + * + * @return <code>True</code> if the number of opening characters matches the number of closing characters, <code>false</code> otherwise. + */ + protected boolean isComplete(String tok, char opening, char closing) { + Assert.isNotNull(tok); + + int countOpening = 0; + int countClosing = 0; + + boolean same = opening == closing; + + for (int i = 0; i < tok.length(); i++) { + char c = tok.charAt(i); + + if (c == opening && same) { + if (countOpening > countClosing) countClosing++; + else countOpening++; + } else { + if (c == opening) { countOpening++; continue; } + if (c == closing) { countClosing++; continue; } + } + } + + return countOpening > 0 && countOpening == countClosing; + } +} |