| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.php.editor.parser; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java_cup.runtime.*; |
| import org.netbeans.modules.php.editor.parser.astnodes.*; |
| import org.netbeans.modules.web.common.api.ByteStack; |
| |
| @org.netbeans.api.annotations.common.SuppressWarnings({"SF_SWITCH_FALLTHROUGH", "URF_UNREAD_FIELD", "DLS_DEAD_LOCAL_STORE", "DM_DEFAULT_ENCODING", "EI_EXPOSE_REP2", "UUF_UNUSED_FIELD"}) |
| %% |
| // Options adn declarations section |
| |
| %class ASTPHP5Scanner |
| %implements Scanner |
| %type Symbol |
| %function next_token |
| %public |
| |
| %eofval{ |
| return createSymbol(ASTPHP5Symbols.EOF); |
| %eofval} |
| %eofclose |
| |
| %unicode |
| %caseless |
| |
| //Turns character counting on |
| %char |
| //Turns line counting on |
| %line |
| //Turns column counting on |
| %column |
| |
| |
| %state ST_IN_SCRIPTING |
| %state ST_DOUBLE_QUOTES |
| %state ST_BACKQUOTE |
| %state ST_HEREDOC |
| %state ST_START_HEREDOC |
| %state ST_END_HEREDOC |
| %state ST_NOWDOC |
| %state ST_START_NOWDOC |
| %state ST_END_NOWDOC |
| %state ST_LOOKING_FOR_PROPERTY |
| %state ST_LOOKING_FOR_VARNAME |
| %state ST_VAR_OFFSET |
| %state ST_COMMENT |
| %state ST_DOCBLOCK |
| %state ST_ONE_LINE_COMMENT |
| %state ST_IN_SHORT_ECHO |
| %state ST_HALTED_COMPILER |
| %{ |
| private final List commentList = new ArrayList(); |
| private String heredoc = null; |
| private int heredocBodyStart = -1; |
| private int heredocBodyLength = 0; |
| private final StringBuilder heredocBody = new StringBuilder(); |
| private String nowdoc = null; |
| private int nowdoc_len = 0; |
| private int nowdocBodyStart = -1; |
| private int nowdocBodyLength = 0; |
| private final StringBuilder nowdocBody = new StringBuilder(); |
| private String comment = null; |
| private boolean asp_tags = false; |
| private boolean short_tags_allowed = true; |
| private ByteStack stack = new ByteStack(); |
| private char yy_old_buffer[] = new char[ZZ_BUFFERSIZE]; |
| private int yy_old_pushbackPos; |
| protected int commentStartPosition; |
| private int whitespaceEndPosition; |
| private boolean isEndedPhp; |
| private final PHPDocCommentParser docParser = new PHPDocCommentParser(); |
| private final PHPVarCommentParser varParser = new PHPVarCommentParser(); |
| |
| public ASTPHP5Scanner(java.io.Reader in, boolean short_tags_allowed, boolean asp_tags_allowed) { |
| this(in); |
| this.asp_tags = asp_tags_allowed; |
| this.short_tags_allowed = short_tags_allowed; |
| } |
| //private AST ast; |
| |
| private int bracket = 0; |
| |
| /** |
| * Returns balance beween '{' and '}'. If it's equesl 0, |
| * then number of '{' == number of '}', if > 0 then '{' > '}' and |
| * if return number < 0 then '{' < '}' |
| */ |
| public int getCurlyBalance() { |
| return bracket; |
| } |
| |
| public int getWhitespaceEndPosition() { |
| return whitespaceEndPosition; |
| } |
| |
| public boolean isEndedPhp() { |
| return isEndedPhp; |
| } |
| |
| public boolean useAspTagsAsPhp() { |
| return asp_tags; |
| } |
| |
| public void reset(java.io.Reader reader) { |
| yyreset(reader); |
| } |
| |
| public void setState(int state) { |
| yybegin(state); |
| } |
| |
| public int getState() { |
| return yystate(); |
| } |
| |
| public void setInScriptingState() { |
| yybegin(ST_IN_SCRIPTING); |
| } |
| |
| public void resetCommentList() { |
| commentList.clear(); |
| } |
| |
| public List getCommentList() { |
| return commentList; |
| } |
| |
| protected void addComment(Comment.Type type) { |
| int leftPosition = getTokenStartPosition(); |
| //System.out.println("#####AddCommnet start: " + commentStartPosition + " end: " + (leftPosition + getTokenLength()) + ", type: " + type); |
| Comment comm; |
| if (type == Comment.Type.TYPE_PHPDOC) { |
| comm = docParser.parse(commentStartPosition, leftPosition + getTokenLength(), comment); |
| comment = null; |
| } |
| else if(type == Comment.Type.TYPE_VARTYPE) { |
| comm = varParser.parse(commentStartPosition, leftPosition + getTokenLength(), comment); |
| comment = null; |
| if (comm == null) { |
| comm = new Comment(commentStartPosition, leftPosition + getTokenLength(), /*ast,*/ type); |
| } |
| } |
| else { |
| comm = new Comment(commentStartPosition, leftPosition + getTokenLength(), /*ast,*/ type); |
| } |
| commentList.add(comm); |
| } |
| |
| public void setUseAspTagsAsPhp(boolean useAspTagsAsPhp) { |
| asp_tags = useAspTagsAsPhp; |
| } |
| |
| private void pushState(int state) { |
| stack.push(zzLexicalState); |
| yybegin(state); |
| } |
| |
| private void popState() { |
| yybegin(stack.pop()); |
| } |
| |
| public int getCurrentLine() { |
| return yyline; |
| } |
| |
| protected int getTokenStartPosition() { |
| return zzStartRead - zzPushbackPos; |
| } |
| |
| protected int getTokenLength() { |
| return zzMarkedPos - zzStartRead; |
| } |
| |
| public int getLength() { |
| return zzEndRead - zzPushbackPos; |
| } |
| |
| private void handleCommentStart() { |
| commentStartPosition = getTokenStartPosition(); |
| } |
| |
| private void handleLineCommentEnd() { |
| addComment(Comment.Type.TYPE_SINGLE_LINE); |
| } |
| |
| private void handleMultilineCommentEnd() { |
| addComment(Comment.Type.TYPE_MULTILINE); |
| } |
| |
| private void handlePHPDocEnd() { |
| addComment(Comment.Type.TYPE_PHPDOC); |
| } |
| |
| private void handleVarComment() { |
| commentStartPosition = getTokenStartPosition(); |
| addComment(Comment.Type.TYPE_VARTYPE); |
| } |
| |
| private Symbol createFullSymbol(int symbolNumber) { |
| Symbol symbol = createSymbol(symbolNumber); |
| symbol.value = yytext(); |
| return symbol; |
| } |
| |
| private Symbol createSymbol(int symbolNumber) { |
| int leftPosition = getTokenStartPosition(); |
| Symbol symbol = new Symbol(symbolNumber, leftPosition, leftPosition + getTokenLength()); |
| return symbol; |
| } |
| |
| private void updateNowdocBodyInfo() { |
| if (nowdocBodyStart == -1) { |
| nowdocBodyStart = getTokenStartPosition(); |
| } |
| nowdocBody.append(yytext()); |
| nowdocBodyLength += getTokenLength(); |
| } |
| |
| private Symbol createFullNowdocBodySymbol() { |
| Symbol symbol = new Symbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE, nowdocBodyStart, nowdocBodyStart + nowdocBodyLength); |
| symbol.value = nowdocBody.toString(); |
| return symbol; |
| } |
| |
| private void updateHeredocBodyInfo() { |
| if (heredocBodyStart == -1) { |
| heredocBodyStart = getTokenStartPosition(); |
| } |
| heredocBody.append(yytext()); |
| heredocBodyLength += getTokenLength(); |
| } |
| |
| private void resetHeredocBodyInfo() { |
| heredocBodyStart = -1; |
| heredocBodyLength = 0; |
| heredocBody.delete(0, heredocBody.length()); |
| } |
| |
| private Symbol createFullHeredocBodySymbol() { |
| Symbol symbol = new Symbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE, heredocBodyStart, heredocBodyStart + heredocBodyLength); |
| symbol.value = heredocBody.toString(); |
| resetHeredocBodyInfo(); |
| return symbol; |
| } |
| |
| private boolean isLabelChar(char c) { |
| return c == '_' |
| || (c >= 'a' && c <= 'z') |
| || (c >= 'A' && c <= 'Z') |
| || (c >= 0x7f && c <= 0xff); |
| } |
| |
| private boolean isEndHereOrNowdoc(String hereOrNowdoc) { |
| // check whether ID exists |
| String trimedText = yytext().trim(); |
| boolean isEnd = false; |
| if (trimedText.startsWith(hereOrNowdoc)) { |
| if (trimedText.length() == hereOrNowdoc.length()) { |
| isEnd = true; |
| } else if (trimedText.length() > hereOrNowdoc.length() |
| && !isLabelChar(trimedText.charAt(hereOrNowdoc.length()))) { |
| // e.g. |
| // $test = <<< END |
| // ENDING |
| // END |
| isEnd = true; |
| } |
| } |
| return isEnd; |
| } |
| |
| public int[] getParamenters(){ |
| return new int[]{zzMarkedPos, zzPushbackPos, zzCurrentPos, zzStartRead, zzEndRead, yyline}; |
| } |
| |
| private boolean parsePHPDoc(){ |
| /*final IDocumentorLexer documentorLexer = getDocumentorLexer(zzReader); |
| if(documentorLexer == null){ |
| return false; |
| } |
| yypushback(zzMarkedPos - zzStartRead); |
| int[] parameters = getParamenters(); |
| documentorLexer.reset(zzReader, zzBuffer, parameters); |
| Object phpDocBlock = documentorLexer.parse(); |
| commentList.add(phpDocBlock); |
| reset(zzReader, documentorLexer.getBuffer(), documentorLexer.getParamenters());*/ |
| |
| //System.out.println("#######ParsePHPDoc()"); |
| //return true; |
| return false; |
| } |
| |
| |
| /*protected IDocumentorLexer getDocumentorLexer(java.io.Reader reader) { |
| return null; |
| }*/ |
| |
| public void reset(java.io.Reader reader, char[] buffer, int[] parameters){ |
| this.zzReader = reader; |
| this.zzBuffer = buffer; |
| this.zzMarkedPos = parameters[0]; |
| this.zzPushbackPos = parameters[1]; |
| this.zzCurrentPos = parameters[2]; |
| this.zzStartRead = parameters[3]; |
| this.zzEndRead = parameters[4]; |
| this.yyline = parameters[5]; |
| this.yychar = this.zzStartRead - this.zzPushbackPos; |
| } |
| |
| %} |
| |
| LNUM=[0-9]+(_[0-9]+)* |
| DNUM=({LNUM}?[\.]{LNUM})|({LNUM}[\.]{LNUM}?) |
| EXPONENT_DNUM=(({LNUM}|{DNUM})[eE][+-]?{LNUM}) |
| HNUM="0x"[0-9a-fA-F]+(_[0-9a-fA-F]+)* |
| BNUM="0b"[01]+(_[01]+)* |
| //LABEL=[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* |
| LABEL=([[:letter:]_]|[\u007f-\u00ff])([[:letter:][:digit:]_]|[\u007f-\u00ff])* |
| NAMESPACE_SEPARATOR=[\\] |
| QUALIFIED_LABEL=({NAMESPACE_SEPARATOR}?{LABEL})+ |
| WHITESPACE=[ \n\r\t]+ |
| TABS_AND_SPACES=[ \t]* |
| ANY_CHAR=[^] |
| NEWLINE=("\r"|"\n"|"\r\n") |
| DOUBLE_QUOTES_LITERAL_DOLLAR=("$"+([^a-zA-Z_\x7f-\xff$\"\\{]|("\\"{ANY_CHAR}))) |
| BACKQUOTE_LITERAL_DOLLAR=("$"+([^a-zA-Z_\x7f-\xff$`\\{]|("\\"{ANY_CHAR}))) |
| HEREDOC_LITERAL_DOLLAR=("$"+([^a-zA-Z_\x7f-\xff$\n\r\\{]|("\\"[^\n\r]))) |
| HEREDOC_CURLY_OR_ESCAPE_OR_DOLLAR=(("{"+[^$\n\r\\{])|("{"*"\\"[^\n\r])|{HEREDOC_LITERAL_DOLLAR}) |
| HEREDOC_NON_LABEL=([^a-zA-Z_\x7f-\xff$\n\r\\{]|{HEREDOC_CURLY_OR_ESCAPE_OR_DOLLAR}) |
| HEREDOC_LABEL_NO_NEWLINE=({LABEL}([^a-zA-Z0-9_\x7f-\xff;$\n\r\\{]|(";"[^$\n\r\\{])|(";"?{HEREDOC_CURLY_OR_ESCAPE_OR_DOLLAR}))) |
| DOUBLE_QUOTES_CHARS=("{"*([^$\"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLLAR}) |
| BACKQUOTE_CHARS=("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR}) |
| HEREDOC_CHARS=([^$\\{]|("\\"{ANY_CHAR}))({HEREDOC_LABEL_NO_NEWLINE} | {HEREDOC_NON_LABEL} | {LABEL})* |
| NOWDOC_CHARS=({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+))) |
| |
| %% |
| |
| <ST_IN_SHORT_ECHO>"=" { |
| yybegin(ST_IN_SCRIPTING); |
| return createSymbol(ASTPHP5Symbols.T_ECHO); |
| } |
| |
| <ST_IN_SCRIPTING>"exit" { |
| return createFullSymbol(ASTPHP5Symbols.T_EXIT); |
| } |
| |
| <ST_IN_SCRIPTING>"die" { |
| return createFullSymbol(ASTPHP5Symbols.T_EXIT); |
| } |
| |
| <ST_IN_SCRIPTING>"fn" { |
| // PHP 7.4 Arrow Functions 2.0 |
| // https://wiki.php.net/rfc/arrow_functions_v2 |
| return createFullSymbol(ASTPHP5Symbols.T_FN); |
| } |
| |
| <ST_IN_SCRIPTING>"function" { |
| return createFullSymbol(ASTPHP5Symbols.T_FUNCTION); |
| } |
| |
| <ST_IN_SCRIPTING>"const" { |
| return createFullSymbol(ASTPHP5Symbols.T_CONST); |
| } |
| |
| <ST_IN_SCRIPTING>"return" { |
| return createFullSymbol(ASTPHP5Symbols.T_RETURN); |
| } |
| |
| <ST_IN_SCRIPTING>"yield"{WHITESPACE}+"from" { |
| return createSymbol(ASTPHP5Symbols.T_YIELD_FROM); |
| } |
| |
| <ST_IN_SCRIPTING>"yield" { |
| return createFullSymbol(ASTPHP5Symbols.T_YIELD); |
| } |
| |
| <ST_IN_SCRIPTING>"try" { |
| return createFullSymbol(ASTPHP5Symbols.T_TRY); |
| } |
| |
| <ST_IN_SCRIPTING>"catch" { |
| return createFullSymbol(ASTPHP5Symbols.T_CATCH); |
| } |
| |
| <ST_IN_SCRIPTING>"throw" { |
| return createFullSymbol(ASTPHP5Symbols.T_THROW); |
| } |
| |
| <ST_IN_SCRIPTING>"finally" { |
| return createFullSymbol(ASTPHP5Symbols.T_FINALLY); |
| } |
| |
| <ST_IN_SCRIPTING>"if" { |
| return createFullSymbol(ASTPHP5Symbols.T_IF); |
| } |
| |
| <ST_IN_SCRIPTING>"elseif" { |
| return createFullSymbol(ASTPHP5Symbols.T_ELSEIF); |
| } |
| |
| <ST_IN_SCRIPTING>"endif" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDIF); |
| } |
| |
| <ST_IN_SCRIPTING>"else" { |
| return createFullSymbol(ASTPHP5Symbols.T_ELSE); |
| } |
| |
| <ST_IN_SCRIPTING>"while" { |
| return createFullSymbol(ASTPHP5Symbols.T_WHILE); |
| } |
| |
| <ST_IN_SCRIPTING>"endwhile" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDWHILE); |
| } |
| |
| <ST_IN_SCRIPTING>"do" { |
| return createFullSymbol(ASTPHP5Symbols.T_DO); |
| } |
| |
| <ST_IN_SCRIPTING>"for" { |
| return createFullSymbol(ASTPHP5Symbols.T_FOR); |
| } |
| |
| <ST_IN_SCRIPTING>"endfor" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDFOR); |
| } |
| |
| <ST_IN_SCRIPTING>"foreach" { |
| return createFullSymbol(ASTPHP5Symbols.T_FOREACH); |
| } |
| |
| <ST_IN_SCRIPTING>"endforeach" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDFOREACH); |
| } |
| |
| <ST_IN_SCRIPTING>"declare" { |
| return createFullSymbol(ASTPHP5Symbols.T_DECLARE); |
| } |
| |
| <ST_IN_SCRIPTING>"enddeclare" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDDECLARE); |
| } |
| |
| <ST_IN_SCRIPTING>"instanceof" { |
| return createFullSymbol(ASTPHP5Symbols.T_INSTANCEOF); |
| } |
| |
| <ST_IN_SCRIPTING>"insteadof" { |
| return createFullSymbol(ASTPHP5Symbols.T_INSTEADOF); |
| } |
| |
| <ST_IN_SCRIPTING>"as" { |
| return createFullSymbol(ASTPHP5Symbols.T_AS); |
| } |
| |
| <ST_IN_SCRIPTING>"switch" { |
| return createFullSymbol(ASTPHP5Symbols.T_SWITCH); |
| } |
| |
| <ST_IN_SCRIPTING>"endswitch" { |
| return createFullSymbol(ASTPHP5Symbols.T_ENDSWITCH); |
| } |
| |
| <ST_IN_SCRIPTING>"case" { |
| return createFullSymbol(ASTPHP5Symbols.T_CASE); |
| } |
| |
| <ST_IN_SCRIPTING>"default" { |
| return createFullSymbol(ASTPHP5Symbols.T_DEFAULT); |
| } |
| |
| <ST_IN_SCRIPTING>"break" { |
| return createFullSymbol(ASTPHP5Symbols.T_BREAK); |
| } |
| |
| <ST_IN_SCRIPTING>"continue" { |
| return createFullSymbol(ASTPHP5Symbols.T_CONTINUE); |
| } |
| |
| <ST_IN_SCRIPTING>"goto" { |
| return createFullSymbol(ASTPHP5Symbols.T_GOTO); |
| } |
| |
| <ST_IN_SCRIPTING>"echo" { |
| return createFullSymbol(ASTPHP5Symbols.T_ECHO); |
| } |
| |
| <ST_IN_SCRIPTING>"print" { |
| return createFullSymbol(ASTPHP5Symbols.T_PRINT); |
| } |
| |
| <ST_IN_SCRIPTING>"class" { |
| return createFullSymbol(ASTPHP5Symbols.T_CLASS); |
| } |
| |
| <ST_IN_SCRIPTING>"trait" { |
| return createFullSymbol(ASTPHP5Symbols.T_TRAIT); |
| } |
| |
| <ST_IN_SCRIPTING>"interface" { |
| return createFullSymbol(ASTPHP5Symbols.T_INTERFACE); |
| } |
| |
| <ST_IN_SCRIPTING>"extends" { |
| return createFullSymbol(ASTPHP5Symbols.T_EXTENDS); |
| } |
| |
| <ST_IN_SCRIPTING>"implements" { |
| return createFullSymbol(ASTPHP5Symbols.T_IMPLEMENTS); |
| } |
| |
| <ST_IN_SCRIPTING>"->" { |
| pushState(ST_LOOKING_FOR_PROPERTY); |
| return createSymbol(ASTPHP5Symbols.T_OBJECT_OPERATOR); |
| } |
| |
| <ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ { |
| whitespaceEndPosition = getTokenStartPosition() + yylength(); |
| } |
| |
| <ST_LOOKING_FOR_PROPERTY>"->" { |
| return createSymbol(ASTPHP5Symbols.T_OBJECT_OPERATOR); |
| } |
| |
| <ST_LOOKING_FOR_PROPERTY>{LABEL} { |
| popState(); |
| return createFullSymbol(ASTPHP5Symbols.T_STRING); |
| } |
| |
| <ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} { |
| yypushback(yylength()); |
| popState(); |
| } |
| |
| <ST_IN_SCRIPTING>"::" { |
| return createSymbol(ASTPHP5Symbols.T_PAAMAYIM_NEKUDOTAYIM); |
| } |
| |
| <ST_IN_SCRIPTING>"\\" { |
| return createSymbol(ASTPHP5Symbols.T_NS_SEPARATOR); |
| } |
| |
| <ST_IN_SCRIPTING>"new" { |
| return createFullSymbol(ASTPHP5Symbols.T_NEW); |
| } |
| |
| <ST_IN_SCRIPTING>"clone" { |
| return createFullSymbol(ASTPHP5Symbols.T_CLONE); |
| } |
| |
| <ST_IN_SCRIPTING>"var" { |
| return createFullSymbol(ASTPHP5Symbols.T_VAR); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_INT_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_DOUBLE_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"string"{TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_STRING_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"binary"{TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_STRING_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_ARRAY_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_OBJECT_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_BOOL_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" { |
| return createSymbol(ASTPHP5Symbols.T_UNSET_CAST); |
| } |
| |
| <ST_IN_SCRIPTING>"eval" { |
| return createFullSymbol(ASTPHP5Symbols.T_EVAL); |
| } |
| |
| <ST_IN_SCRIPTING>"include" { |
| return createFullSymbol(ASTPHP5Symbols.T_INCLUDE); |
| } |
| |
| <ST_IN_SCRIPTING>"include_once" { |
| return createFullSymbol(ASTPHP5Symbols.T_INCLUDE_ONCE); |
| } |
| |
| <ST_IN_SCRIPTING>"require" { |
| return createFullSymbol(ASTPHP5Symbols.T_REQUIRE); |
| } |
| |
| <ST_IN_SCRIPTING>"require_once" { |
| return createFullSymbol(ASTPHP5Symbols.T_REQUIRE_ONCE); |
| } |
| |
| <ST_IN_SCRIPTING>"namespace" { |
| return createFullSymbol(ASTPHP5Symbols.T_NAMESPACE); |
| } |
| |
| <ST_IN_SCRIPTING>"use" { |
| return createFullSymbol(ASTPHP5Symbols.T_USE); |
| } |
| |
| <ST_IN_SCRIPTING>"global" { |
| return createFullSymbol(ASTPHP5Symbols.T_GLOBAL); |
| } |
| |
| <ST_IN_SCRIPTING>"isset" { |
| return createFullSymbol(ASTPHP5Symbols.T_ISSET); |
| } |
| |
| <ST_IN_SCRIPTING>"empty" { |
| return createFullSymbol(ASTPHP5Symbols.T_EMPTY); |
| } |
| |
| <ST_IN_SCRIPTING>"__halt_compiler();" { |
| yybegin(ST_HALTED_COMPILER); |
| return createSymbol(ASTPHP5Symbols.T_HALT_COMPILER); |
| } |
| |
| <ST_HALTED_COMPILER> {ANY_CHAR}+ { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| |
| <ST_IN_SCRIPTING>"static" { |
| return createFullSymbol(ASTPHP5Symbols.T_STATIC); |
| } |
| |
| <ST_IN_SCRIPTING>"abstract" { |
| return createFullSymbol(ASTPHP5Symbols.T_ABSTRACT); |
| } |
| |
| <ST_IN_SCRIPTING>"final" { |
| return createFullSymbol(ASTPHP5Symbols.T_FINAL); |
| } |
| |
| <ST_IN_SCRIPTING>"private" { |
| return createFullSymbol(ASTPHP5Symbols.T_PRIVATE); |
| } |
| |
| <ST_IN_SCRIPTING>"protected" { |
| return createFullSymbol(ASTPHP5Symbols.T_PROTECTED); |
| } |
| |
| <ST_IN_SCRIPTING>"public" { |
| return createFullSymbol(ASTPHP5Symbols.T_PUBLIC); |
| } |
| |
| <ST_IN_SCRIPTING>"unset" { |
| return createFullSymbol(ASTPHP5Symbols.T_UNSET); |
| } |
| |
| <ST_IN_SCRIPTING>"=>" { |
| return createSymbol(ASTPHP5Symbols.T_DOUBLE_ARROW); |
| } |
| |
| <ST_IN_SCRIPTING>"list" { |
| return createFullSymbol(ASTPHP5Symbols.T_LIST); |
| } |
| |
| <ST_IN_SCRIPTING>"array" { |
| return createFullSymbol(ASTPHP5Symbols.T_ARRAY); |
| } |
| |
| <ST_IN_SCRIPTING>"callable" { |
| return createFullSymbol(ASTPHP5Symbols.T_CALLABLE); |
| } |
| |
| <ST_IN_SCRIPTING>"++" { |
| return createSymbol(ASTPHP5Symbols.T_INC); |
| } |
| |
| <ST_IN_SCRIPTING>"--" { |
| return createSymbol(ASTPHP5Symbols.T_DEC); |
| } |
| |
| <ST_IN_SCRIPTING>"===" { |
| return createSymbol(ASTPHP5Symbols.T_IS_IDENTICAL); |
| } |
| |
| <ST_IN_SCRIPTING>"!==" { |
| return createSymbol(ASTPHP5Symbols.T_IS_NOT_IDENTICAL); |
| } |
| |
| <ST_IN_SCRIPTING>"==" { |
| return createSymbol(ASTPHP5Symbols.T_IS_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"!="|"<>" { |
| return createSymbol(ASTPHP5Symbols.T_IS_NOT_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"<=" { |
| return createSymbol(ASTPHP5Symbols.T_IS_SMALLER_OR_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>">=" { |
| return createSymbol(ASTPHP5Symbols.T_IS_GREATER_OR_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"<=>" { |
| return createSymbol(ASTPHP5Symbols.T_SPACESHIP); |
| } |
| |
| <ST_IN_SCRIPTING>"+=" { |
| return createSymbol(ASTPHP5Symbols.T_PLUS_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"-=" { |
| return createSymbol(ASTPHP5Symbols.T_MINUS_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"*=" { |
| return createSymbol(ASTPHP5Symbols.T_MUL_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"/=" { |
| return createSymbol(ASTPHP5Symbols.T_DIV_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>".=" { |
| return createSymbol(ASTPHP5Symbols.T_CONCAT_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"%=" { |
| return createSymbol(ASTPHP5Symbols.T_MOD_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"<<=" { |
| return createSymbol(ASTPHP5Symbols.T_SL_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>">>=" { |
| return createSymbol(ASTPHP5Symbols.T_SR_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"&=" { |
| return createSymbol(ASTPHP5Symbols.T_AND_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"|=" { |
| return createSymbol(ASTPHP5Symbols.T_OR_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"^=" { |
| return createSymbol(ASTPHP5Symbols.T_XOR_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"||" { |
| return createSymbol(ASTPHP5Symbols.T_BOOLEAN_OR); |
| } |
| |
| <ST_IN_SCRIPTING>"&&" { |
| return createSymbol(ASTPHP5Symbols.T_BOOLEAN_AND); |
| } |
| |
| <ST_IN_SCRIPTING>"OR" { |
| return createFullSymbol(ASTPHP5Symbols.T_LOGICAL_OR); |
| } |
| |
| <ST_IN_SCRIPTING>"AND" { |
| return createFullSymbol(ASTPHP5Symbols.T_LOGICAL_AND); |
| } |
| |
| <ST_IN_SCRIPTING>"XOR" { |
| return createFullSymbol(ASTPHP5Symbols.T_LOGICAL_XOR); |
| } |
| |
| <ST_IN_SCRIPTING>"<<" { |
| return createSymbol(ASTPHP5Symbols.T_SL); |
| } |
| |
| <ST_IN_SCRIPTING>">>" { |
| return createSymbol(ASTPHP5Symbols.T_SR); |
| } |
| |
| <ST_IN_SCRIPTING>"**" { |
| return createSymbol(ASTPHP5Symbols.T_POW); |
| } |
| |
| <ST_IN_SCRIPTING>"**=" { |
| return createSymbol(ASTPHP5Symbols.T_POW_EQUAL); |
| } |
| |
| <ST_IN_SCRIPTING>"..." { |
| return createSymbol(ASTPHP5Symbols.T_ELLIPSIS); |
| } |
| |
| <ST_IN_SCRIPTING>"??" { |
| return createSymbol(ASTPHP5Symbols.T_COALESCE); |
| } |
| |
| <ST_IN_SCRIPTING>"??=" { |
| return createSymbol(ASTPHP5Symbols.T_COALESCE_EQUAL); |
| } |
| |
| // TOKENS |
| <ST_IN_SCRIPTING> { |
| ";" {return createSymbol(ASTPHP5Symbols.T_SEMICOLON);} |
| ":" {return createSymbol(ASTPHP5Symbols.T_NEKUDOTAIM);} |
| "," {return createSymbol(ASTPHP5Symbols.T_COMMA);} |
| "." {return createSymbol(ASTPHP5Symbols.T_NEKUDA);} |
| "[" {return createSymbol(ASTPHP5Symbols.T_OPEN_RECT);} |
| "]" {return createSymbol(ASTPHP5Symbols.T_CLOSE_RECT);} |
| "(" {return createSymbol(ASTPHP5Symbols.T_OPEN_PARENTHESE);} |
| ")" {return createSymbol(ASTPHP5Symbols.T_CLOSE_PARENTHESE);} |
| "|" {return createSymbol(ASTPHP5Symbols.T_OR);} |
| "^" {return createSymbol(ASTPHP5Symbols.T_KOVA);} |
| "&" {return createSymbol(ASTPHP5Symbols.T_REFERENCE);} |
| "+" {return createSymbol(ASTPHP5Symbols.T_PLUS);} |
| "-" {return createSymbol(ASTPHP5Symbols.T_MINUS);} |
| "/" {return createSymbol(ASTPHP5Symbols.T_DIV);} |
| "*" {return createSymbol(ASTPHP5Symbols.T_TIMES);} |
| "=" {return createSymbol(ASTPHP5Symbols.T_EQUAL);} |
| "%" {return createSymbol(ASTPHP5Symbols.T_PRECENT);} |
| "!" {return createSymbol(ASTPHP5Symbols.T_NOT);} |
| "~" {return createSymbol(ASTPHP5Symbols.T_TILDA);} |
| "$" {return createSymbol(ASTPHP5Symbols.T_DOLLAR);} |
| "<" {return createSymbol(ASTPHP5Symbols.T_RGREATER);} |
| ">" {return createSymbol(ASTPHP5Symbols.T_LGREATER);} |
| "?" {return createSymbol(ASTPHP5Symbols.T_QUESTION_MARK);} |
| "@" {return createSymbol(ASTPHP5Symbols.T_AT);} |
| } |
| |
| <ST_IN_SCRIPTING>"{" { |
| pushState(ST_IN_SCRIPTING); |
| bracket++; |
| return createSymbol(ASTPHP5Symbols.T_CURLY_OPEN); |
| |
| } |
| |
| <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"${" { |
| pushState(ST_LOOKING_FOR_VARNAME); |
| return createSymbol(ASTPHP5Symbols.T_DOLLAR_OPEN_CURLY_BRACES); |
| } |
| |
| <ST_IN_SCRIPTING>"}" { |
| /* This is a temporary fix which is dependant on flex and it's implementation */ |
| if (!stack.isEmpty()) { |
| popState(); |
| } |
| bracket--; |
| return createSymbol(ASTPHP5Symbols.T_CURLY_CLOSE); |
| } |
| |
| <ST_LOOKING_FOR_VARNAME>{LABEL} { |
| popState(); |
| pushState(ST_IN_SCRIPTING); |
| return createFullSymbol(ASTPHP5Symbols.T_STRING_VARNAME); |
| } |
| |
| <ST_LOOKING_FOR_VARNAME>{ANY_CHAR} { |
| yypushback(yylength()); |
| popState(); |
| pushState(ST_IN_SCRIPTING); |
| } |
| |
| <ST_IN_SCRIPTING>{LNUM} { |
| return createFullSymbol(ASTPHP5Symbols.T_LNUMBER); |
| } |
| |
| <ST_IN_SCRIPTING>{HNUM} { |
| return createFullSymbol(ASTPHP5Symbols.T_DNUMBER); |
| } |
| |
| <ST_IN_SCRIPTING>{BNUM} { |
| return createFullSymbol(ASTPHP5Symbols.T_DNUMBER); |
| } |
| |
| <ST_VAR_OFFSET>0|([1-9][0-9]*) { |
| return createFullSymbol(ASTPHP5Symbols.T_NUM_STRING); |
| } |
| |
| <ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* treat numbers (almost) as strings inside encapsulated strings */ |
| return createFullSymbol(ASTPHP5Symbols.T_NUM_STRING); |
| } |
| |
| <ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} { |
| return createFullSymbol(ASTPHP5Symbols.T_DNUMBER); |
| } |
| |
| <ST_IN_SCRIPTING>"__CLASS__" { |
| return createFullSymbol(ASTPHP5Symbols.T_CLASS_C); |
| } |
| |
| <ST_IN_SCRIPTING>"__TRAIT__" { |
| return createFullSymbol(ASTPHP5Symbols.T_TRAIT_C); |
| } |
| |
| <ST_IN_SCRIPTING>"__FUNCTION__" { |
| return createFullSymbol(ASTPHP5Symbols.T_FUNC_C); |
| } |
| |
| <ST_IN_SCRIPTING>"__METHOD__" { |
| return createFullSymbol(ASTPHP5Symbols.T_METHOD_C); |
| } |
| |
| <ST_IN_SCRIPTING>"__LINE__" { |
| return createFullSymbol(ASTPHP5Symbols.T_LINE); |
| } |
| |
| <ST_IN_SCRIPTING>"__FILE__" { |
| return createFullSymbol(ASTPHP5Symbols.T_FILE); |
| } |
| |
| <ST_IN_SCRIPTING>"__DIR__" { |
| return createFullSymbol(ASTPHP5Symbols.T_DIR); |
| } |
| |
| <ST_IN_SCRIPTING>"__NAMESPACE__" { |
| return createFullSymbol(ASTPHP5Symbols.T_NS_C); |
| } |
| |
| <YYINITIAL>(([^<]|"<"[^?%s<])+)|"<s"|"<" { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| |
| <YYINITIAL>"<?"|"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"\'php\'"){WHITESPACE}*">" { |
| if (short_tags_allowed || yylength()>2) { /* yyleng>2 means it's not <? but <script> */ |
| yybegin(ST_IN_SCRIPTING); |
| //return T_OPEN_TAG; |
| //return createSymbol(ASTPHP5Symbols.T_OPEN_TAG); |
| } else { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| } |
| |
| <YYINITIAL>"<%="|"<?=" { |
| String text = yytext(); |
| if ((text.charAt(1)=='%' && asp_tags) |
| || (text.charAt(1)=='?')) { |
| yypushback(1); |
| yybegin(ST_IN_SHORT_ECHO); |
| } else { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| } |
| |
| <YYINITIAL>"<%" { |
| if (asp_tags) { |
| yybegin(ST_IN_SCRIPTING); |
| //return T_OPEN_TAG; |
| //return createSymbol(ASTPHP5Symbols.T_OPEN_TAG); |
| } else { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| } |
| |
| <YYINITIAL>"<?php"([ \t]|{NEWLINE}) { |
| isEndedPhp = false; |
| whitespaceEndPosition = getTokenStartPosition() + yylength(); |
| yybegin(ST_IN_SCRIPTING); |
| //return T_OPEN_TAG; |
| //return createSymbol(ASTPHP5Symbols.T_OPEN_TAG); |
| } |
| |
| <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} { |
| return createFullSymbol(ASTPHP5Symbols.T_VARIABLE); |
| } |
| |
| <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"->"[a-zA-Z_\x7f-\xff] { |
| yypushback(3); |
| pushState(ST_LOOKING_FOR_PROPERTY); |
| return createFullSymbol(ASTPHP5Symbols.T_VARIABLE); |
| } |
| |
| <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"[" { |
| yypushback(1); |
| pushState(ST_VAR_OFFSET); |
| return createFullSymbol(ASTPHP5Symbols.T_VARIABLE); |
| } |
| |
| <ST_VAR_OFFSET>"]" { |
| popState(); |
| return createSymbol(ASTPHP5Symbols.T_CLOSE_RECT); |
| } |
| |
| //this is instead {TOKENS}|[{}"`] |
| <ST_VAR_OFFSET> { |
| ";" {return createSymbol(ASTPHP5Symbols.T_SEMICOLON);} |
| ":" {return createSymbol(ASTPHP5Symbols.T_NEKUDOTAIM);} |
| "," {return createSymbol(ASTPHP5Symbols.T_COMMA);} |
| "." {return createSymbol(ASTPHP5Symbols.T_NEKUDA);} |
| "[" {return createSymbol(ASTPHP5Symbols.T_OPEN_RECT);} |
| // "]" {return createSymbol(ASTPHP5Symbols.T_CLOSE_RECT);} //we dont need this line because the rule before deals with it |
| "(" {return createSymbol(ASTPHP5Symbols.T_OPEN_PARENTHESE);} |
| ")" {return createSymbol(ASTPHP5Symbols.T_CLOSE_PARENTHESE);} |
| "|" {return createSymbol(ASTPHP5Symbols.T_OR);} |
| "^" {return createSymbol(ASTPHP5Symbols.T_KOVA);} |
| "&" {return createSymbol(ASTPHP5Symbols.T_REFERENCE);} |
| "+" {return createSymbol(ASTPHP5Symbols.T_PLUS);} |
| "-" {return createSymbol(ASTPHP5Symbols.T_MINUS);} |
| "/" {return createSymbol(ASTPHP5Symbols.T_DIV);} |
| "*" {return createSymbol(ASTPHP5Symbols.T_TIMES);} |
| "=" {return createSymbol(ASTPHP5Symbols.T_EQUAL);} |
| "%" {return createSymbol(ASTPHP5Symbols.T_PRECENT);} |
| "!" {return createSymbol(ASTPHP5Symbols.T_NOT);} |
| "~" {return createSymbol(ASTPHP5Symbols.T_TILDA);} |
| "$" {return createSymbol(ASTPHP5Symbols.T_DOLLAR);} |
| "<" {return createSymbol(ASTPHP5Symbols.T_RGREATER);} |
| ">" {return createSymbol(ASTPHP5Symbols.T_LGREATER);} |
| "?" {return createSymbol(ASTPHP5Symbols.T_QUESTION_MARK);} |
| "@" {return createSymbol(ASTPHP5Symbols.T_AT);} |
| "{" {bracket++; return createSymbol(ASTPHP5Symbols.T_CURLY_OPEN);} |
| "}" {bracket--; return createSymbol(ASTPHP5Symbols.T_CURLY_CLOSE);} |
| "\"" {return createSymbol(ASTPHP5Symbols.T_QUATE);} |
| "`" {return createSymbol(ASTPHP5Symbols.T_BACKQUATE);} |
| } |
| |
| <ST_VAR_OFFSET>[ \n\r\t\\'#] { |
| yypushback(1); |
| popState(); |
| /*<ST_VAR_OFFSET>[ \n\r\t\\'#]*/ |
| return createSymbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE); |
| } |
| |
| <ST_IN_SCRIPTING>"define" { |
| /* not a keyword, hust for recognize constans.*/ |
| return createFullSymbol(ASTPHP5Symbols.T_DEFINE); |
| } |
| |
| <ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} { |
| return createFullSymbol(ASTPHP5Symbols.T_STRING); |
| } |
| |
| <ST_IN_SCRIPTING>"#"|"//" { |
| handleCommentStart(); |
| yybegin(ST_ONE_LINE_COMMENT); |
| // yymore(); |
| } |
| |
| <ST_ONE_LINE_COMMENT>"?"|"%"|">" { |
| // yymore(); |
| } |
| |
| <ST_ONE_LINE_COMMENT>[^\n\r?%>]*(.|{NEWLINE}) { |
| String yytext = yytext(); |
| switch (yytext.charAt(yytext.length() - 1)) { |
| case '?': |
| case '%': |
| case '>': |
| yypushback(1); |
| break; |
| default: |
| handleLineCommentEnd(); |
| yybegin(ST_IN_SCRIPTING); |
| } |
| // yymore(); |
| } |
| |
| <ST_ONE_LINE_COMMENT>"?>"|"%>" { |
| if (asp_tags || yytext().charAt(0)!='%') { /* asp comment? */ |
| isEndedPhp = true; |
| handleLineCommentEnd(); |
| yypushback(yylength()); |
| yybegin(ST_IN_SCRIPTING); |
| //return T_COMMENT; |
| } |
| } |
| |
| <ST_IN_SCRIPTING>"/*"{WHITESPACE}*"@var"{WHITESPACE}("$"?){LABEL}("["({LABEL} | "\"" | "'")*"]")*{WHITESPACE}{QUALIFIED_LABEL}("[""]")*([|]{QUALIFIED_LABEL}("[""]")*)*{WHITESPACE}?"*/" { |
| comment = yytext(); |
| handleVarComment(); |
| // if we want to handle the var comment in ast, then return the T_VAR_Comment symbol |
| // but it needs some changes in parser grammar. see issue #154967 |
| //return createFullSymbol(ASTPHP5Symbols.T_VAR_COMMENT); |
| } |
| |
| <ST_IN_SCRIPTING>"/**"{WHITESPACE}*"@var"{WHITESPACE}{QUALIFIED_LABEL}("[""]")*([|]{QUALIFIED_LABEL}("[""]")*)*{WHITESPACE}("$"){LABEL}("["({LABEL} | "\"" | "'")*"]")*{WHITESPACE}?[^\n\r]*"*/" { |
| comment = yytext(); |
| handleVarComment(); |
| } |
| |
| <ST_IN_SCRIPTING>"/**" { |
| if (!parsePHPDoc()) { |
| handleCommentStart(); |
| yybegin(ST_DOCBLOCK); |
| } |
| } |
| |
| <ST_DOCBLOCK>"*/" { |
| handlePHPDocEnd(); |
| yybegin(ST_IN_SCRIPTING); |
| } |
| |
| <ST_DOCBLOCK>~"*/" { |
| int len = yylength(); |
| yypushback(2); // go back to mark end of comment in the next token |
| comment = yytext(); |
| } |
| |
| <ST_DOCBLOCK> <<EOF>> { |
| if (yytext().length() > 0) { |
| yypushback(1); // backup eof |
| comment = yytext(); |
| } |
| else { |
| return createSymbol(ASTPHP5Symbols.EOF); |
| } |
| |
| } |
| |
| <ST_IN_SCRIPTING>"/**/" { |
| handleCommentStart(); |
| } |
| |
| <ST_IN_SCRIPTING>"/*" { |
| handleCommentStart(); |
| yybegin(ST_COMMENT); |
| } |
| |
| <ST_COMMENT>[^*]+ { |
| } |
| |
| <ST_COMMENT>"*/" { |
| handleMultilineCommentEnd(); |
| yybegin(ST_IN_SCRIPTING); |
| } |
| |
| <ST_COMMENT>"*" { |
| // yymore(); |
| } |
| |
| <ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? { |
| isEndedPhp = true; |
| yybegin(YYINITIAL); |
| return createSymbol(ASTPHP5Symbols.T_SEMICOLON); /* implicit ';' at php-end tag */ |
| } |
| |
| <ST_IN_SCRIPTING>"%>"{NEWLINE}? { |
| if (asp_tags) { |
| yybegin(YYINITIAL); |
| return createSymbol(ASTPHP5Symbols.T_SEMICOLON); /* implicit ';' at php-end tag */ |
| } else { |
| return createSymbol(ASTPHP5Symbols.T_INLINE_HTML); |
| } |
| } |
| |
| <ST_IN_SCRIPTING>(b?[\"]{DOUBLE_QUOTES_CHARS}*("{"*|"$"*)[\"]) { |
| return createFullSymbol(ASTPHP5Symbols.T_CONSTANT_ENCAPSED_STRING); |
| } |
| |
| <ST_IN_SCRIPTING>(b?[']([^'\\]|("\\"{ANY_CHAR}))*[']) { |
| return createFullSymbol(ASTPHP5Symbols.T_CONSTANT_ENCAPSED_STRING); |
| } |
| |
| <ST_IN_SCRIPTING>b?[\"] { |
| yybegin(ST_DOUBLE_QUOTES); |
| return createSymbol(ASTPHP5Symbols.T_QUATE); |
| } |
| |
| <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} { |
| int bprefix = (yytext().charAt(0) != '<') ? 1 : 0; |
| int startString=3+bprefix; |
| /* 3 is <<<, 2 is quotes, 1 is newline */ |
| nowdoc_len = yylength()-bprefix-3-2-1-(yytext().charAt(yylength()-2)=='\r'?1:0); |
| while ((yytext().charAt(startString) == ' ') || (yytext().charAt(startString) == '\t')) { |
| startString++; |
| nowdoc_len--; |
| } |
| // first quate |
| startString++; |
| nowdoc = yytext().substring(startString,nowdoc_len+startString); |
| yybegin(ST_START_NOWDOC); |
| return createSymbol(ASTPHP5Symbols.T_START_NOWDOC); |
| } |
| |
| <ST_START_NOWDOC>{ANY_CHAR} { |
| yypushback(1); |
| yybegin(ST_NOWDOC); |
| } |
| |
| <ST_START_NOWDOC>{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\r\n]? { |
| /* <ST_START_NOWDOC>{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\r\n]? */ |
| // there is no [\r\n] if it is the last line |
| // i.e. not [\r\n] but EOF, so check not [\r\n] but [\r\n]? |
| if (isEndHereOrNowdoc(nowdoc)) { |
| int indexOfNowdocId = yytext().indexOf(nowdoc); |
| int back = yylength() - indexOfNowdocId - nowdoc.length(); |
| yypushback(back); |
| nowdoc = null; |
| nowdoc_len = 0; |
| nowdocBody.delete(0, nowdocBody.length()); |
| nowdocBodyStart = -1; |
| nowdocBodyLength = 0; |
| yybegin(ST_IN_SCRIPTING); |
| return createSymbol(ASTPHP5Symbols.T_END_NOWDOC); |
| } else { |
| yypushback(1); // [\r\n] length |
| yybegin(ST_NOWDOC); |
| updateNowdocBodyInfo(); |
| } |
| } |
| |
| |
| <ST_NOWDOC> { |
| {NEWLINE}{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\r\n]? { |
| /* <ST_NOWDOC>{NEWLINE}{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\r\n]? */ |
| if (isEndHereOrNowdoc(nowdoc)) { |
| String yytext = yytext(); |
| int newlineLength = yytext.startsWith("\r\n") ? 2 : 1; |
| int back = yylength() - newlineLength; |
| yypushback(back); |
| updateNowdocBodyInfo(); |
| yybegin(ST_END_NOWDOC); |
| if (nowdocBodyLength > 0) { |
| return createFullNowdocBodySymbol(); |
| } |
| } else { |
| yypushback(1); |
| updateNowdocBodyInfo(); |
| } |
| } |
| |
| {NOWDOC_CHARS}|{NEWLINE} { |
| /* <ST_NOWDOC>{NOWDOC_CHARS}|{NEWLINE} */ |
| updateNowdocBodyInfo(); |
| } |
| } |
| |
| <ST_END_NOWDOC>{TABS_AND_SPACES}{LABEL}";"? { |
| /* <ST_END_NOWDOC>{LABEL}";"?[\n\r] */ |
| nowdoc=null; |
| nowdoc_len=0; |
| nowdocBody.delete(0, nowdocBody.length()); |
| nowdocBodyStart = -1; |
| nowdocBodyLength = 0; |
| yybegin(ST_IN_SCRIPTING); |
| int back = 0; |
| if (yytext().charAt(yylength() - 1)==';') { |
| back++; |
| } |
| yypushback(back); |
| return createSymbol(ASTPHP5Symbols.T_END_NOWDOC); |
| } |
| |
| <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|"\""{LABEL}"\""){NEWLINE} { |
| int removeChars = (yytext().charAt(0) == 'b')?4:3; |
| heredoc = yytext().substring(removeChars).trim(); // for 'b<<<' or '<<<' |
| if (heredoc.charAt(0) == '"') { |
| heredoc = heredoc.substring(1, heredoc.length()-1); |
| } |
| yybegin(ST_START_HEREDOC); |
| return createSymbol(ASTPHP5Symbols.T_START_HEREDOC); |
| } |
| |
| <ST_IN_SCRIPTING>[`] { |
| yybegin(ST_BACKQUOTE); |
| return createSymbol(ASTPHP5Symbols.T_BACKQUATE); |
| } |
| |
| <ST_START_HEREDOC>{ANY_CHAR} { |
| yypushback(1); |
| yybegin(ST_HEREDOC); |
| } |
| |
| <ST_START_HEREDOC>{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\n\r]? { |
| /* <ST_START_HEREDOC>{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\n\r]? */ |
| int trailingNewLineLength = 1; |
| int labelLength = yylength() - trailingNewLineLength; |
| int back = trailingNewLineLength; |
| String yytext = yytext(); |
| |
| if (yytext.charAt(labelLength - 1) == ';') { |
| labelLength--; |
| back++; |
| } |
| |
| if (isEndHereOrNowdoc(heredoc)) { |
| int indexOfHeredocId = yytext().indexOf(heredoc); |
| back += labelLength - indexOfHeredocId; |
| yypushback(back); |
| yybegin(ST_END_HEREDOC); |
| } else { |
| yypushback(yylength()); |
| yybegin(ST_HEREDOC); |
| } |
| } |
| |
| <ST_HEREDOC> { |
| {NEWLINE}{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\n\r]? { |
| /* {NEWLINE}{TABS_AND_SPACES}{LABEL}";"?[^\n\r]*[\n\r]? */ |
| int trailingNewLineLength = 1; |
| int labelLength = yylength() - trailingNewLineLength; |
| int back = trailingNewLineLength; |
| |
| if (yytext().charAt(labelLength-1) == ';') { |
| labelLength--; |
| back++; |
| } |
| |
| if (isEndHereOrNowdoc(heredoc)) { |
| int indexOfHeredocId = yytext().indexOf(heredoc); |
| back += labelLength - indexOfHeredocId; |
| yypushback(back); |
| yybegin(ST_END_HEREDOC); |
| } else { |
| // handle variable |
| char previousChar = ' '; |
| int indexOfVariable = -1; |
| for (int i = 0; i < yylength(); i++) { |
| char currentChar = yytext().charAt(i); |
| if (currentChar == '$' && previousChar == '{') { |
| indexOfVariable = i - 1; |
| break; |
| } |
| if (currentChar == '$' && previousChar != '\\') { |
| indexOfVariable = i; |
| break; |
| } |
| previousChar = currentChar; |
| } |
| |
| if (indexOfVariable == -1) { |
| yypushback(trailingNewLineLength); |
| } else { |
| yypushback(yylength() - indexOfVariable); |
| updateHeredocBodyInfo(); |
| return createFullHeredocBodySymbol(); |
| } |
| } |
| updateHeredocBodyInfo(); |
| if (yystate() == ST_END_HEREDOC) { |
| return createFullHeredocBodySymbol(); |
| } |
| } |
| |
| {HEREDOC_CHARS} { |
| /* <ST_HEREDOC> {HEREDOC_CHARS} */ |
| int indexOfNewline = yytext().indexOf("\r"); |
| if (indexOfNewline == -1) { |
| indexOfNewline = yytext().indexOf("\n"); |
| } |
| if (indexOfNewline > 0) { |
| // if index equals 0, don't pushback (infinite loop) |
| yypushback(yylength() - indexOfNewline); |
| } |
| updateHeredocBodyInfo(); |
| } |
| |
| {HEREDOC_CHARS}("{$" | "${") { |
| /* <ST_HEREDOC> {HEREDOC_CHARS}("{$" | "${") */ |
| yypushback(2); |
| updateHeredocBodyInfo(); |
| return createFullHeredocBodySymbol(); |
| } |
| |
| {HEREDOC_CHARS}"$"{LABEL}"["? { |
| /* <ST_HEREDOC> {HEREDOC_CHARS}"$"{LABEL}"["? */ |
| String text = yytext(); |
| int lastIndexOfDollar = text.lastIndexOf('$'); |
| yypushback(text.length() - lastIndexOfDollar); |
| updateHeredocBodyInfo(); |
| return createFullHeredocBodySymbol(); |
| } |
| |
| "$" | "{" { |
| /* <ST_HEREDOC> "$" | "{" */ |
| updateHeredocBodyInfo(); |
| } |
| } |
| |
| <ST_END_HEREDOC>{TABS_AND_SPACES}{LABEL}";"? { |
| /* <ST_END_HEREDOC>{TABS_AND_SPACES}{LABEL}";"? */ |
| heredoc=null; |
| resetHeredocBodyInfo(); |
| yybegin(ST_IN_SCRIPTING); |
| int back = 0; |
| // mark just the label |
| if (yytext().charAt(yylength() - 1)==';') { |
| back++; |
| } |
| yypushback(back); |
| return createSymbol(ASTPHP5Symbols.T_END_HEREDOC); |
| } |
| |
| <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"{$" { |
| pushState(ST_IN_SCRIPTING); |
| yypushback(yylength()-1); |
| bracket++; |
| return createSymbol(ASTPHP5Symbols.T_CURLY_OPEN_WITH_DOLAR); |
| } |
| |
| <ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}+ { |
| /*<ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}+*/ |
| return createFullSymbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE); |
| } |
| |
| /* |
| The original parsing rule was {DOUBLE_QUOTES_CHARS}*("{"{2,}|"$"{2,}|(("{"+|"$"+)[\"])) |
| but jflex doesn't support a{n,} so we changed a{2,} to aa+ |
| */ |
| <ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}*("{""{"+|"$""$"+|(("{"+|"$"+)[\"])) { |
| yypushback(1); |
| /*<ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}*("{""{"+|"$""$"+|(("{"+|"$"+)[\"]))*/ |
| return createFullSymbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE); |
| } |
| |
| <ST_BACKQUOTE>{BACKQUOTE_CHARS}+ { |
| /*<ST_BACKQUOTE>{BACKQUOTE_CHARS}+*/ |
| return createFullSymbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE); |
| } |
| |
| /* |
| The original parsing rule was {BACKQUOTE_CHARS}*("{"{2,}|"$"{2,}|(("{"+|"$"+)[`])) |
| but jflex doesn't support a{n,} so we changed a{2,} to aa+ |
| */ |
| <ST_BACKQUOTE>{BACKQUOTE_CHARS}*("{""{"+|"$""$"+|(("{"+|"$"+)[`])) { |
| yypushback(1); |
| /*<ST_BACKQUOTE>{BACKQUOTE_CHARS}*("{""{"+|"$""$"+|(("{"+|"$"+)[`]))*/ |
| return createFullSymbol(ASTPHP5Symbols.T_ENCAPSED_AND_WHITESPACE); |
| } |
| |
| <ST_DOUBLE_QUOTES>[\"] { |
| yybegin(ST_IN_SCRIPTING); |
| return createSymbol(ASTPHP5Symbols.T_QUATE); |
| } |
| |
| <ST_BACKQUOTE>[`] { |
| yybegin(ST_IN_SCRIPTING); |
| return createSymbol(ASTPHP5Symbols.T_BACKQUATE); |
| } |
| |
| <ST_IN_SCRIPTING,YYINITIAL,ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC,ST_START_HEREDOC,ST_END_HEREDOC, ST_NOWDOC,ST_START_NOWDOC,ST_END_NOWDOC,ST_VAR_OFFSET, ST_DOCBLOCK>{ANY_CHAR} { |
| // do nothing |
| } |