Warning, /kdevelop/kdevelop-pg-qt/examples/php/php.g is written in an unsupported language. File is not indexed.

0001 %token_stream TokenStream ;
0002 
0003 -- %input_encoding "utf8"
0004 %input_encoding "ascii"
0005 %sequence_lexer
0006 %input_stream "KDevPG::QByteArrayIterator"
0007 
0008 %parser_declaration_header "QtCore/QDebug"
0009 %lexer_bits_header "QtCore/QDebug"
0010 
0011 %lexer_bits_header "algorithm"
0012 %lexer_declaration_header "QtCore/QStack"
0013 %lexer_declaration_header "utility" -- pair
0014 %lexerclass(private declaration)
0015 [:
0016 QStack<std::pair<Iterator::PlainIterator, Iterator::PlainIterator> > nowDocStack;
0017 Iterator::PlainIterator hereDocHeaderBegin, hereDocHederEnd;
0018 :]
0019 
0020 
0021 ------------------------------------------------------------
0022 -- Enumeration types for additional AST members,
0023 -- in the global "Php" namespace
0024 ------------------------------------------------------------
0025 %namespace
0026 [:
0027     class Lexer;
0028 
0029     enum ModifierFlags {
0030         ModifierPrivate      = 1,
0031         ModifierPublic       = 1 << 1,
0032         ModifierProtected    = 1 << 2,
0033         ModifierStatic       = 1 << 3,
0034         ModifierFinal        = 1 << 4,
0035         ModifierAbstract     = 1 << 5
0036     };
0037 
0038     enum ClassModifier {
0039         NormalClass,
0040         AbstractClass,
0041         FinalClass
0042     };
0043 
0044     enum ScalarTypes {
0045         ScalarTypeInt,
0046         ScalarTypeFloat,
0047         ScalarTypeString
0048     };
0049 
0050     enum CastType {
0051         CastInt,
0052         CastDouble,
0053         CastString,
0054         CastArray,
0055         CastObject,
0056         CastBool,
0057         CastUnset
0058     };
0059 
0060     enum OperationType {
0061         OperationPlus = 1,
0062         OperationMinus,
0063         OperationConcat,
0064         OperationMul,
0065         OperationDiv,
0066         OperationMod,
0067         OperationAnd,
0068         OperationOr,
0069         OperationXor,
0070         OperationSl,
0071         OperationSr
0072     };
0073 :]
0074 
0075 ------------------------------------------------------------
0076 -- Ast Node class members
0077 ------------------------------------------------------------
0078 %ast_extra_members
0079 [:
0080 //KDevelop::DUContext* ducontext;
0081 :]
0082 
0083 ------------------------------------------------------------
0084 -- Parser class members
0085 ------------------------------------------------------------
0086 
0087 %parserclass (public declaration)
0088 [:
0089 
0090   enum ProblemType {
0091       Error,
0092       Warning,
0093       Info
0094   };
0095   void reportProblem( Parser::ProblemType type, const QString& message, int tokenOffset = -1 );
0096   QString tokenText(qint64 begin, qint64 end);
0097   void setDebug(bool debug);
0098 
0099     enum InitialLexerState {
0100         HtmlState = 0,
0101         DefaultState = 1
0102     };
0103 
0104 :]
0105 
0106 %parserclass (private declaration)
0107 [:
0108     enum VarExpressionState {
0109         Normal,
0110         OnlyVariable,
0111         OnlyNewObject
0112     };
0113     QString m_contents;
0114     bool m_debug;
0115     
0116     struct ParserState {
0117         VarExpressionState varExpressionState;
0118         bool varExpressionIsVariable;
0119     };
0120     ParserState m_state;
0121 :]
0122 
0123 %parserclass (constructor)
0124 [:
0125     m_state.varExpressionState = Normal;
0126     m_state.varExpressionIsVariable = false;
0127 :]
0128 
0129 %lexerclass(constructor)
0130 [:
0131 :]
0132 
0133 -- keywords:
0134 %token ABSTRACT ("abstract"), BREAK ("break"), CASE ("case"), CATCH ("catch"),
0135        CLASS ("class"), CONST ("const"), CONTINUE ("continue"),
0136        DEFAULT ("default"), DO ("do"), ELSE ("else"), EXTENDS ("extends"),
0137        FINAL ("final"), FOR ("for"), IF ("if"),
0138        IMPLEMENTS ("implements"), INSTANCEOF ("instanceof"), INTERFACE ("interface"),
0139        NEW ("new"), PRIVATE ("private"), PROTECTED ("protected"), PUBLIC ("public"),
0140        RETURN ("return"), STATIC ("static"), SWITCH ("switch"), THROW ("throw"),
0141        TRY ("try"), WHILE ("while"), ECHO ("echo"), PRINT ("print"),
0142        CLONE ("clone"), EXIT ("exit"), ELSEIF ("elseif"), ENDIF ("endif"),
0143        ENDWHILE ("endwhile"), ENDFOR ("endfor"), FOREACH ("foreach"), ENDFOREACH ("endforeach"),
0144        DECLARE ("declare"), ENDDECLARE ("enddeclare"), AS ("as"), ENDSWITCH ("endswitch"),
0145        FUNCTION ("function"), USE ("use"), GLOBAL ("global"), VAR ("var "), UNSET ("unset"),
0146        ISSET ("isset"), EMPTY ("empty"), HALT_COMPILER ("halt compiler"),
0147        DOUBLE_ARROW ("=>"), LIST ("list"), ARRAY ("array"), CLASS_C ("__CLASS__"),
0148        METHOD_C ("__METHOD__"), FUNC_C ("__FUNCTION__"), LINE ("__LINE__"),
0149        FILE ("__FILE__"), COMMENT ("comment"), DOC_COMMENT ("doc comment"),  PAAMAYIM_NEKUDOTAYIM ("::"),
0150        INCLUDE ("include"), INCLUDE_ONCE ("include_once"), EVAL ("eval"), REQUIRE ("require"),
0151        REQUIRE_ONCE ("require_once"), NAMESPACE ("namespace"), NAMESPACE_C("__NAMESPACE__"), USE("use"),
0152        GOTO ("goto") ;
0153 
0154 -- casts:
0155 %token INT_CAST ("int cast"), DOUBLE_CAST ("double cast"), STRING_CAST ("string cast"),
0156        ARRAY_CAST ("array cast"), OBJECT_CAST ("object cast"), BOOL_CAST ("bool cast"),
0157        UNSET_CAST ("unset cast") ;
0158 
0159 -- seperators:
0160 %token SEMICOLON (";"), DOUBLE_QUOTE ("\""), LBRACKET ("["),
0161        RBRACKET ("]"),
0162        LPAREN ("("), RPAREN (")"), LBRACE ("{"), RBRACE ("}"),
0163        COMMA (","), AT ("@"),
0164        CURLY_OPEN ("curly open"), -- { in "{$foo}"; not the same as LBRACE
0165        DOLLAR_OPEN_CURLY_BRACES ("${"),
0166        START_HEREDOC ("start heredoc"), END_HEREDOC ("end heredoc"),
0167        BACKTICK ("`"), BACKSLASH ("\\"),
0168        START_NOWDOC("start nowdoc"), END_NOWDOC("end nowdoc") ;
0169 
0170 -- operators:
0171 %token IS_EQUAL ("=="), IS_NOT_EQUAL ("!="), IS_IDENTICAL ("==="),
0172        IS_NOT_IDENTICAL ("!=="), IS_SMALLER ("<"), IS_GREATER (">"),
0173        IS_SMALLER_OR_EQUAL ("<="), IS_GREATER_OR_EQUAL (">="),
0174        BOOLEAN_OR ("||"), BOOLEAN_AND ("&&"), ASSIGN ("="),
0175        PLUS_ASSIGN ("+="), MINUS_ASSIGN ("-="), MUL_ASSIGN ("*="), DIV_ASSIGN ("/="),
0176        CONCAT_ASSIGN (".="), MOD_ASSIGN ("%="), AND_ASSIGN ("&="), OR_ASSIGN ("|="),
0177        XOR_ASSIGN ("^="), SL_ASSIGN ("<<="), SR_ASSIGN (">>="), OBJECT_OPERATOR ("->"),
0178        PLUS ("+"), MINUS("-"), CONCAT("."),
0179        INC ("++"), DEC ("--"), BANG ("!"), QUESTION ("?"), COLON (":"),
0180        BIT_AND ("&"), BIT_OR("|"), BIT_XOR ("^"),
0181        SL ("<<"), SR (">>"), MUL("*"), DIV("/"), MOD ("%"),
0182        TILDE ("~"), DOLLAR ("$"),
0183        LOGICAL_OR ("logical or"), LOGICAL_AND ("logical and"), LOGICAL_XOR ("logical xor") ;
0184 
0185 -- literals and identifiers:
0186 %token INLINE_HTML ("inline html"), WHITESPACE ("whitespace"),
0187        CONSTANT_ENCAPSED_STRING ("constant encapsed string"),
0188        VARIABLE ("variable"), ENCAPSED_AND_WHITESPACE ("encapsed and whitespace"),
0189        DNUMBER ("double number"), LNUMBER ("long number"),
0190        NUM_STRING ("num string"), STRING ("string"),
0191        STRING_VARNAME ("string varname") ; -- when in "${varname}"
0192 
0193 -- open/close tags
0194 %token OPEN_TAG ("<?"), CLOSE_TAG ("?>"), OPEN_TAG_WITH_ECHO ("<?=");
0195 
0196 %lexer ->
0197   "<?"|"<?php"                  [: qDebug() << "blub"; lxSET_RULE_SET(php) qDebug() << "open tag" << lxBEGIN_IDX << " " << lxCURR_IDX << " " << char(*lxCURR_POS);  :] OPEN_TAG ;
0198   "<?="                         [: lxSET_RULE_SET(php) :] OPEN_TAG_WITH_ECHO ;
0199   .+ %ba("<?")                  [: qDebug() << "ht " << lxBEGIN_IDX << " " << lxCURR_IDX << " " << char(*lxCURR_POS); :] INLINE_HTML;
0200   ;
0201 
0202 %lexer "php" ->
0203 %error [: qDebug() << "error in php"; throw exception(); :] ;
0204 [{alphabetic}_][{alphabetic}{num}_]* -> identifier ;
0205 
0206 "<<<"{identifier}\n               [: qDebug() << "start heredoc"; nowDocStack.push(make_pair(lxBEGIN_POS + 3, lxCURR_POS - 1)); :] START_HEREDOC;
0207 "<<<'"{identifier}"'"\n           [: lxSET_RULE_SET(nowdoc); nowDocStack.push(make_pair(lxBEGIN_POS + 4, lxCURR_POS - 2)); :] START_NOWDOC;
0208 
0209 -- abstract        ABSTRACT ;
0210 -- break           BREAK ;
0211 -- case            CASE ;
0212 -- catch           CATCH ;
0213 -- class           CLASS ;
0214 -- const           CONST ;
0215 -- continue        CONTINUE ;
0216 -- default         DEFAULT ;
0217 -- do              DO ;
0218 -- else            ELSE ;
0219 -- extends         EXTENDS ;
0220 -- final           FINAL ;
0221 -- for             FOR ;
0222 -- if              IF ;
0223 -- implements      IMPLEMENTS ;
0224 -- instanceof      INSTANCEOF ;
0225 -- interface       INTERFACE ;
0226 -- new             NEW ;
0227 -- private         PRIVATE ;
0228 -- protected       PROTECTED ;
0229 -- public          PUBLIC ;
0230 -- return          RETURN ;
0231 -- static          STATIC ;
0232 -- switch          SWITCH ;
0233 -- throw           THROW ;
0234 -- try             TRY ;
0235 -- while           WHILE ;
0236 echo            ECHO ;
0237 -- print           PRINT ;
0238 -- clone           CLONE ;
0239 -- exit            EXIT ;
0240 -- elseif          ELSEIF ;
0241 -- endif           ENDIF ;
0242 -- endwhile        ENDWHILE ;
0243 -- endfor          ENDFOR ;
0244 -- foreach         FOREACH ;
0245 -- endforeach      ENDFOREACH ;
0246 -- declare         DECLARE ;
0247 -- enddeclare      ENDDECLARE ;
0248 -- as              AS ;
0249 -- endswitch       ENDSWITCH ;
0250 -- function        FUNCTION ;
0251 -- use             USE ;
0252 -- global          GLOBAL ;
0253 -- var             VAR ;
0254 -- unset           UNSET ;
0255 -- isset           ISSET ;
0256 -- empty           EMPTY ;
0257 -- __halt_compiler HALT_COMPILER ;
0258 -- "=>"            DOUBLE_ARROW ;
0259 -- list            LIST ;
0260 -- array           ARRAY ;
0261 -- "__CLASS__"     CLASS_C ;
0262 -- "__METHOD__"    METHOD_C ;
0263 -- "__FUNCTION__"  FUNC_C ;
0264 -- "__LINE__"      LINE ;
0265 -- "__FILE__"      FILE ;
0266 -- "::"            PAAMAYIM_NEKUDOTAYIM ;
0267 -- include         INCLUDE ;
0268 -- include_once    INCLUDE_ONCE ;
0269 -- eval            EVAL ;
0270 -- require         REQUIRE ;
0271 -- require_once    REQUIRE_ONCE ;
0272 -- namespace       NAMESPACE ;
0273 -- "__NAMESPACE__" NAMESPACE_C ;
0274 -- use             USE ;
0275 -- goto            GOTO ;
0276 
0277 "/**"{white_space}(\.*^"*/")"*/"        DOC_COMMENT ;
0278 "/*"(\.*^"*/")"*/"|"//"[.^\n]*          COMMENT ;
0279 "?>"    [: lxSET_RULE_SET(start) :] CLOSE_TAG ;
0280 
0281 -- "("{white_space}*   -> bcast ;
0282 -- {white_space}*")"   -> ecast ;
0283 -- {bcast}(int|integer){ecast}     INT_CAST ;
0284 -- {bcast}(double|real|float){ecast}     DOUBLE_CAST ;
0285 -- {bcast}(string|binary){ecast}     STRING_CAST ;
0286 -- {bcast}"array"{ecast}     ARRAY_CAST ;
0287 -- {bcast}"object"{ecast}     OBJECT_CAST ;
0288 -- {bcast}(bool|boolean){ecast}     BOOL_CAST ;
0289 -- {bcast}"unset"{ecast}     UNSET_CAST ;
0290 
0291 -- "=="        IS_EQUAL;
0292 -- "!="        IS_NOT_EQUAL;
0293 -- "==="       IS_IDENTICAL;
0294 -- "!=="       IS_NOT_IDENTICAL;
0295 -- "<"         IS_SMALLER;
0296 -- ">"         IS_GREATER;
0297 -- "<="        IS_SMALLER_OR_EQUAL;
0298 -- ">="        IS_GREATER_OR_EQUAL;
0299 -- "||"        BOOLEAN_OR;
0300 -- "&&"        BOOLEAN_AND;
0301 -- "="         ASSIGN;
0302 -- "+="        PLUS_ASSIGN;
0303 -- "-="        MINUS_ASSIGN;
0304 -- "*="        MUL_ASSIGN;
0305 -- "/="        DIV_ASSIGN;
0306 -- ".="        CONCAT_ASSIGN;
0307 -- "%="        MOD_ASSIGN;
0308 -- "&="        AND_ASSIGN;
0309 -- "|="        OR_ASSIGN;
0310 -- "^="        XOR_ASSIGN;
0311 -- "<<="       SL_ASSIGN;
0312 -- ">>="       SR_ASSIGN;
0313 -- "->"        OBJECT_OPERATOR;
0314 -- "+"         PLUS;
0315 -- "-"         MINUS;
0316 -- "."         CONCAT;
0317 -- "++"        INC;
0318 -- "--"        DEC;
0319 -- "!"         BANG;
0320 -- "?"         QUESTION;
0321 -- ":"         COLON;
0322 -- "&"         BIT_AND;
0323 -- "|"         BIT_OR;
0324 -- "^"         BIT_XOR;
0325 -- "<<"        SL;
0326 -- ">>"        SR;
0327 -- "*"         MUL;
0328 -- "/"         DIV;
0329 -- "%"         MOD;
0330 -- "~"         TILDE;
0331 -- "$"         DOLLAR;
0332 -- "or"        LOGICAL_OR;
0333 -- "and"       LOGICAL_AND;
0334 -- "xor"       LOGICAL_XOR;
0335 
0336 ";"         SEMICOLON;
0337 "["         LBRACKET;
0338 "]"         RBRACKET;
0339 "("         LPAREN;
0340 ")"         RPAREN;
0341 "{"         LBRACE;
0342 "}"         RBRACE;
0343 ","         COMMA;
0344 "@"         AT;
0345 
0346 ("$"{identifier})    VARIABLE ;
0347 {identifier}         STRING ;
0348 
0349 {white_space}+   ; -- WHITESPACE
0350 
0351 ;
0352 
0353 %lexer "heredoc" ->
0354 %enter [: qDebug() << "entering heredoc"; :]
0355 %fail [: qDebug() << "failed in heredoc"; throw exception(); :]
0356 -- "$"{identifier}   
0357 "${"{identifier} [:
0358                     qDebug() << "found opening";
0359                     lxNAMED_TOKEN(open, DOLLAR_OPEN_CURLY_BRACES)
0360                     open.end = open.begin + 1;
0361                     lxNAMED_TOKEN(varname, STRING_VARNAME)
0362                     varname.begin += 2;
0363                     lxDONE
0364                 :] ;
0365 [.^\n]*. %ba("${")    [:
0366               std::size_t topLength = nowDocStack.top().second - nowDocStack.top().first;
0367               if(lxLENGTH >= topLength && equal(nowDocStack.top().first, nowDocStack.top().second, lxBEGIN_POS))
0368               {
0369                   qDebug() << "heredoc match";
0370                   lxCURR_POS = lxBEGIN_POS + topLength;
0371                   nowDocStack.pop();
0372                   lxRETURN(END_HEREDOC);
0373               }
0374               qDebug() << "heredoc line";
0375             :]
0376             ENCAPSED_AND_WHITESPACE;
0377 ;
0378 
0379 %lexer "nowdoc" ->
0380 [.^\n]*\n    [:
0381               std::size_t topLength = nowDocStack.top().second - nowDocStack.top().first;
0382               if(lxLENGTH >= topLength && equal(nowDocStack.top().first, nowDocStack.top().second, lxBEGIN_POS))
0383               {
0384                   lxCURR_POS = lxBEGIN_POS + topLength;
0385                   nowDocStack.pop();
0386                   lxSET_RULE_SET(php);
0387                   lxRETURN(END_NOWDOC);
0388               }
0389               qDebug() << "nowdoc line";
0390             :]
0391             STRING;
0392 ;
0393 
0394 -- The actual grammar starts here.
0395 
0396 #statements=outerTopStatement*
0397 -> start ;;
0398 
0399   namespaceDeclaration=namespaceDeclarationStatement
0400   | statement=topStatement
0401 -> outerTopStatement ;;
0402 
0403 -- first/first conflict for FUNCTION
0404    (?[: (LA(1).kind == Token_FUNCTION && ((LA(2).kind == Token_BIT_AND && LA(3).kind == Token_LPAREN)
0405             || LA(2).kind == Token_LPAREN))
0406         || LA(1).kind != Token_FUNCTION :]
0407     statement=statement )
0408   | functionDeclaration=functionDeclarationStatement
0409   | classDeclaration=classDeclarationStatement
0410   | interfaceDeclaration=interfaceDeclarationStatement
0411   | HALT_COMPILER LPAREN RPAREN SEMICOLON -- Lexer stops allready
0412 -> topStatement ;;
0413 
0414 [: bool reported = false; while ( true ) { :]
0415     try/recover(#statements=topStatement)*
0416 [: if (yytoken != Token_RBRACE && yytoken != Token_EOF && yytoken != Token_CLOSE_TAG
0417        && yytoken != Token_ELSEIF && yytoken != Token_ELSE
0418        && yytoken != Token_ENDIF && yytoken != Token_ENDFOREACH && yytoken != Token_ENDFOR
0419        && yytoken != Token_ENDWHILE && yytoken != Token_ENDSWITCH && yytoken != Token_ENDDECLARE
0420        && yytoken != Token_CASE && yytoken != Token_DEFAULT) {
0421         if (!reported) {
0422             qint64 index = tokenStream->index() - 1;
0423             Token &token = tokenStream->at(index);
0424             QString tokenValue = token.kind != 0 ? tokenText(token.begin, token.end) : "EOF";
0425             reportProblem(Error, QString("Unexpected token \"%1\".").arg(tokenValue));
0426             reported = true;
0427         }
0428         yylex();
0429    } else {
0430         break;
0431    }
0432 } :]
0433 -> innerStatementList ;;
0434 
0435 --Operator Precedence, from PHP Manual
0436 --left    or
0437 --left    xor
0438 --left    and
0439 --right   print
0440 --right   = += -= *= /= .= %= &= |= ^= <<= >>=    assignment
0441 --left    ? : ternary
0442 --left    ||  logical
0443 --left    &&  logical
0444 --left    |   bitwise
0445 --left    ^   bitwise
0446 --left    &   bitwise and references
0447 --non-associative == != === !==   comparison
0448 --non-associative < <= > >=   comparison
0449 --left    << >>   bitwise
0450 --left    + - .   arithmetic and string
0451 --left    * / %   arithmetic
0452 --non-associative ! ~ - (int) (float) (string) (array) (object) @ types
0453 --non-associative ++ --   increment/decrement
0454 --left    [   array()
0455 --non-associative new new
0456 
0457   expression=logicalOrExpression
0458 -> expr ;;
0459 
0460    #expression=logicalXorExpression @ LOGICAL_OR
0461 -> logicalOrExpression ;;
0462 
0463    #expression=logicalAndExpression @ LOGICAL_XOR
0464 -> logicalXorExpression ;;
0465 
0466    #expression=printExpression @ LOGICAL_AND
0467 -> logicalAndExpression ;;
0468 
0469   (print=PRINT*) expression=assignmentExpression
0470 -> printExpression ;;
0471 
0472 -- leftside must me a variable, we check afterwards if it was a variable and
0473 -- if not we report an error
0474 0 --needed for line below
0475 [: m_state.varExpressionIsVariable = false; :] --reset flag
0476 expression=conditionalExpression
0477 (
0478   assignmentExpressionEqual=assignmentExpressionEqual | (
0479      (
0480         PLUS_ASSIGN   [: (*yynode)->operation = OperationPlus; :]
0481       | MINUS_ASSIGN  [: (*yynode)->operation = OperationMinus; :]
0482       | MUL_ASSIGN    [: (*yynode)->operation = OperationMul; :]
0483       | DIV_ASSIGN    [: (*yynode)->operation = OperationDiv; :]
0484       | CONCAT_ASSIGN [: (*yynode)->operation = OperationConcat; :]
0485       | MOD_ASSIGN    [: (*yynode)->operation = OperationMod; :]
0486       | AND_ASSIGN    [: (*yynode)->operation = OperationAnd; :]
0487       | OR_ASSIGN     [: (*yynode)->operation = OperationOr; :]
0488       | XOR_ASSIGN    [: (*yynode)->operation = OperationXor; :]
0489       | SL_ASSIGN     [: (*yynode)->operation = OperationSl; :]
0490       | SR_ASSIGN     [: (*yynode)->operation = OperationSr; :]
0491      )
0492      assignmentExpressionCheckIfVariable
0493      assignmentExpression=assignmentExpression)
0494    | 0)
0495 -> assignmentExpression [
0496      member variable operation: OperationType;
0497 ];;
0498 
0499 --=& is special:
0500   -- $foo =& $var; is allowed but not $foo =& 'static';
0501   -- $foo =& new bar(); is allowed too but deprecated and reports a warning
0502   --we set a flag (varExpressionState) with that var_expression accepts only valid parts
0503   --this is done in such a strage way because we need the full expression to allow
0504   --things like $foo =& $bar || e();
0505 ASSIGN
0506     assignmentExpressionCheckIfVariable --as in assignmentExpression
0507     (BIT_AND [: if (yytoken == Token_NEW) {
0508                 reportProblem(Warning, "=& new foo() is deprecated", -2);
0509                 m_state.varExpressionState = OnlyNewObject;
0510               } else {
0511                 m_state.varExpressionState = OnlyVariable;
0512               }:]
0513      | 0) assignmentExpression=assignmentExpression [: m_state.varExpressionState = Normal; :]
0514 -> assignmentExpressionEqual ;;
0515 
0516 
0517 -- check if var_expression was a variable, if not report an error
0518 -- varExpressionIsVariable is set in var_expression
0519 0 --to allow cpp-code
0520 [:
0521     if (!m_state.varExpressionIsVariable) {
0522         reportProblem(Error, "Left side is not a variable");
0523         return false;
0524     }
0525 :]
0526 -> assignmentExpressionCheckIfVariable ;;
0527 
0528 expression=booleanOrExpression
0529    (  QUESTION (ifExpression=expr|0)
0530       COLON    elseExpression=conditionalExpression
0531     | 0
0532    )
0533 -> conditionalExpression ;;
0534 
0535   #expression=booleanAndExpression @ BOOLEAN_OR
0536 -> booleanOrExpression ;;
0537 
0538    #expression=bitOrExpression @ BOOLEAN_AND
0539 -> booleanAndExpression ;;
0540 
0541    #expression=bitXorExpression @ BIT_OR
0542 -> bitOrExpression ;;
0543 
0544    #expression=bitAndExpression @ BIT_XOR
0545 -> bitXorExpression ;;
0546 
0547    #expression=equalityExpression @ BIT_AND
0548 -> bitAndExpression ;;
0549 
0550    expression=relationalExpression
0551    (#additionalExpression=equalityExpressionRest)*
0552 -> equalityExpression ;;
0553 
0554    (  IS_EQUAL | IS_NOT_EQUAL | IS_IDENTICAL | IS_NOT_IDENTICAL )
0555    expression=relationalExpression
0556 -> equalityExpressionRest ;;
0557 
0558 
0559    expression=shiftExpression
0560    (  (#additionalExpression=relationalExpressionRest)+
0561       --instanceof as in java.g (correct??)
0562     | INSTANCEOF instanceofType=classNameReference
0563     | 0
0564    )
0565 -> relationalExpression ;;
0566 
0567    ( IS_SMALLER | IS_GREATER | IS_SMALLER_OR_EQUAL | IS_GREATER_OR_EQUAL )
0568    expression=shiftExpression
0569 -> relationalExpressionRest ;;
0570 
0571 
0572    expression=additiveExpression
0573    (#additionalExpression=shiftExpressionRest)*
0574 -> shiftExpression ;;
0575 
0576    ( SL | SR )
0577    expression=additiveExpression
0578 -> shiftExpressionRest ;;
0579 
0580 
0581    expression=multiplicativeExpression
0582    (#additionalExpression=additiveExpressionRest)*
0583 -> additiveExpression ;;
0584 
0585    (
0586        PLUS   [: (*yynode)->operation = OperationPlus; :]
0587      | MINUS  [: (*yynode)->operation = OperationMinus; :]
0588      | CONCAT [: (*yynode)->operation = OperationConcat; :]
0589    )
0590    expression=multiplicativeExpression
0591 -> additiveExpressionRest [
0592      member variable operation: OperationType;
0593 ];;
0594 
0595 
0596    expression=unaryExpression
0597    (#additionalExpression=multiplicativeExpressionRest)*
0598 -> multiplicativeExpression ;;
0599 
0600    (
0601        MUL [: (*yynode)->operation = OperationMul; :]
0602      | DIV [: (*yynode)->operation = OperationDiv; :]
0603      | MOD [: (*yynode)->operation = OperationMod; :]
0604    )
0605    expression=unaryExpression
0606 -> multiplicativeExpressionRest [
0607      member variable operation: OperationType;
0608 ];;
0609 
0610  (
0611     MINUS unaryExpression=unaryExpression
0612   | PLUS  unaryExpression=unaryExpression
0613   | BANG unaryExpression=unaryExpression
0614   | TILDE unaryExpression=unaryExpression
0615   | INT_CAST unaryExpression=unaryExpression    [: (*yynode)->castType = CastInt; :]
0616   | DOUBLE_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastDouble; :]
0617   | STRING_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastString; :]
0618   | ARRAY_CAST unaryExpression=unaryExpression  [: (*yynode)->castType = CastArray; :]
0619   | OBJECT_CAST unaryExpression=unaryExpression [: (*yynode)->castType = CastObject; :]
0620   | BOOL_CAST unaryExpression=unaryExpression   [: (*yynode)->castType = CastBool; :]
0621   | UNSET_CAST unaryExpression=unaryExpression  [: (*yynode)->castType = CastUnset; :]
0622   | AT unaryExpression=unaryExpression
0623   | LIST LPAREN assignmentList=assignmentList RPAREN ASSIGN unaryExpression=unaryExpression
0624   | EXIT (LPAREN (expression=expr | 0) RPAREN | 0)
0625   | EVAL LPAREN expression=expr RPAREN
0626   | INCLUDE includeExpression=unaryExpression
0627   | INCLUDE_ONCE includeExpression=unaryExpression
0628   | REQUIRE includeExpression=unaryExpression
0629   | REQUIRE_ONCE includeExpression=unaryExpression
0630 
0631   | unaryExpressionNotPlusminus=unaryExpressionNotPlusminus
0632  )
0633 -> unaryExpression [
0634      member variable castType: CastType;
0635 ];;
0636 
0637     (#prefixOperator=postprefixOperator)*
0638     varExpression=varExpression
0639     (#postfixOperator=postprefixOperator)*
0640 -> unaryExpressionNotPlusminus ;;
0641 
0642    op=INC | op=DEC
0643 -> postprefixOperator ;;
0644 
0645 --first/first conflict - no problem because of ifs
0646     ?[: m_state.varExpressionState == OnlyVariable :] 0 [: m_state.varExpressionState = Normal; :] variable=variable
0647   | ?[: m_state.varExpressionState == OnlyNewObject :] 0 [: m_state.varExpressionState = Normal; :] newObject=varExpressionNewObject
0648   | varExpressionNormal=varExpressionNormal
0649 -> varExpression ;;
0650 
0651     LPAREN expression=expr RPAREN
0652   | BACKTICK encapsList=encapsList BACKTICK
0653   --try/rollback resolves conflict scalar vs. staticMember (foo::bar vs. foo::$bar)
0654   --varExpressionIsVariable flag is needed for assignmentExpression
0655   | try/rollback (variable=variable [: m_state.varExpressionIsVariable = true; :])
0656     catch (scalar=scalar)
0657   | array=ARRAY LPAREN
0658         (#arrayValues=arrayPairValue
0659              -- break because array(1,) is allowed (solves FIRST/FOLLOW conflict)
0660           @ (COMMA [: if (yytoken == Token_RPAREN) { break; } :] ) | 0)
0661     RPAREN
0662   | ISSET LPAREN (#issetVariable=variable @ COMMA) RPAREN
0663   | EMPTY LPAREN emptyVarialbe=variable RPAREN
0664   | newObject=varExpressionNewObject
0665   | CLONE cloneCar=varExpressionNormal
0666   | closure=closure
0667 -> varExpressionNormal ;;
0668 
0669 -- http://wiki.php.net/rfc/closures
0670     FUNCTION (isRef=BIT_AND|0) LPAREN parameters=parameterList RPAREN
0671         ( USE LPAREN lexicalVars=lexicalVarList RPAREN | 0)
0672         LBRACE try/recover(functionBody=innerStatementList) RBRACE
0673 -> closure ;;
0674 
0675   (#lexicalVars=lexicalVar @ COMMA) | 0 [: reportProblem(Error, "Use list of closure must not be empty."); :]
0676 -> lexicalVarList ;;
0677 
0678   (isRef=BIT_AND | 0) variable=variableIdentifier
0679 -> lexicalVar ;;
0680 
0681     NEW className=classNameReference ctor=ctorArguments
0682 -> varExpressionNewObject ;;
0683 
0684     LPAREN parameterList=functionCallParameterList RPAREN
0685   | 0
0686 -> ctorArguments ;;
0687 
0688     #parameters=functionCallParameterListElement @ COMMA | 0
0689 -> functionCallParameterList ;;
0690 
0691     (BIT_AND variable=variable) | expr=expr
0692 -> functionCallParameterListElement ;;
0693 
0694     #element=assignmentListElement @COMMA
0695 -> assignmentList ;;
0696 
0697     variable=variable
0698   | LIST LPAREN assignmentList=assignmentList RPAREN
0699   | 0
0700 -> assignmentListElement ;;
0701 
0702     expr=expr (DOUBLE_ARROW (exprValue=expr | BIT_AND varValue=variable) | 0)
0703   | BIT_AND variable=variable
0704 -> arrayPairValue ;;
0705 
0706    var=baseVariableWithFunctionCalls (#variableProperties=variableProperty*)
0707 -> variable ;;
0708 
0709     (OBJECT_OPERATOR|PAAMAYIM_NEKUDOTAYIM)
0710     ( ?[: LA(1).kind == Token_DOLLAR:] LBRACE variable=variable RBRACE | objectProperty=objectProperty )
0711     (isFunctionCall=LPAREN parameterList=functionCallParameterList RPAREN | 0)
0712 -> variableProperty ;;
0713 
0714    --Conflict
0715    --   foo::$bar[0] (=baseVariable-staticMember)
0716    --vs.foo::$bar[0](); (=static function call)
0717    try/rollback (functionCall=functionCall)
0718    catch (baseVariable=baseVariable)
0719 -> baseVariableWithFunctionCalls ;;
0720 
0721     stringFunctionNameOrClass=namespacedIdentifier (
0722         LPAREN stringParameterList=functionCallParameterList RPAREN
0723       | PAAMAYIM_NEKUDOTAYIM
0724         (
0725             stringFunctionName=identifier LPAREN stringParameterList=functionCallParameterList RPAREN
0726             | varFunctionName=variableWithoutObjects LPAREN stringParameterList=functionCallParameterList RPAREN
0727         )
0728     )
0729   | varFunctionName=variableWithoutObjects LPAREN varParameterList=functionCallParameterList RPAREN
0730 -> functionCall ;;
0731 
0732     var=compoundVariableWithSimpleIndirectReference #offsetItems=dimListItem*
0733   | staticMember=staticMember
0734 -> baseVariable ;;
0735 
0736     variable=variableIdentifier
0737   | DOLLAR LBRACE expr=expr RBRACE
0738 -> compoundVariable ;;
0739 
0740   ( DOLLAR ( DOLLAR+ | 0 ) ( indirectVariable=variableIdentifier | LBRACE expr=expr RBRACE ) | variable=variableIdentifier )
0741 -> compoundVariableWithSimpleIndirectReference ;;
0742 
0743     expr=expr | 0
0744 -> dimOffset ;;
0745 
0746     className=namespacedIdentifier PAAMAYIM_NEKUDOTAYIM variable=variableWithoutObjects
0747 -> staticMember ;;
0748 
0749     LBRACE try/recover(statements=innerStatementList) RBRACE
0750   | IF LPAREN ifExpr=expr RPAREN
0751       (   COLON statements=innerStatementList newElseifList newElseSingle ENDIF semicolonOrCloseTag
0752         | ifStatement=statement elseifList=elseifList elseSingle=elseSingle
0753       )
0754   | WHILE LPAREN whileExpr=expr RPAREN whileStatement=whileStatement
0755   | FOR LPAREN forExpr1=forExpr SEMICOLON forExpr2=forExpr
0756     SEMICOLON forExpr3=forExpr RPAREN forStatement=forStatement
0757   | SWITCH LPAREN swtichExpr=expr RPAREN switchCaseList=switchCaseList
0758 
0759   | FOREACH LPAREN (
0760             -- allow $var as &$i and not expr() as &$i
0761         try/rollback(foreachVar=variable AS foreachVarAsVar=foreachVariable)
0762         catch(foreachExpr=expr AS foreachExprAsVar=variableIdentifier))
0763         (DOUBLE_ARROW foreachVariable=foreachVariable | 0) RPAREN
0764         foreachStatement=foreachStatement
0765   | DECLARE LPAREN declareItem=declareItem @ COMMA RPAREN declareStatement
0766   | SEMICOLON     -- empty statement
0767   | TRY  LBRACE try/recover(statements=innerStatementList) RBRACE
0768     #catches=catchItem*
0769   | UNSET LPAREN #unsetVariables=variable @ COMMA RPAREN semicolonOrCloseTag
0770   -- fix first/follow with goto target
0771   | ( ?[: LA(1).kind != Token_STRING || LA(2).kind != Token_COLON :] expr=expr semicolonOrCloseTag )
0772   | DO doStatement=statement WHILE LPAREN whileExpr=expr RPAREN semicolonOrCloseTag
0773   | BREAK (breakExpr=expr | 0) semicolonOrCloseTag
0774   | CONTINUE (continueExpr=expr | 0) semicolonOrCloseTag
0775   | RETURN (returnExpr=expr | 0) semicolonOrCloseTag
0776   | GLOBAL #globalVars=globalVar @ COMMA semicolonOrCloseTag
0777   | STATIC #staticVars=staticVar @ COMMA semicolonOrCloseTag
0778   | ECHO #echoExprs=expr @ COMMA semicolonOrCloseTag
0779   | THROW throwExpr=expr semicolonOrCloseTag
0780   -- throws error in zend parser, so ignored | USE use_filename  semicolonOrCloseTag
0781 
0782   | CLOSE_TAG
0783   | OPEN_TAG
0784   | OPEN_TAG_WITH_ECHO expr=expr semicolonOrCloseTag
0785   | INLINE_HTML
0786   | CONST #consts=constantDeclaration @ COMMA SEMICOLON
0787   | USE #useNamespace=useNamespace @ COMMA SEMICOLON
0788   | GOTO gotoLabel=STRING SEMICOLON
0789   | gotoTarget=STRING COLON
0790 -> statement ;;
0791 
0792     identifier=namespacedIdentifier (AS aliasIdentifier=identifier | 0)
0793 -> useNamespace ;;
0794 
0795     identifier=identifier ASSIGN scalar=staticScalar
0796 -> constantDeclaration ;;
0797 
0798    SEMICOLON | CLOSE_TAG
0799 -> semicolonOrCloseTag ;;
0800 
0801     LBRACE (SEMICOLON | 0) try/recover(caseList=caseList) RBRACE
0802   | COLON (SEMICOLON | 0) caseList=caseList ENDSWITCH semicolonOrCloseTag
0803 -> switchCaseList ;;
0804 
0805     #caseItems=case_item*
0806 -> caseList ;;
0807 
0808     CASE expr=expr (COLON | SEMICOLON) statements=innerStatementList
0809   | def=DEFAULT (COLON | SEMICOLON) statements=innerStatementList
0810 -> case_item ;;
0811 
0812     CATCH LPAREN catchClass=identifier var=variableIdentifier RPAREN
0813     LBRACE try/recover(statements=innerStatementList) RBRACE
0814 -> catchItem ;;
0815 
0816     statement=statement
0817   | COLON statements=innerStatementList ENDDECLARE semicolonOrCloseTag
0818 -> declareStatement ;;
0819 
0820     STRING ASSIGN scalar=staticScalar
0821 -> declareItem ;;
0822 
0823     (BIT_AND | 0) variable=variableIdentifier
0824 -> foreachVariable ;;
0825 
0826     statement=statement
0827   | COLON statements=innerStatementList ENDFOREACH semicolonOrCloseTag
0828 -> foreachStatement ;;
0829 
0830   var=variableIdentifier (ASSIGN value=staticScalar | 0)
0831 -> staticVar ;;
0832 
0833     var=variableIdentifier
0834   | DOLLAR (dollarVar=variable | LBRACE expr=expr RBRACE)
0835 -> globalVar ;;
0836 
0837     #exprs=expr @ COMMA | 0
0838 -> forExpr ;;
0839 
0840     statement=statement
0841   | COLON statements=innerStatementList ENDFOR semicolonOrCloseTag
0842 -> forStatement ;;
0843 
0844     statement=statement
0845   | COLON statements=innerStatementList ENDWHILE semicolonOrCloseTag
0846 -> whileStatement ;;
0847 
0848     --first/follow conflict; todo check if this is a problem
0849     #elseifListItem=elseifListItem*
0850 -> elseifList ;;
0851 
0852     ELSEIF LPAREN expr=expr RPAREN statement=statement
0853 -> elseifListItem ;;
0854 
0855     ELSE statement=statement | 0
0856 -> elseSingle ;;
0857 
0858     #newElseifListItem=newelseifListItem*
0859 -> newElseifList ;;
0860 
0861     ELSEIF LPAREN expr=expr RPAREN COLON statements=innerStatementList
0862 -> newelseifListItem ;;
0863 
0864     ELSE COLON statements=innerStatementList | 0
0865 -> newElseSingle ;;
0866 
0867 --TODO     --resolve STRING vs. staticMember conflict
0868 --     ?[: LA(2).kind != Token_PAAMAYIM_NEKUDOTAYIM :]
0869     identifier=namespacedIdentifier
0870   | dynamicClassNameReference=dynamicClassNameReference
0871 -> classNameReference ;;
0872 
0873     baseVariable=baseVariable (OBJECT_OPERATOR objectProperty=objectProperty
0874                           properties=dynamicClassNameVariableProperties | 0)
0875 -> dynamicClassNameReference ;;
0876 
0877     #properties=dynamicClassNameVariableProperty*
0878 -> dynamicClassNameVariableProperties ;;
0879 
0880     OBJECT_OPERATOR property=objectProperty
0881 -> dynamicClassNameVariableProperty ;;
0882 
0883     objectDimList=objectDimList
0884   | variableWithoutObjects=variableWithoutObjects
0885 -> objectProperty ;;
0886 
0887     variableName=variableName #offsetItems=dimListItem*
0888 -> objectDimList ;;
0889 
0890   variable=compoundVariableWithSimpleIndirectReference #offsetItems=dimListItem*
0891 -> variableWithoutObjects ;;
0892 
0893 LBRACKET dimOffset=dimOffset RBRACKET | LBRACE expr=expr RBRACE
0894 -> dimListItem ;;
0895 
0896     name=identifier
0897   | LBRACE expr=expr RBRACE
0898 -> variableName ;;
0899 
0900     commonScalar=commonScalar
0901   | constantOrClassConst=constantOrClassConst
0902   | varname=STRING_VARNAME
0903   | DOUBLE_QUOTE encapsList=encapsList DOUBLE_QUOTE
0904   | [: tokenStream->setRuleSet(TokenStream::State_heredoc); :] START_HEREDOC encapsList=encapsList [: tokenStream->setRuleSet(TokenStream::State_php); :] END_HEREDOC
0905 -> scalar ;;
0906 
0907   constant=namespacedIdentifier
0908   ( PAAMAYIM_NEKUDOTAYIM classConstant=identifier | 0 )
0909 -> constantOrClassConst ;;
0910 
0911     #encaps=encaps*
0912 -> encapsList ;;
0913 
0914     var=encapsVar | value=ENCAPSED_AND_WHITESPACE
0915 -> encaps ;;
0916 
0917     -- first/first conflict resolved by LA(2)
0918     --(expr allows STRING_VARNAME too - but without [expr])
0919     (
0920         [: 
0921         TokenStream::RuleSet lastRuleSet = tokenStream->ruleSet();
0922         tokenStream->setRuleSet(TokenStream::State_php);
0923         :]
0924         DOLLAR_OPEN_CURLY_BRACES ( ?[: LA(2).kind == Token_LBRACKET:] STRING_VARNAME LBRACKET expr=expr RBRACKET
0925       | expr=expr ) [: tokenStream->setRuleSet(lastRuleSet); :] RBRACE
0926   | variable=variableIdentifier (OBJECT_OPERATOR propertyIdentifier=identifier | LBRACKET offset=encapsVarOffset RBRACKET | 0)
0927   | CURLY_OPEN expr=expr RBRACE)
0928 -> encapsVar ;;
0929 
0930     STRING
0931   | NUM_STRING
0932   | variableIdentifier
0933 -> encapsVarOffset ;;
0934 
0935 
0936     LNUMBER                  [: (*yynode)->scalarType = ScalarTypeInt; :]
0937   | DNUMBER                  [: (*yynode)->scalarType = ScalarTypeFloat; :]
0938   | string=CONSTANT_ENCAPSED_STRING [: (*yynode)->scalarType = ScalarTypeString; :]
0939   | LINE                     [: (*yynode)->scalarType = ScalarTypeInt; :]
0940   | FILE                     [: (*yynode)->scalarType = ScalarTypeString; :]
0941   | CLASS_C                  [: (*yynode)->scalarType = ScalarTypeString; :]
0942   | METHOD_C                 [: (*yynode)->scalarType = ScalarTypeString; :]
0943   | FUNC_C                   [: (*yynode)->scalarType = ScalarTypeString; :]
0944   | NAMESPACE_C              [: (*yynode)->scalarType = ScalarTypeString; :]
0945   | START_NOWDOC STRING END_NOWDOC [: (*yynode)->scalarType = ScalarTypeString; :]
0946 -> commonScalar [
0947      member variable scalarType: ScalarTypes;
0948 ] ;;
0949 
0950     FUNCTION (BIT_AND | 0) functionName=identifier
0951     LPAREN parameters=parameterList RPAREN LBRACE try/recover(functionBody=innerStatementList) RBRACE
0952 -> functionDeclarationStatement ;;
0953 
0954     (#parameters=parameter @ COMMA) | 0
0955 -> parameterList ;;
0956 
0957 (parameterType=namespacedIdentifier | arrayType=ARRAY | 0) (isRef=BIT_AND | 0)
0958     variable=variableIdentifier (ASSIGN defaultValue=staticScalar | 0)
0959 -> parameter ;;
0960 
0961     value=commonScalar
0962   | constantOrClassConst=constantOrClassConst
0963   | PLUS plusValue=staticScalar
0964   | MINUS minusValue=staticScalar
0965   | array=ARRAY LPAREN
0966         (#arrayValues=staticArrayPairValue
0967              -- break because array(1,) is allowed
0968           @ (COMMA [: if (yytoken == Token_RPAREN) { break; } :] ) | 0)
0969     RPAREN
0970 -> staticScalar ;;
0971 
0972     #val1=staticScalar (DOUBLE_ARROW #val2=staticScalar | 0)
0973 -> staticArrayPairValue ;;
0974 
0975    (isGlobal=BACKSLASH | 0)
0976    #namespaceName=identifier+ @ BACKSLASH
0977 -> namespacedIdentifier ;;
0978 
0979      string=STRING
0980 -> identifier ;;
0981 
0982      variable=VARIABLE
0983 -> variableIdentifier ;;
0984 
0985     NAMESPACE #namespaceName=identifier* @ BACKSLASH
0986     (
0987         -- the semicolon case needs at least one namespace identifier, the {...} case not...
0988         SEMICOLON [: if (!(*yynode)->namespaceNameSequence) { reportProblem(Error, "Missing namespace identifier.", -2); } :]
0989     | LBRACE try/recover(body=innerStatementList) RBRACE )
0990 -> namespaceDeclarationStatement ;;
0991 
0992     INTERFACE interfaceName=identifier (EXTENDS extends=classImplements | 0)
0993     LBRACE try/recover(body=classBody) RBRACE
0994 -> interfaceDeclarationStatement ;;
0995 
0996     modifier=optionalClassModifier CLASS className=identifier
0997         (EXTENDS extends=classExtends | 0)
0998         (IMPLEMENTS implements=classImplements | 0)
0999     LBRACE body=classBody RBRACE
1000 -> classDeclarationStatement ;;
1001 
1002 identifier=namespacedIdentifier
1003 -> classExtends ;;
1004 
1005 #implements=namespacedIdentifier @ COMMA
1006 -> classImplements ;;
1007 
1008 -- error recovery, to understand it you probably have to look at the generated code ;-)
1009 [: bool reported = false; while ( true ) { :]
1010 try/recover(#classStatements=classStatement)*
1011 [: if (yytoken != Token_RBRACE && yytoken != Token_EOF && yytoken != Token_CLOSE_TAG) {
1012         if (!reported) {
1013             reportProblem(Error, "Unexpected token in class context.");
1014             reported = true;
1015         }
1016         yylex();
1017    } else {
1018         break;
1019    }
1020 } :]
1021  RBRACE [: rewind(tokenStream->index() - 2); :]
1022 -> classBody ;;
1023 
1024     CONST #consts=constantDeclaration @ COMMA SEMICOLON
1025   | VAR variable=classVariableDeclaration SEMICOLON
1026   | modifiers=optionalModifiers
1027     ( variable=classVariableDeclaration SEMICOLON
1028       | FUNCTION (BIT_AND | 0) methodName=identifier LPAREN parameters=parameterList RPAREN
1029         methodBody=methodBody
1030     )
1031 -> classStatement ;;
1032 
1033     SEMICOLON -- abstract method
1034  |  LBRACE try/recover(statements=innerStatementList) RBRACE
1035 -> methodBody ;;
1036 
1037 #vars=classVariable @ COMMA
1038 -> classVariableDeclaration ;;
1039 
1040     variable=variableIdentifier (ASSIGN value=staticScalar | 0)
1041 -> classVariable ;;
1042 
1043   (
1044     PUBLIC     [: (*yynode)->modifiers |= ModifierPublic;      :]
1045   | PROTECTED  [: (*yynode)->modifiers |= ModifierProtected;      :]
1046   | PRIVATE    [: (*yynode)->modifiers |= ModifierPrivate;      :]
1047   | STATIC     [: (*yynode)->modifiers |= ModifierStatic;      :]
1048   | ABSTRACT   [: (*yynode)->modifiers |= ModifierAbstract;      :]
1049   | FINAL      [: (*yynode)->modifiers |= ModifierFinal;      :]
1050   | 0
1051   )*
1052 -> optionalModifiers[
1053      member variable modifiers: unsigned int;
1054 ] ;;
1055 
1056   (
1057     ABSTRACT   [: (*yynode)->modifier = AbstractClass; :]
1058   | FINAL      [: (*yynode)->modifier = FinalClass;    :]
1059   | 0
1060   )
1061 -> optionalClassModifier[
1062      member variable modifier: ClassModifier;
1063 ] ;;
1064 
1065 
1066 
1067 
1068 
1069 -----------------------------------------------------------------
1070 -- Code segments copied to the implementation (.cpp) file.
1071 -- If existent, kdevelop-pg's current syntax requires this block
1072 -- to occur at the end of the file.
1073 -----------------------------------------------------------------
1074 
1075 [:
1076 
1077 #include <QDebug>
1078 
1079 namespace Php
1080 {
1081 
1082 QString Parser::tokenText(qint64 begin, qint64 end)
1083 {
1084     return m_contents.mid(begin,end-begin+1);
1085 }
1086 
1087 
1088 void Parser::reportProblem( Parser::ProblemType type, const QString& message, int offset )
1089 {
1090     if (type == Error)
1091         qDebug() << "** ERROR:" << message;
1092     else if (type == Warning)
1093         qDebug() << "** WARNING:" << message;
1094     else if (type == Info)
1095         qDebug() << "** Info:" << message;
1096 }
1097 
1098 
1099 // custom error recovery
1100 void Parser::expectedToken(int /*expected*/, qint64 /*where*/, const QString& name)
1101 {
1102     reportProblem( Parser::Error, QString("Expected token \"%1\"").arg(name));
1103 }
1104 
1105 void Parser::expectedSymbol(int /*expectedSymbol*/, const QString& name)
1106 {
1107     qint64 line;
1108     qint64 col;
1109     qint64 index = tokenStream->index()-1;
1110     Token &token = tokenStream->at(index);
1111     qDebug() << "token starts at:" << token.begin;
1112     qDebug() << "index is:" << index;
1113     tokenStream->startPosition(index, &line, &col);
1114     QString tokenValue = tokenText(token.begin, token.end);
1115     qint64 eLine;
1116     qint64 eCol;
1117     tokenStream->endPosition(index, &eLine, &eCol);
1118     reportProblem( Parser::Error,
1119                    QString("Expected symbol \"%1\" (current token: \"%2\" [%3] at %4:%5 - %6:%7)")
1120                   .arg(name)
1121                   .arg(token.kind != 0 ? tokenValue : "EOF")
1122                   .arg(token.kind)
1123                   .arg(line)
1124                   .arg(col)
1125                   .arg(eLine)
1126                   .arg(eCol));
1127 }
1128 
1129 void Parser::setDebug( bool debug )
1130 {
1131     m_debug = debug;
1132 }
1133 
1134 Parser::ParserState *Parser::copyCurrentState()
1135 {
1136     ParserState *state = new ParserState();
1137     state->varExpressionState = m_state.varExpressionState;
1138     state->varExpressionIsVariable = m_state.varExpressionIsVariable;
1139     return state;
1140 }
1141 
1142 void Parser::restoreState( Parser::ParserState* state)
1143 {
1144     m_state.varExpressionState = state->varExpressionState;
1145     m_state.varExpressionIsVariable = state->varExpressionIsVariable;
1146 }
1147 
1148 } // end of namespace Php
1149 
1150 :]
1151 
1152 -- kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on; auto-insert-doxygen on; mode KDevelop-PG[-Qt]
1153