Search in sources :

Example 1 with ParseException

use of php.runtime.exceptions.ParseException in project jphp by jphp-compiler.

the class EvalFunctions method eval.

public static Memory eval(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals, String code) throws Throwable {
    Context context = new Context(code);
    try {
        Tokenizer tokenizer = new Tokenizer(context);
        SyntaxAnalyzer analyzer = syntaxAnalyzer.get();
        analyzer.reset(env, tokenizer);
        AbstractCompiler compiler = new JvmCompiler(env, context, analyzer);
        ModuleEntity module = compiler.compile();
        env.scope.loadModule(module);
        env.registerModule(module);
        return module.include(env, locals);
    } catch (ErrorException e) {
        if (e.getType() == ErrorType.E_PARSE) {
            if (env.isHandleErrors(ErrorType.E_PARSE))
                throw new ParseException(evalErrorMessage(e), trace);
        } else
            env.error(trace, e.getType(), evalErrorMessage(e));
    }
    return Memory.FALSE;
}
Also used : Context(php.runtime.env.Context) AbstractCompiler(php.runtime.common.AbstractCompiler) SyntaxAnalyzer(org.develnext.jphp.core.syntax.SyntaxAnalyzer) JvmCompiler(org.develnext.jphp.core.compiler.jvm.JvmCompiler) ModuleEntity(php.runtime.reflection.ModuleEntity) ParseException(php.runtime.exceptions.ParseException) ErrorException(php.runtime.exceptions.support.ErrorException) Tokenizer(org.develnext.jphp.core.tokenizer.Tokenizer)

Example 2 with ParseException

use of php.runtime.exceptions.ParseException in project jphp by jphp-compiler.

the class TokenizerTest method testParseError.

@Test
public void testParseError() throws IOException {
    Throwable ex = null;
    Tokenizer tokenizer = new Tokenizer(new Context("  'foobar \n "));
    try {
        tokenizer.nextToken();
    } catch (Throwable e) {
        ex = e;
    }
    assertTrue(ex instanceof ParseException);
    TraceInfo traceInfo = ((ParseException) ex).getTraceInfo();
    assertNotNull(traceInfo);
    assertNull(traceInfo.getContext().getFileName());
    assertEquals(1, traceInfo.getStartLine());
    assertEquals(1, traceInfo.getEndLine());
    assertEquals(1, traceInfo.getStartPosition());
    assertEquals(1, traceInfo.getEndPosition());
}
Also used : Context(php.runtime.env.Context) ParseException(php.runtime.exceptions.ParseException) TraceInfo(php.runtime.env.TraceInfo) Tokenizer(org.develnext.jphp.core.tokenizer.Tokenizer) Test(org.junit.Test)

Example 3 with ParseException

use of php.runtime.exceptions.ParseException 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)

Example 4 with ParseException

use of php.runtime.exceptions.ParseException in project jphp by jphp-compiler.

the class SimpleExprGenerator method processString.

protected Token processString(StringExprToken string) {
    if (string.getSegments().isEmpty()) {
        if (string.getQuote() == StringExprToken.Quote.SHELL) {
            return new ShellExecExprToken(string.getMeta(), Arrays.<Token>asList(string));
        }
        return string;
    }
    List<Token> tokens = new ArrayList<Token>();
    int i = 0;
    String value = string.getValue();
    TokenMeta meta = string.getMeta();
    for (StringExprToken.Segment segment : string.getSegments()) {
        String prev = value.substring(i, segment.from);
        if (!prev.isEmpty()) {
            StringExprToken item = new StringExprToken(new TokenMeta(prev, meta.getStartLine() + i, meta.getEndLine(), meta.getStartLine(), meta.getEndLine()), StringExprToken.Quote.SINGLE);
            tokens.add(item);
        }
        String dynamic = value.substring(segment.from, segment.to);
        if (!segment.isVariable)
            dynamic = dynamic.substring(1, dynamic.length() - 1);
        Tokenizer tokenizer = new Tokenizer(dynamic + ";", analyzer.getContext());
        try {
            SyntaxAnalyzer syntaxAnalyzer = new SyntaxAnalyzer(analyzer.getEnvironment(), tokenizer, analyzer.getFunction());
            List<Token> tree = syntaxAnalyzer.getTree();
            analyzer.getScope().addVariables(syntaxAnalyzer.getScope().getVariables());
            assert tree.size() > 0;
            Token item = tree.get(0);
            if (!(item instanceof ExprStmtToken))
                unexpectedToken(item);
            ExprStmtToken expr = (ExprStmtToken) item;
            if (expr.isSingle()) {
                tokens.add(expr.getSingle());
            } else
                tokens.add(expr);
        } catch (ParseException e) {
            TraceInfo oldTrace = e.getTraceInfo();
            e.setTraceInfo(new TraceInfo(analyzer.getContext(), meta.getStartLine() + oldTrace.getStartLine(), meta.getEndLine() + oldTrace.getEndLine(), meta.getStartLine() + oldTrace.getStartLine(), meta.getEndLine() + oldTrace.getEndLine()));
            throw e;
        }
        i = segment.to;
    }
    String prev = value.substring(i);
    if (!prev.isEmpty()) {
        StringExprToken item = new StringExprToken(new TokenMeta(prev, meta.getStartLine() + i, meta.getEndLine(), meta.getStartLine(), meta.getEndLine()), StringExprToken.Quote.SINGLE);
        tokens.add(item);
    }
    if (string.getQuote() == StringExprToken.Quote.SHELL) {
        return new ShellExecExprToken(meta, tokens);
    }
    StringBuilderExprToken result = new StringBuilderExprToken(meta, tokens);
    result.setBinary(string.isBinary());
    return result;
}
Also used : TokenMeta(org.develnext.jphp.core.tokenizer.TokenMeta) MacroToken(org.develnext.jphp.core.tokenizer.token.expr.value.macro.MacroToken) SemicolonToken(org.develnext.jphp.core.tokenizer.token.SemicolonToken) Token(org.develnext.jphp.core.tokenizer.token.Token) CastExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.cast.CastExprToken) BreakToken(org.develnext.jphp.core.tokenizer.token.BreakToken) ColonToken(org.develnext.jphp.core.tokenizer.token.ColonToken) UnsetCastExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.cast.UnsetCastExprToken) TraceInfo(php.runtime.env.TraceInfo) SyntaxAnalyzer(org.develnext.jphp.core.syntax.SyntaxAnalyzer) ParseException(php.runtime.exceptions.ParseException) Tokenizer(org.develnext.jphp.core.tokenizer.Tokenizer)

