Search in sources :

Example 1 with StringExprToken

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());
}
Also used : TokenMeta(org.develnext.jphp.core.tokenizer.TokenMeta) StringExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken) Test(org.junit.Test)

Example 2 with StringExprToken

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;
}
Also used : ArrayList(java.util.ArrayList) TraceInfo(php.runtime.env.TraceInfo) StringExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken) ParseException(php.runtime.exceptions.ParseException)

Aggregations

StringExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken)2 ArrayList (java.util.ArrayList)1 TokenMeta (org.develnext.jphp.core.tokenizer.TokenMeta)1 Test (org.junit.Test)1 TraceInfo (php.runtime.env.TraceInfo)1 ParseException (php.runtime.exceptions.ParseException)1