Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

2.1-beta1: Compiler: Expression token order #5

Open
Skrupellos opened this Issue · 0 comments

1 participant

@Skrupellos

Reproduce

(This is a copy of http://bugs.invenzzia.org/task/178 )

Create an expression containing a "===" e.g. in an opt:if condition (like in my case) and compile it. (The bug also applies to "!=" and "!==")

<opt:if test="$edit === true">

Result

The compiler struggles interpreting "===" and raises the following exception:

PHP Fatal error: Uncaught exception 'Opt_Expression_Exception' with message 'Invalid token: =' in /Opt/Expression/Standard/Parser.php:2062
Stack trace:
#0 /Opt/Expression/Standard/Parser.php(2120): Opt_Expression_Standard_Parser->yy_syntax_error(25, '=')
#1 /Opt/Expression/Standard.php(177): Opt_Expression_Standard_Parser->doParse(25, '=')
#2 /Opt/Compiler/Class.php(1946): Opt_Expression_Standard->parse('$edit === true', true)
#3 /Opt/Instruction/Abstract.php(606): Opt_Compiler_Class->parseExpression('$edit === true', 'parse')
#4 /Opt/Instruction/Abstract.php(479): Opt_Instruction_Abstract->_extractAttribute(Object(Opt_Xml_Element), Object(Opt_Xml_Attribute), 6, NULL)
#5 /Opt/Instruction/If.php(107): Opt_Instruction_Abstract->_extractAttributes(Object(Opt_Xml_Element), Array)
#6 /Opt/Xml/Element.php(503): Opt_Instruction_If->proc in /Opt/Expression/Standard/Parser.php on line 2062

adding the following PHP code in Opt/Expression/Standard.php on line 172 (in the while loop) I get the output following afterwards.

Standard.php, line 172:

<?php
    if($expr == '$edit === true') {
        echo "{$lexer->token} ## {$lexer->value}\n";
    }
?>

debug output:

57 ## $
50 ## edit
w ##
4 ## ==
25 ## =
... The error message

Assumption

I guess the lexer sees the valid "==" token and accepts it before finding an also valid "===". Perhaps this is because of an wrong order in tools/lexer/expression_lexer.plex as shown below:

expression_lexer.plex:

<?php
// [...]
identifier {
    switch($this->value)
    {
    // [...]
    case 'eq':
        $this->token = Opt_Expression_Standard_Parser::T_EQUALS;
        break;
    case 'neq':
        $this->token = Opt_Expression_Standard_Parser::T_NEQUALS;
        break;
    case 'eqt':
        $this->token = Opt_Expression_Standard_Parser::T_EQUALS_T;
        break;
    case 'neqt':
        $this->token = Opt_Expression_Standard_Parser::T_NEQUALS_T;
        break;
    // [...]
?>

Workaround

According to http://static.invenzzia.org/docs/opt/2_0/book/en/syntax.expressions.operators.html , you can replace "===" with "eqt", "!=" with "neq" and "!==" with "neqt"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.