Example 5 with ParseException

use of php.runtime.exceptions.ParseException in project jphp by jphp-compiler.

the class ClassGenerator method processProperty.

protected List<ClassVarStmtToken> processProperty(ClassStmtToken clazz, VariableExprToken current, List<Token> modifiers, ListIterator<Token> iterator) {
    Token next = current;
    Token prev = null;
    Set<VariableExprToken> variables = new LinkedHashSet<VariableExprToken>();
    List<ExprStmtToken> initValues = new ArrayList<>();
    ExprStmtToken initValue = null;
    List<ClassVarStmtToken> result = new ArrayList<ClassVarStmtToken>();
    Modifier modifier = Modifier.PUBLIC;
    boolean isStatic = false;
    for (Token token : modifiers) {
        if (token instanceof PrivateStmtToken)
            modifier = Modifier.PRIVATE;
        else if (token instanceof ProtectedStmtToken)
            modifier = Modifier.PROTECTED;
        else if (token instanceof StaticExprToken)
            isStatic = true;
    }
    do {
        if (next instanceof VariableExprToken) {
            if (!variables.add((VariableExprToken) next)) {
                throw new ParseException(Messages.ERR_IDENTIFIER_X_ALREADY_USED.fetch(next.getWord()), next.toTraceInfo(analyzer.getContext()));
            }
            initValues.add(null);
        } else if (next instanceof CommaToken) {
            if (!(prev instanceof VariableExprToken))
                unexpectedToken(next);
        } else if (next instanceof AssignExprToken) {
            if (!(prev instanceof VariableExprToken))
                unexpectedToken(next);
            initValue = analyzer.generator(SimpleExprGenerator.class).getToken(nextToken(iterator), iterator, Separator.COMMA_OR_SEMICOLON, null);
            initValues.set(initValues.size() - 1, initValue);
            if (iterator.hasPrevious() && isBreak(iterator.previous())) {
                iterator.next();
                break;
            }
            if (iterator.hasNext()) {
                iterator.next();
            }
        //break;
        } else if (next instanceof SemicolonToken) {
            if (!(prev instanceof VariableExprToken))
                unexpectedToken(next);
            break;
        }
        prev = next;
        next = nextToken(iterator);
    } while (true);
    int i = 0;
    for (VariableExprToken variable : variables) {
        ClassVarStmtToken classVar = new ClassVarStmtToken(variable.getMeta());
        classVar.setModifier(modifier);
        classVar.setStatic(isStatic);
        classVar.setValue(initValues.get(i));
        classVar.setVariable(variable);
        classVar.setClazz(clazz);
        result.add(classVar);
        i++;
    }
    return result;
}
Also used : CommaToken(org.develnext.jphp.core.tokenizer.token.expr.CommaToken) AssignExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.AssignExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) AssignExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.AssignExprToken) CommentToken(org.develnext.jphp.core.tokenizer.token.CommentToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) CommaToken(org.develnext.jphp.core.tokenizer.token.expr.CommaToken) SemicolonToken(org.develnext.jphp.core.tokenizer.token.SemicolonToken) SemicolonToken(org.develnext.jphp.core.tokenizer.token.SemicolonToken) ParseException(php.runtime.exceptions.ParseException) Modifier(php.runtime.common.Modifier)

Aggregations

ParseException (php.runtime.exceptions.ParseException)5 Tokenizer (org.develnext.jphp.core.tokenizer.Tokenizer)3 TraceInfo (php.runtime.env.TraceInfo)3 SyntaxAnalyzer (org.develnext.jphp.core.syntax.SyntaxAnalyzer)2 SemicolonToken (org.develnext.jphp.core.tokenizer.token.SemicolonToken)2 Token (org.develnext.jphp.core.tokenizer.token.Token)2 Context (php.runtime.env.Context)2 ArrayList (java.util.ArrayList)1 JvmCompiler (org.develnext.jphp.core.compiler.jvm.JvmCompiler)1 TokenMeta (org.develnext.jphp.core.tokenizer.TokenMeta)1 BreakToken (org.develnext.jphp.core.tokenizer.token.BreakToken)1 ColonToken (org.develnext.jphp.core.tokenizer.token.ColonToken)1 CommentToken (org.develnext.jphp.core.tokenizer.token.CommentToken)1 BraceExprToken (org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken)1 CommaToken (org.develnext.jphp.core.tokenizer.token.expr.CommaToken)1 AssignExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.AssignExprToken)1 CastExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.cast.CastExprToken)1 UnsetCastExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.cast.UnsetCastExprToken)1 StringExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken)1 MacroToken (org.develnext.jphp.core.tokenizer.token.expr.value.macro.MacroToken)1