4 changed files with 218 additions and 0 deletions
-
198prism/src/parser/ast/QuotedString.java
-
10prism/src/parser/visitor/ASTTraverse.java
-
9prism/src/parser/visitor/ASTTraverseModify.java
-
1prism/src/parser/visitor/ASTVisitor.java
@ -0,0 +1,198 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2015- |
|||
// Authors: |
|||
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden) |
|||
// |
|||
//------------------------------------------------------------------------------ |
|||
// |
|||
// This file is part of PRISM. |
|||
// |
|||
// PRISM is free software; you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation; either version 2 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// PRISM is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with PRISM; if not, write to the Free Software Foundation, |
|||
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|||
// |
|||
//============================================================================== |
|||
|
|||
package parser.ast; |
|||
|
|||
import java.util.regex.Matcher; |
|||
|
|||
import parser.visitor.ASTVisitor; |
|||
import prism.PrismLangException; |
|||
|
|||
/** |
|||
* A quoted string ("text"). |
|||
*/ |
|||
public class QuotedString extends ASTElement |
|||
{ |
|||
|
|||
/** The unquoted text */ |
|||
private String text; |
|||
/** Flag: do we need to quote on output? */ |
|||
private boolean needsEscaping; |
|||
|
|||
/** Constructor for the text (without quotes) */ |
|||
public QuotedString(String text) |
|||
{ |
|||
this.text = text; |
|||
needsEscaping = needsEscaping(text); |
|||
} |
|||
|
|||
/** Constructor for the text (without quotes) and info about escaping */ |
|||
private QuotedString(String text, boolean needsEscaping) |
|||
{ |
|||
this.text = text; |
|||
this.needsEscaping = needsEscaping; |
|||
} |
|||
|
|||
/** Get the unquoted text */ |
|||
public String getText() |
|||
{ |
|||
return text; |
|||
} |
|||
|
|||
/** Get the quoted string */ |
|||
public String getQuoted() { |
|||
if (!needsEscaping) { |
|||
return "\"" + text + "\""; |
|||
} |
|||
// first, replace all \ -> \\ |
|||
String result= text.replaceAll("[\\\\]", Matcher.quoteReplacement("\\\\")); |
|||
// first, replace all " -> \" |
|||
result = result.replaceAll("[\"]", Matcher.quoteReplacement("\\\"")); |
|||
// finally, add outer " |
|||
return "\"" + result + "\""; |
|||
} |
|||
|
|||
@Override |
|||
public Object accept(ASTVisitor v) throws PrismLangException |
|||
{ |
|||
return v.visit(this); |
|||
} |
|||
|
|||
@Override |
|||
public String toString() |
|||
{ |
|||
return getQuoted(); |
|||
} |
|||
|
|||
@Override |
|||
public QuotedString deepCopy() |
|||
{ |
|||
return new QuotedString(text, needsEscaping); |
|||
} |
|||
|
|||
/** Does the unquoted string need quoting, i.e. does it contain " or \ characters?*/ |
|||
private static boolean needsEscaping(String s) |
|||
{ |
|||
// does the string contain " or \ ? |
|||
return (s.indexOf('"')!=-1 || s.indexOf('\\')!=-1); |
|||
} |
|||
|
|||
/** Static constructor, from quoted string */ |
|||
public static QuotedString fromQuoted(String quotedString) throws PrismLangException { |
|||
return new QuotedString(unquote(quotedString)); |
|||
} |
|||
|
|||
/** Unquote a quoted string */ |
|||
public static String unquote(String s) throws PrismLangException |
|||
{ |
|||
if (!s.startsWith("\"")) { |
|||
throw new PrismLangException("String not quoted : " + s); |
|||
} |
|||
if (!s.endsWith("\"")) { |
|||
throw new PrismLangException("String does not end with quote: " + s); |
|||
} |
|||
|
|||
// remove outer quotes |
|||
s = s.substring(1, s.length()-1); |
|||
int pos = s.indexOf('\\'); // find first '\' |
|||
if (pos == -1) { |
|||
// nothing to unquote |
|||
if (s.indexOf('\"') != -1) { |
|||
throw new PrismLangException("Unquoted \" in string: \"" + s+ "\""); |
|||
} |
|||
return s; |
|||
} |
|||
|
|||
StringBuffer sb = new StringBuffer(); |
|||
int last_pos = 0; |
|||
do { |
|||
String n = s.substring(last_pos, pos); // substring that doesn't need to be quoted |
|||
if (n.indexOf('\"') != -1) { |
|||
throw new PrismLangException("Unquoted \" in string: \"" + s+ "\""); |
|||
} |
|||
sb.append(n); |
|||
if (pos+1 >= s.length()) { |
|||
throw new PrismLangException("Quoted string ends with \\ character: \"" + s +"\""); |
|||
} |
|||
sb.append(s.charAt(pos+1)); // the quoted character |
|||
last_pos = pos+2; // skip quote character |
|||
pos = s.indexOf('\\', last_pos); // find next '\' |
|||
} while (pos != -1); |
|||
|
|||
if (last_pos < s.length()) { |
|||
String n = s.substring(last_pos); // remaining |
|||
if (n.indexOf('\"') != -1) { |
|||
throw new PrismLangException("Unquoted \" in string: \"" + s+ "\""); |
|||
} |
|||
sb.append(n); |
|||
} |
|||
|
|||
return sb.toString(); |
|||
} |
|||
|
|||
@Override |
|||
public int hashCode() |
|||
{ |
|||
final int prime = 31; |
|||
int result = 1; |
|||
result = prime * result + (needsEscaping ? 1231 : 1237); |
|||
result = prime * result + ((text == null) ? 0 : text.hashCode()); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public boolean equals(Object obj) |
|||
{ |
|||
if (this == obj) |
|||
return true; |
|||
if (obj == null) |
|||
return false; |
|||
if (!(obj instanceof QuotedString)) |
|||
return false; |
|||
QuotedString other = (QuotedString) obj; |
|||
if (needsEscaping != other.needsEscaping) |
|||
return false; |
|||
if (text == null) { |
|||
if (other.text != null) |
|||
return false; |
|||
} else if (!text.equals(other.text)) |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
/** small test routine, reads lines from System.in and unquotes / quotes */ |
|||
public static void main(String[] args) throws Exception |
|||
{ |
|||
java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); |
|||
String line; |
|||
while ((line = r.readLine()) != null) { |
|||
System.out.print(line + " => "); |
|||
System.out.flush(); |
|||
String unquoted = unquote(line); |
|||
System.out.println(unquoted + " => " + new QuotedString(unquoted)); |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue