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