use of org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken in project jphp by jphp-compiler.
the class StringExprTokenTest method testSimple.
@Test
public void testSimple() {
TokenMeta meta = new TokenMeta("foobar", 0, 0, 0, 0);
StringExprToken token = new StringExprToken(meta, StringExprToken.Quote.SINGLE);
Assert.assertEquals("foobar", token.getValue());
}
use of org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken in project jphp by jphp-compiler.
the class Tokenizer method readString.
protected ValueExprToken readString(StringExprToken.Quote quote, int startPosition, int startLine) {
int i = currentPosition + 1, pos = relativePosition + 1;
StringExprToken.Quote ch_quote = null;
boolean slash = false;
StringBuilder sb = new StringBuilder();
boolean isMagic = quote != null && quote.isMagic();
String endString = null;
int startIndex = currentPosition + 1;
if (quote == StringExprToken.Quote.DOC) {
StringBuilder tmp = new StringBuilder();
StringExprToken.Quote docType = null;
for (; i < codeLength; i++) {
char ch = code.charAt(i);
pos++;
if (docType == null && GrammarUtils.isQuote(ch) != null) {
docType = GrammarUtils.isQuote(ch);
} else if (docType != null && docType == GrammarUtils.isQuote(ch)) {
if (i + 1 >= codeLength || !GrammarUtils.isNewline(code.charAt(i + 1))) {
throw new ParseException(Messages.ERR_PARSE_UNEXPECTED_END_OF_STRING.fetch(), new TraceInfo(context, currentLine, currentLine, pos + 1, pos + 1));
}
i += 1;
break;
// nop
} else if (tmp.length() == 0 && (ch == ' ' || ch == '\t')) {
//nop
} else if (GrammarUtils.isEngLetter(ch) || ch == '_' || (tmp.length() != 0 && Character.isDigit(ch))) {
tmp.append(ch);
} else if (tmp.length() > 0 && checkNewLine(ch)) {
pos = 0;
break;
} else {
String error = Messages.ERR_PARSE_UNEXPECTED_X.fetch(ch);
if (GrammarUtils.isNewline(ch))
error = Messages.ERR_PARSE_UNEXPECTED_END_OF_STRING.fetch();
throw new ParseException(error, new TraceInfo(context, currentLine, currentLine, pos, pos));
}
}
currentPosition = i;
// skip \n
i += 1;
isMagic = (docType == null || docType.isMagic());
endString = tmp.toString();
}
List<StringExprToken.Segment> segments = new ArrayList<StringExprToken.Segment>();
for (; i < codeLength; i++) {
char ch = code.charAt(i);
pos++;
ch_quote = GrammarUtils.isQuote(ch);
if (endString == null && (ch_quote == quote && !slash)) {
currentPosition = i;
relativePosition = pos;
break;
}
if (checkNewLine(ch)) {
pos = 0;
if (endString != null) {
int end = i + 1 + endString.length();
if (end < codeLength) {
if (code.substring(i + 1, end).equals(endString)) {
if ((code.charAt(end) == ';' && GrammarUtils.isNewline(code.charAt(end + 1))) || GrammarUtils.isNewline(code.charAt(end))) {
currentPosition = i + endString.length();
relativePosition = endString.length();
ch_quote = StringExprToken.Quote.DOC;
break;
}
}
}
}
}
if (!isMagic) {
switch(ch) {
case '\\':
if (!slash || endString != null)
sb.append(ch);
slash = !slash;
break;
case '\'':
if (endString == null)
// remove slash
sb.deleteCharAt(sb.length() - 1);
default:
sb.append(ch);
slash = false;
}
} else {
int dynamic = 0;
if (!slash) {
if (ch == '$' && (i + 1 < codeLength && code.charAt(i + 1) == '{')) {
dynamic = 2;
}
if (ch == '{' && (i + 1 < codeLength && code.charAt(i + 1) == '$'))
dynamic = 1;
}
if (dynamic > 0) {
if (dynamic == 2 || i + 1 < codeLength && code.charAt(i + 1) == '$') {
slash = false;
int opened = dynamic == 2 ? 0 : 1;
int j;
for (j = i + 1; j < codeLength; j++) {
switch(code.charAt(j)) {
case '{':
opened++;
break;
case '}':
opened--;
break;
}
checkNewLine(code.charAt(j));
if (opened == 0)
break;
}
if (opened != 0)
throw new ParseException(Messages.ERR_PARSE_UNEXPECTED_END_OF_STRING.fetch(), new TraceInfo(context, startLine, 0, relativePosition, 0));
String sub = code.substring(i, j + 1);
segments.add(new StringExprToken.Segment(sb.length(), sb.length() + sub.length(), dynamic == 2));
/*segments.add(new StringExprToken.Segment(
i - currentPosition - 1, j - currentPosition, dynamic == 2
));*/
sb.append(sub);
i = j;
continue;
}
}
if (slash) {
switch(ch) {
case 'r':
sb.append('\r');
slash = false;
break;
case 'n':
sb.append('\n');
slash = false;
break;
case 't':
sb.append('\t');
slash = false;
break;
case 'e':
sb.append((char) 0x1B);
slash = false;
break;
case 'v':
sb.append((char) 0x0B);
slash = false;
break;
case 'f':
sb.append('\f');
slash = false;
break;
case '\\':
sb.append(ch);
slash = !slash;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
// \[0-7]{1,3}
int k = i + 1;
for (int j = 1; j < 3; j++) {
k = i + j;
if (k < codeLength) {
char digit = code.charAt(k);
if (digit >= '0' && digit <= '7') {
// nop
} else
break;
} else
break;
}
String s = code.substring(i, k);
if (s.isEmpty()) {
sb.append(ch);
} else {
int val = Integer.parseInt(s, 8);
sb.append((char) val);
}
i = k - 1;
slash = false;
break;
case 'x':
int t = i + 1;
for (int j = 1; j < 5; j++) {
t = i + j;
if (t < codeLength) {
char digit = code.charAt(t);
if (Character.isDigit(digit) || (digit >= 'A' && digit <= 'F') || (digit >= 'a' && digit <= 'f')) {
// nop;
} else {
break;
}
} else
break;
}
String s16 = code.substring(i + 1, t);
if (s16.isEmpty()) {
sb.append(ch);
} else {
int val16 = Integer.parseInt(s16, 16);
sb.append((char) val16);
}
i = t - 1;
slash = false;
break;
case '$':
case '"':
default:
slash = false;
sb.append(ch);
break;
}
} else {
switch(ch) {
case '\\':
slash = true;
break;
case '$':
int k = i + 1;
boolean done = false;
int opened = 0;
int complex = 0;
if (k < codeLength) {
char first = code.charAt(k);
if (GrammarUtils.isEngLetter(first) || first == '_') {
k++;
done = true;
for (; i < codeLength; k++) {
if (k < codeLength) {
first = code.charAt(k);
if (Character.isDigit(first) || GrammarUtils.isEngLetter(first) || first == '_') {
// nop
} else if (complex == 1 && GrammarUtils.isVariableChar(first) && code.charAt(k - 1) == '[') {
// nop
} else if (complex == 0 && first == '[') {
opened++;
complex = 1;
} else if (complex == 1 && opened != 0 && first == ']') {
opened--;
if (opened <= 0) {
k++;
break;
}
} else if (complex == 0 && first == '-') {
if (k + 1 < codeLength && code.charAt(k + 1) == '>') {
k++;
complex = 2;
} else
break;
} else
break;
} else
break;
}
}
}
if (done) {
if (opened != 0)
throw new ParseException(Messages.ERR_PARSE_UNEXPECTED_END_OF_STRING.fetch(), new TraceInfo(context, startLine, 0, pos, 0));
String s = code.substring(i, k);
segments.add(new StringExprToken.Segment(sb.length(), sb.length() + s.length(), true));
sb.append(s);
} else
sb.append(ch);
i = k - 1;
break;
default:
sb.append(ch);
}
}
}
}
if (ch_quote != quote || slash) {
throw new ParseException(Messages.ERR_PARSE_UNEXPECTED_END_OF_STRING.fetch(), new TraceInfo(context, currentLine, currentLine, pos, pos));
}
TokenMeta meta = buildMeta(startPosition + 1, startLine);
meta.setStartIndex(startIndex - 1);
if (quote == StringExprToken.Quote.DOC) {
meta.setEndIndex(currentPosition + 3);
} else {
meta.setEndIndex(currentPosition + 1);
}
meta.setWord(sb.toString());
StringExprToken expr = new StringExprToken(meta, quote);
expr.setSegments(segments);
return expr;
}
Aggregations