summaryrefslogtreecommitdiff
path: root/Zend/zend-scanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend-scanner.l')
-rw-r--r--Zend/zend-scanner.l1195
1 files changed, 1195 insertions, 0 deletions
diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l
new file mode 100644
index 0000000000..03131240d9
--- /dev/null
+++ b/Zend/zend-scanner.l
@@ -0,0 +1,1195 @@
+%{
+
+/*
+ +----------------------------------------------------------------------+
+ | Zend Engine |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
+ +----------------------------------------------------------------------+
+ | This source file is subject to the Zend license, that is bundled |
+ | with this package in the file LICENSE. If you did not receive a |
+ | copy of the Zend license, please mail us at zend@zend.com so we can |
+ | send you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+%}
+
+%x IN_SCRIPTING
+%x DOUBLE_QUOTES
+%x SINGLE_QUOTE
+%x BACKQUOTE
+%x HEREDOC
+%x LOOKING_FOR_PROPERTY
+%option stack
+
+%{
+
+#if WIN32|WINNT
+#include <winsock.h>
+#endif
+
+#include <errno.h>
+
+#include "zend.h"
+#include "zend_alloc.h"
+#include "zend_compile.h"
+#include "zend-scanner.h"
+#include "zend_highlight.h"
+#include "zend_constants.h"
+#include "zend_variables.h"
+#include "zend_operators.h"
+
+#if HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#define YY_DECL int lex_scan(zval *zendlval CLS_DC)
+#define ECHO { ZEND_WRITE( yytext, yyleng ); }
+
+#ifdef __cplusplus
+# define MY_INPUT yyinput
+#else
+# define MY_INPUT input
+#endif
+
+
+#ifndef YY_TLS_VARS
+/* NOTE, YY_TLS_VARS CANNOT have a semicolon after in
+ in the code or it will break compilation in msvc5 */
+#define YY_TLS_VARS
+#endif
+
+#ifndef TLS_VARS /* just to make sure ;) */
+#define TLS_VARS
+#endif
+
+#define HANDLE_NEWLINES(s,l) \
+do { \
+ char *p = (s),*boundary = p+(l); \
+\
+ while(p<boundary) { \
+ if (*p++=='\n') { \
+ CG(zend_lineno)++; \
+ } \
+ } \
+} while(0)
+
+#define HANDLE_NEWLINE(c) \
+{ \
+ if (c=='\n') { \
+ CG(zend_lineno)++; \
+ } \
+}
+
+
+void startup_scanner(CLS_D)
+{
+ CG(heredoc) = NULL;
+ CG(heredoc_len)=0;
+}
+
+
+void shutdown_scanner(CLS_D)
+{
+ if (CG(heredoc)) {
+ efree(CG(heredoc));
+ CG(heredoc_len)=0;
+ }
+}
+
+
+void reset_scanner(CLS_D)
+{
+ YY_TLS_VARS
+
+ BEGIN(INITIAL);
+ CG(zend_lineno)=1;
+}
+
+
+static inline void save_lexical_state(zend_lex_state *lex_state CLS_DC)
+{
+ memcpy(&lex_state->buffer_state,&YY_CURRENT_BUFFER,sizeof(YY_BUFFER_STATE));
+ lex_state->in = yyin;
+ lex_state->lineno = CG(zend_lineno);
+ lex_state->state = YYSTATE;
+ lex_state->filename = zend_get_compiled_filename();
+}
+
+
+static inline void restore_lexical_state(zend_lex_state *lex_state CLS_DC)
+{
+ YY_BUFFER_STATE original_buffer_state = YY_CURRENT_BUFFER;
+
+ if (lex_state->buffer_state) {
+ yy_switch_to_buffer(lex_state->buffer_state);
+ } else {
+ YY_CURRENT_BUFFER = NULL;
+ }
+
+ yy_delete_buffer(original_buffer_state);
+ yyin = lex_state->in;
+ CG(zend_lineno) = lex_state->lineno;
+ BEGIN(lex_state->state);
+ zend_restore_compiled_filename(lex_state->filename);
+}
+
+
+inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
+{
+ FILE *tmp;
+ YY_BUFFER_STATE buffer_state = YY_CURRENT_BUFFER;
+
+ switch (file_handle->type) {
+ case ZEND_HANDLE_FILENAME:
+ tmp = zend_fopen(file_handle->filename);
+ break;
+ case ZEND_HANDLE_FD:
+ tmp = fdopen(file_handle->handle.fd, "r");
+ break;
+ case ZEND_HANDLE_FP:
+ tmp = file_handle->handle.fp;
+ break;
+ }
+ if (!tmp) {
+ return FAILURE;
+ }
+
+ /* Reset the scanner for scanning the new file */
+ yyin = tmp;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ CG(zend_lineno) = 1;
+ BEGIN(INITIAL);
+
+ zend_set_compiled_filename(file_handle->filename);
+ return SUCCESS;
+}
+
+
+zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...)
+{
+ zend_lex_state original_lex_state;
+ zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
+ zend_op_array *original_active_op_array = CG(active_op_array);
+ zend_op_array *retval=NULL;
+ zend_file_handle *file_handle;
+ va_list files;
+ int i;
+
+ va_start(files, file_count);
+
+ init_op_array(op_array, INITIAL_OP_ARRAY_SIZE);
+ save_lexical_state(&original_lex_state CLS_CC);
+
+ for (i=0; i<file_count; i++) {
+ file_handle = va_arg(files, zend_file_handle *);
+ if (!file_handle) {
+ continue;
+ }
+ if (open_file_for_scanning(file_handle CLS_CC)==FAILURE) {
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ destroy_op_array(op_array);
+ efree(op_array);
+ retval = NULL;
+ break;
+ } else {
+ CG(active_op_array) = op_array;
+ if (zendparse(CLS_C)==1) {
+ retval = NULL;
+ break;
+ } else {
+ fclose(yyin);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ CG(active_op_array) = original_active_op_array;
+ retval = op_array;
+ }
+ }
+ }
+ if (retval) {
+ pass_two(op_array);
+ if (mark_as_ref) {
+ pass_include_eval(op_array);
+ }
+ }
+ va_end(files);
+ return retval;
+}
+
+
+zend_op_array *compile_filename(zval *filename CLS_DC)
+{
+ zend_file_handle file_handle;
+ zval tmp;
+ zend_op_array *retval;
+
+ if (filename->type != IS_STRING) {
+ tmp = *filename;
+ zval_copy_ctor(&tmp);
+ convert_to_string(&tmp);
+ filename = &tmp;
+ }
+ file_handle.filename = filename->value.str.val;
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ retval = compile_files(0 CLS_CC, 1, &file_handle);
+ if (filename==&tmp) {
+ zval_dtor(&tmp);
+ }
+ return retval;
+}
+
+
+static inline int prepare_string_for_scanning(zval *str)
+{
+ /* enforce two trailing NULLs for flex... */
+ str->value.str.val = (char *) erealloc(str->value.str.val,str->value.str.len+2);
+ str->value.str.val[str->value.str.len+1]=0;
+
+ yyin=NULL;
+ yy_scan_buffer(str->value.str.val, str->value.str.len+2);
+ return SUCCESS;
+}
+
+
+zend_op_array *compile_string(zval *source_string CLS_DC)
+{
+ zend_lex_state original_lex_state;
+ zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
+ zend_op_array *original_active_op_array = CG(active_op_array);
+ zend_op_array *retval;
+ zval tmp;
+
+ tmp = *source_string;
+ zval_copy_ctor(&tmp);
+ convert_to_string(&tmp);
+ source_string = &tmp;
+
+ init_op_array(op_array, INITIAL_OP_ARRAY_SIZE);
+ save_lexical_state(&original_lex_state CLS_CC);
+ if (prepare_string_for_scanning(source_string)==FAILURE) {
+ destroy_op_array(op_array);
+ efree(op_array);
+ retval = NULL;
+ } else {
+ CG(active_op_array) = op_array;
+ BEGIN(IN_SCRIPTING);
+ if (zendparse(CLS_C)==1) {
+ retval = NULL;
+ } else {
+ pass_two(op_array);
+ pass_include_eval(op_array);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ CG(active_op_array) = original_active_op_array;
+ retval = op_array;
+ }
+ }
+
+ zval_dtor(&tmp);
+
+ return retval;
+}
+
+
+int require_filename(char *filename CLS_DC)
+{
+ zend_file_handle file_handle;
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = filename;
+ return require_file(&file_handle CLS_CC);
+}
+
+
+int require_file(zend_file_handle *file_handle CLS_DC)
+{
+ zend_lex_state original_lex_state;
+
+ save_lexical_state(&original_lex_state CLS_CC);
+ if (open_file_for_scanning(file_handle CLS_CC)==FAILURE) {
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ return FAILURE;
+ }
+ zendparse(CLS_C);
+ fclose(yyin);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ return SUCCESS;
+}
+
+int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini)
+{
+ zend_lex_state original_lex_state;
+ zend_file_handle file_handle;
+ CLS_FETCH();
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = filename;
+ save_lexical_state(&original_lex_state CLS_CC);
+ if (open_file_for_scanning(&file_handle CLS_CC)==FAILURE) {
+ zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename);
+ return FAILURE;
+ }
+ zend_highlight(syntax_highlighter_ini);
+ fclose(yyin);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ return SUCCESS;
+}
+
+
+int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini)
+{
+ zend_lex_state original_lex_state;
+ zval tmp = *str;
+ CLS_FETCH();
+
+ str = &tmp;
+ zval_copy_ctor(str);
+ save_lexical_state(&original_lex_state CLS_CC);
+ if (prepare_string_for_scanning(str)==FAILURE) {
+ return FAILURE;
+ }
+ zend_highlight(syntax_highlighter_ini);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ zval_dtor(str);
+ return SUCCESS;
+}
+
+
+/* redefine YY_INPUT to handle urls for win32*/
+#if 0 /*WIN32|WINNT*/
+#define YY_INPUT(buf,result,max_size) \
+ if ( yyin->_tmpfname != "url" ){ \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ }else{ /* this is a url */ \
+ int recv_char=0,socketd=0; \
+ /*memset(buf,0,max_size);*/ \
+ socketd=yyin->_file; \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ ( (recv_char=recv( socketd,(char *)&c,1,0 ))) >0 && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( recv_char == SOCKET_ERROR ) \
+ YY_FATAL_ERROR( "input from url in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ((result = recv( socketd, (char *)buf, max_size, 0)) == SOCKET_ERROR) \
+ YY_FATAL_ERROR( "input from url read in flex scanner failed" ); \
+ }
+#endif
+
+%}
+
+LNUM [0-9]+
+DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
+EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM})
+HNUM "0x"[0-9a-fA-F]+
+LABEL [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
+WHITESPACE [ \n\r\t]+
+TABS_AND_SPACES [ \t]*
+TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
+ENCAPSED_TOKENS [\[\]{}$]
+ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
+
+%option noyylineno
+%option noyywrap
+%%
+%{
+TLS_VARS;
+%}
+
+<IN_SCRIPTING>"exit" {
+ return T_EXIT;
+}
+
+<IN_SCRIPTING>"die" {
+ return T_EXIT;
+}
+
+<IN_SCRIPTING>"old_function" {
+ return OLD_FUNCTION;
+}
+
+<IN_SCRIPTING>"function"|"cfunction" {
+ return FUNCTION;
+}
+
+<IN_SCRIPTING>"const" {
+ return ZEND_CONST;
+}
+
+<IN_SCRIPTING>"return" {
+ return RETURN;
+}
+
+<IN_SCRIPTING>"if" {
+ return IF;
+}
+
+<IN_SCRIPTING>"elseif" {
+ return ELSEIF;
+}
+
+<IN_SCRIPTING>"endif" {
+ return ENDIF;
+}
+
+<IN_SCRIPTING>"else" {
+ return ELSE;
+}
+
+<IN_SCRIPTING>"while" {
+ return WHILE;
+}
+
+<IN_SCRIPTING>"endwhile" {
+ return ENDWHILE;
+}
+
+<IN_SCRIPTING>"do" {
+ return DO;
+}
+
+<IN_SCRIPTING>"for" {
+ return FOR;
+}
+
+<IN_SCRIPTING>"endfor" {
+ return ENDFOR;
+}
+
+<IN_SCRIPTING>"foreach" {
+ return ZEND_FOREACH;
+}
+
+<IN_SCRIPTING>"endforeach" {
+ return T_ENDFOREACH;
+}
+
+<IN_SCRIPTING>"as" {
+ return ZEND_AS;
+}
+
+<IN_SCRIPTING>"switch" {
+ return SWITCH;
+}
+
+<IN_SCRIPTING>"endswitch" {
+ return ENDSWITCH;
+}
+
+<IN_SCRIPTING>"case" {
+ return CASE;
+}
+
+<IN_SCRIPTING>"default" {
+ return DEFAULT;
+}
+
+<IN_SCRIPTING>"break" {
+ return BREAK;
+}
+
+<IN_SCRIPTING>"continue" {
+ return CONTINUE;
+}
+
+<IN_SCRIPTING>"echo" {
+ return ZEND_ECHO;
+}
+
+<IN_SCRIPTING>"print" {
+ return ZEND_PRINT;
+}
+
+<IN_SCRIPTING>"class" {
+ return CLASS;
+}
+
+<IN_SCRIPTING>"extends" {
+ return EXTENDS;
+}
+
+<IN_SCRIPTING,DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"->" {
+ yy_push_state(LOOKING_FOR_PROPERTY);
+ return ZEND_OBJECT_OPERATOR;
+}
+
+<LOOKING_FOR_PROPERTY>{LABEL} {
+ yy_pop_state();
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return STRING;
+}
+
+<LOOKING_FOR_PROPERTY>. {
+ unput(yytext[0]);
+ yy_pop_state();
+}
+
+<IN_SCRIPTING>"::" {
+ return T_PAAMAYIM_NEKUDOTAYIM;
+}
+
+<IN_SCRIPTING>"new" {
+ return NEW;
+}
+
+<IN_SCRIPTING>"var" {
+ return VAR;
+}
+
+<IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
+ return INT_CAST;
+}
+
+<IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" {
+ return DOUBLE_CAST;
+}
+
+<IN_SCRIPTING>"("{TABS_AND_SPACES}"string"{TABS_AND_SPACES}")" {
+ return STRING_CAST;
+}
+
+<IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" {
+ return ARRAY_CAST;
+}
+
+<IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" {
+ return OBJECT_CAST;
+}
+
+<IN_SCRIPTING>"eval" {
+ return EVAL;
+}
+
+<IN_SCRIPTING>"include" {
+ return INCLUDE;
+}
+
+<IN_SCRIPTING>"require" {
+ return REQUIRE;
+}
+
+<IN_SCRIPTING>"global" {
+ return ZEND_GLOBAL;
+}
+
+<IN_SCRIPTING>"isset" {
+ return T_ISSET;
+}
+
+<IN_SCRIPTING>"empty" {
+ return T_EMPTY;
+}
+
+<IN_SCRIPTING>"static" {
+ return ZEND_STATIC;
+}
+
+<IN_SCRIPTING>"unset" {
+ return ZEND_UNSET;
+}
+
+<IN_SCRIPTING>"=>" {
+ return ZEND_DOUBLE_ARROW;
+}
+
+<IN_SCRIPTING>"list" {
+ return ZEND_LIST;
+}
+
+<IN_SCRIPTING>"array" {
+ return ZEND_ARRAY;
+}
+
+<IN_SCRIPTING>"++" {
+ return INCREMENT;
+}
+
+<IN_SCRIPTING>"--" {
+ return DECREMENT;
+}
+
+<IN_SCRIPTING>"==" {
+ return IS_EQUAL;
+}
+
+<IN_SCRIPTING>"!="|"<>" {
+ return IS_NOT_EQUAL;
+}
+
+<IN_SCRIPTING>"<=" {
+ return IS_SMALLER_OR_EQUAL;
+}
+
+<IN_SCRIPTING>">=" {
+ return IS_GREATER_OR_EQUAL;
+}
+
+<IN_SCRIPTING>"+=" {
+ return PLUS_EQUAL;
+}
+
+<IN_SCRIPTING>"-=" {
+ return MINUS_EQUAL;
+}
+
+<IN_SCRIPTING>"*=" {
+ return MUL_EQUAL;
+}
+
+<IN_SCRIPTING>"/=" {
+ return DIV_EQUAL;
+}
+
+<IN_SCRIPTING>".=" {
+ return CONCAT_EQUAL;
+}
+
+
+<IN_SCRIPTING>"%=" {
+ return MOD_EQUAL;
+}
+
+<IN_SCRIPTING>"<<=" {
+ return SHIFT_LEFT_EQUAL;
+}
+
+<IN_SCRIPTING>">>=" {
+ return SHIFT_RIGHT_EQUAL;
+}
+
+<IN_SCRIPTING>"&=" {
+ return AND_EQUAL;
+}
+
+<IN_SCRIPTING>"|=" {
+ return OR_EQUAL;
+}
+
+<IN_SCRIPTING>"^=" {
+ return XOR_EQUAL;
+}
+
+<IN_SCRIPTING>"||" {
+ return BOOLEAN_OR;
+}
+
+<IN_SCRIPTING>"&&" {
+ return BOOLEAN_AND;
+}
+
+<IN_SCRIPTING>"OR" {
+ return LOGICAL_OR;
+}
+
+<IN_SCRIPTING>"AND" {
+ return LOGICAL_AND;
+}
+
+<IN_SCRIPTING>"XOR" {
+ return LOGICAL_XOR;
+}
+
+<IN_SCRIPTING>"<<" {
+ return SHIFT_LEFT;
+}
+
+<IN_SCRIPTING>">>" {
+ return SHIFT_RIGHT;
+}
+
+<IN_SCRIPTING>{TOKENS} {
+ return yytext[0];
+}
+
+
+<IN_SCRIPTING>"{" {
+ yy_push_state(IN_SCRIPTING);
+ return '{';
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"${" {
+ yy_push_state(IN_SCRIPTING);
+ return DOLLAR_OPEN_CURLY_BRACES;
+}
+
+
+<IN_SCRIPTING>"}" {
+ yy_pop_state();
+ return '}';
+}
+
+
+
+<IN_SCRIPTING>{LNUM}|{HNUM} {
+ errno = 0;
+ zendlval->value.lval = strtol(yytext, NULL, 0);
+ if (errno == ERANGE) { /* overflow */
+ zendlval->value.dval = strtod(yytext,NULL);
+ zendlval->type = IS_DOUBLE;
+ return DNUMBER;
+ } else {
+ zendlval->type = IS_LONG;
+ return LNUMBER;
+ }
+}
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>{LNUM}|{HNUM} { /* treat numbers (almost) as strings inside encapsulated strings */
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return NUM_STRING;
+}
+
+<IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
+ zendlval->value.dval = strtod(yytext,NULL);
+ zendlval->type = IS_DOUBLE;
+ return DNUMBER;
+}
+
+<IN_SCRIPTING>"__LINE__" {
+ zendlval->value.lval = CG(zend_lineno);
+ zendlval->type = IS_LONG;
+ return ZEND_LINE;
+}
+
+<IN_SCRIPTING>"__FILE__" {
+ char *filename = zend_get_compiled_filename();
+
+ zendlval->value.str.len = strlen(filename);
+ zendlval->value.str.val = estrndup(filename,zendlval->value.str.len);
+ zendlval->type = IS_STRING;
+ return ZEND_FILE;
+}
+
+
+<INITIAL>(([^<]|"<"[^?%s<]){1,400})|"<s"|"<" {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext,yyleng);
+ return INLINE_HTML;
+}
+
+<INITIAL>"<?"|"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"\'php\'"){WHITESPACE}*">" {
+ HANDLE_NEWLINES(yytext,yyleng);
+ if (CG(short_tags) || yyleng>2) { /* yyleng>2 means it's not <? but <script> */
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ BEGIN(IN_SCRIPTING);
+ return PHP_OPEN_TAG;
+ } else {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return INLINE_HTML;
+ }
+}
+
+
+<INITIAL>"<%=" {
+ HANDLE_NEWLINES(yytext,yyleng);
+ if (CG(asp_tags)) {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ BEGIN(IN_SCRIPTING);
+ return PHP_OPEN_TAG_WITH_ECHO;
+ } else {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return INLINE_HTML;
+ }
+}
+
+
+<INITIAL>"<%" {
+ HANDLE_NEWLINES(yytext,yyleng);
+ if (CG(asp_tags)) {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ BEGIN(IN_SCRIPTING);
+ } else {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return INLINE_HTML;
+ }
+}
+
+
+<INITIAL>"<?php"[ \n\r\t] {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINE(yytext[yyleng-1]);
+ BEGIN(IN_SCRIPTING);
+ return PHP_OPEN_TAG;
+}
+
+
+<INITIAL>"<?php_track_vars?>"([\n]|"\r\n")? {
+ zend_message_dispatcher(ZMSG_ENABLE_TRACK_VARS, NULL);
+ HANDLE_NEWLINE(yytext[yyleng-1]);
+ return T_PHP_TRACK_VARS;
+}
+
+<IN_SCRIPTING,DOUBLE_QUOTES,HEREDOC>"$"{LABEL} {
+ zendlval->value.str.val = (char *)estrndup(yytext+1, yyleng-1);
+ zendlval->value.str.len = yyleng-1;
+ zendlval->type = IS_STRING;
+ return VARIABLE;
+}
+
+
+<IN_SCRIPTING>{LABEL} {
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return STRING;
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>{LABEL} {
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return STRING;
+}
+
+
+<IN_SCRIPTING>{WHITESPACE} {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext,yyleng);
+ return T_WHITESPACE;
+}
+
+
+<IN_SCRIPTING>([#]|"//")([^\n\r?]|"?"[^>\n\r])*("?\n"|"?\r\n")? { /* eat one line comments */
+ HANDLE_NEWLINE(yytext[yyleng-1]);
+ return ZEND_COMMENT;
+}
+
+<IN_SCRIPTING>"/*"([^*]|"*"[^/])*(("*/")?) {
+ HANDLE_NEWLINES(yytext, yyleng);
+ return ZEND_COMMENT;
+}
+
+
+<IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">")([\n]|"\r\n")? {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext, yyleng);
+ BEGIN(INITIAL);
+ return PHP_CLOSE_TAG; /* implicit ';' at php-end tag */
+}
+
+
+<IN_SCRIPTING>"%>"([\n]|"\r\n")? {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext,yyleng);
+ if (CG(asp_tags)) {
+ BEGIN(INITIAL);
+ return PHP_CLOSE_TAG; /* implicit ';' at php-end tag */
+ } else {
+ return INLINE_HTML;
+ }
+}
+
+
+<IN_SCRIPTING>(["]([^"$\\]|([\\]+[^\\$]))*["])|([']([^'\\]|([\\]+['\\]))*[']) {
+ register char *s, *t;
+ char *end;
+
+ zendlval->value.str.val = estrndup(yytext+1, yyleng-2);
+ zendlval->value.str.len = yyleng-2;
+ zendlval->type = IS_STRING;
+ HANDLE_NEWLINES(yytext,yyleng);
+
+ /* convert escape sequences */
+ s = t = zendlval->value.str.val;
+ end = s+zendlval->value.str.len;
+ while (s<end) {
+ if (*s=='\\') {
+ s++;
+ if (s>=end) {
+ continue;
+ }
+ switch(*s) {
+ case 'n':
+ *t++ = '\n';
+ zendlval->value.str.len--;
+ break;
+ case 'r':
+ *t++ = '\r';
+ zendlval->value.str.len--;
+ break;
+ case 't':
+ *t++ = '\t';
+ zendlval->value.str.len--;
+ break;
+ case '\\':
+ *t++ = '\\';
+ zendlval->value.str.len--;
+ break;
+ case '$':
+ case '"':
+ *t++ = *s;
+ zendlval->value.str.len--;
+ break;
+ default:
+ *t++ = '\\';
+ *t++ = *s;
+ break;
+ }
+ s++;
+ } else {
+ *t++ = *s++;
+ }
+ }
+ *t = 0;
+
+ return CONSTANT_ENCAPSED_STRING;
+}
+
+
+<IN_SCRIPTING>["] {
+ BEGIN(DOUBLE_QUOTES);
+ return '\"';
+}
+
+
+<IN_SCRIPTING>"<<"{LABEL}("\r")?"\n" {
+ CG(heredoc_len) = yyleng-2-1-(yytext[yyleng-2]=='\r'?1:0);
+ CG(heredoc) = estrndup(yytext+2, CG(heredoc_len));
+ BEGIN(HEREDOC);
+ return ZEND_HEREDOC;
+}
+
+
+<IN_SCRIPTING>[`] {
+ BEGIN(BACKQUOTE);
+ return '`';
+}
+
+
+<IN_SCRIPTING>['] {
+ BEGIN(SINGLE_QUOTE);
+ return '\'';
+}
+
+
+<HEREDOC>^{LABEL}("\r")?"\n" {
+ int label_len;
+
+ if (yytext[yyleng-2]=='\r') {
+ label_len = yyleng-2;
+ } else {
+ label_len = yyleng-1;
+ }
+
+ if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
+ efree(CG(heredoc));
+ CG(heredoc)=NULL;
+ CG(heredoc_len)=0;
+ BEGIN(IN_SCRIPTING);
+ return ZEND_HEREDOC;
+ } else {
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return STRING;
+ }
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>{ESCAPED_AND_WHITESPACE} {
+ HANDLE_NEWLINES(yytext,yyleng);
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return ENCAPSED_AND_WHITESPACE;
+}
+
+<SINGLE_QUOTE>([^'\\]|\\[^'\\])+ {
+ HANDLE_NEWLINES(yytext,yyleng);
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return ENCAPSED_AND_WHITESPACE;
+}
+
+
+<DOUBLE_QUOTES>[`]+ {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return ENCAPSED_AND_WHITESPACE;
+}
+
+
+<BACKQUOTE>["]+ {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return ENCAPSED_AND_WHITESPACE;
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"$"[^a-zA-Z_\x7f-\xff{] {
+ zendlval->value.chval = yytext[0];
+ if (yyleng == 2) {
+ unput(yytext[1]);
+ yytext[1] = 0;
+ yyleng--;
+ }
+ return CHARACTER;
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>{ENCAPSED_TOKENS} {
+ zendlval->value.chval = yytext[0];
+ return yytext[0];
+}
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"{$" {
+ zendlval->value.chval = yytext[0];
+ yy_push_state(IN_SCRIPTING);
+ unput('$');
+ return T_CURLY_OPEN;
+}
+
+<SINGLE_QUOTE>"\\'" {
+ zendlval->value.chval='\'';
+ return CHARACTER;
+}
+
+<SINGLE_QUOTE>"\\\\" {
+ zendlval->value.chval='\\';
+ return CHARACTER;
+}
+
+<DOUBLE_QUOTES>"\\\"" {
+ zendlval->value.chval='"';
+ return CHARACTER;
+}
+
+<BACKQUOTE>"\\`" {
+ zendlval->value.chval='`';
+ return CHARACTER;
+}
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"\\"[0-7]{1,3} {
+ zendlval->value.chval = (char) strtol (yytext+1, NULL, 8);
+ return CHARACTER;
+}
+
+<DOUBLE_QUOTES,BACKQUOTE,HEREDOC>"\\x"[0-9A-Fa-f]{1,2} {
+ zendlval->value.chval = (char) strtol (yytext+2, NULL, 16);
+ return CHARACTER;
+}
+
+<DOUBLE_QUOTES,BACKQUOTE>"\\". {
+ switch (yytext[1]) {
+ case 'n':
+ zendlval->value.chval='\n';
+ break;
+ case 't':
+ zendlval->value.chval='\t';
+ break;
+ case 'r':
+ zendlval->value.chval='\r';
+ break;
+ case '\\':
+ zendlval->value.chval='\\';
+ break;
+ case '$':
+ zendlval->value.chval=yytext[1];
+ break;
+ case '{':
+ zendlval->value.chval=yytext[1];
+ break;
+ default:
+ zendlval->value.str.val = estrndup(yytext,yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return BAD_CHARACTER;
+ break;
+ }
+ return CHARACTER;
+}
+
+
+<HEREDOC>"\\$"|"\\{" {
+ zendlval->value.chval = yytext[1];
+ return CHARACTER;
+}
+
+
+<HEREDOC>["'`]+ {
+ zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return ENCAPSED_AND_WHITESPACE;
+}
+
+
+<DOUBLE_QUOTES>["] {
+ BEGIN(IN_SCRIPTING);
+ return '\"';
+}
+
+
+<BACKQUOTE>[`] {
+ BEGIN(IN_SCRIPTING);
+ return '`';
+}
+
+
+<SINGLE_QUOTE>['] {
+ BEGIN(IN_SCRIPTING);
+ return '\'';
+}
+
+
+<DOUBLE_QUOTES,BACKQUOTE,INITIAL,IN_SCRIPTING,LOOKING_FOR_PROPERTY><<EOF>> {
+ return 0;
+}
+
+
+
+
+<IN_SCRIPTING,INITIAL,DOUBLE_QUOTES,BACKQUOTE,SINGLE_QUOTE>. {
+ zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d",yytext[0],yytext[0],YYSTATE);
+}