%top{ /* * Copyright (c) 2002, 2004, 2005, 2006, 2008 Tama Communications Corporation * * This file is part of GNU GLOBAL. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * scanner for php source code. */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef STDC_HEADERS #include #endif #ifdef HAVE_STRING_H #include #else #include #endif #include "global.h" #include "anchor.h" #include "common.h" #include "incop.h" #include "htags.h" #include "../libparser/php_res.h" #define lex_symbol_generation_rule(x) php_ ## x #include "lexcommon.h" #ifdef ECHO #undef ECHO #endif #define ECHO echos(LEXTEXT) #define YY_USER_ACTION DEFAULT_YY_USER_ACTION #define LEFT_BRACE '(' static int pre_here_document; static char end_of_here_document[IDENTLEN]; } /* Definitions */ H 0[Xx][0-9A-Fa-f]+ N [0-9]+ L {N}L? D1 {N}\.{N}([Ee][+-]?{N})? D2 \.{N}([Ee][+-]?{N})? NUMBER -?({L}|{D1}|{D2}) ALPHA [a-zA-Z_\x80-\xff] ALPHANUM [a-zA-Z_\x80-\xff0-9] WORD {ALPHA}{ALPHANUM}* %start PHP C_COMMENT CPP_COMMENT SHELL_COMMENT STRING LITERAL HEREDOCUMENT PREPROCESSOR_LINE %option 8bit noyywrap noyy_top_state stack never-interactive prefix="php_" %% /* Start PHP */ """"<%" { put_string(LEXTEXT); BEGIN PHP; } "" { put_string(LEXTEXT); BEGIN PHP; } /* Ignore HTML */ . put_string(LEXTEXT); /* End of PHP */ "?>" { put_string(LEXTEXT); BEGIN INITIAL; } "%>" { put_string(LEXTEXT); BEGIN INITIAL; } "" { put_string(LEXTEXT); BEGIN INITIAL; } /* Comment */ "/*" { echos(comment_begin); ECHO; yy_push_state(C_COMMENT); } "*/" { ECHO; echos(comment_end); yy_pop_state(); } . { put_char(LEXTEXT[0]); } "#" { echos(comment_begin); ECHO; yy_push_state(SHELL_COMMENT); } "//" { echos(comment_begin); ECHO; yy_push_state(CPP_COMMENT); } /* String */ \" { ECHO; yy_push_state(STRING); } \" { ECHO; yy_pop_state(); } \\. { put_char(LEXTEXT[0]); put_char(LEXTEXT[1]); } /* Literal */ \' { ECHO; yy_push_state(LITERAL); } \' { ECHO; yy_pop_state(); } \\. { put_char(LEXTEXT[0]); put_char(LEXTEXT[1]); } /* Here document */ <<<{WORD} { /* extract word and save */ if (LEXLENG - 3 > IDENTLEN) die("Too long name '%s'.", LEXTEXT + 3); strcpy(end_of_here_document, LEXTEXT + 3); put_string("<<<"); put_reserved_word(end_of_here_document); /* begin here document from the next line */ pre_here_document = 1; } ^[ \t]*{WORD} { const char *keyword = strtrim((const char *)LEXTEXT, TRIM_HEAD, NULL); put_reserved_word(LEXTEXT); if (!strcmp(end_of_here_document, keyword)) { end_of_here_document[0] = '\0'; yy_pop_state(); } } ^[ \t]*(include|require|require_once) { int c; put_reserved_word(LEXTEXT); /* * include ('aaa/bbb.h'); * include 'aaa/bbb.h'; * ^ */ while ((c = input()) && c != EOF && c != '\n' && isspace(c)) echoc(c); if (c == EOF) c = '\n'; if (c == '\n') unput(c); else if (c) { char path[MAXPATHLEN], *p = path, *lim = p + MAXPATHLEN - 1; int sep = 0; if (c == LEFT_BRACE) { c = input(); if (c == EOF) c = '\n'; } if (c == '"' || c == '\'') sep = c; echoc(c); /* pick up path name */ while ((c = input()) && c != EOF && c != '\n' && c != sep) if (p < lim) *p++ = c; *p = '\0'; if (c == EOF) c = '\n'; if (c == sep) { char tmp[MAXPATHLEN]; char normalized_path[MAXPATHLEN]; snprintf(tmp, sizeof(tmp), "%s/%s", get_current_dir(), path); /* * pick up the file only when it exists. */ if (normalize(tmp, get_root_with_slash(), get_cwd(), normalized_path, sizeof(normalized_path)) && test("f", normalized_path)) put_include_anchor_direct(normalized_path, path); else echos(path); echoc(sep); } else { echos(path); if (c) unput(c); } } } {NUMBER} ECHO; \${WORD} | \$\{{WORD}\} { struct anchor *a = NULL; const char *p = LEXTEXT + 1; /* skip '$' */ int brace = 0, i = 0; /* * extract name. */ if (*p == '{') { char buf[IDENTLEN]; brace = 1; for (p++; *p && *p != '}'; p++) { buf[i++] = *p; if (i >= sizeof(buf)) die("Too long name '%s'.", LEXTEXT); } buf[i] = '\0'; p = buf; } else { i = LEXLENG - 1; } if ((a = anchor_get(p, i, 'Y', LINENO)) != NULL) { echoc('$'); if (brace) echoc('{'); put_anchor(gettag(a), a->type, LINENO); if (brace) echoc('}'); a->done = 1; } else if (grtags_is_empty) { echoc('$'); if (brace) echoc('{'); put_anchor_force(LEXTEXT, LEXLENG, LINENO); if (brace) echoc('}'); } else { ECHO; } } {WORD} { struct anchor *a = NULL; if (php_reserved_word(LEXTEXT, LEXLENG)) put_reserved_word(LEXTEXT); else { a = anchor_get(LEXTEXT, LEXLENG, 0, LINENO); if (a) { put_anchor(gettag(a), a->type, LINENO); a->done = 1; } else if (grtags_is_empty) { put_anchor_force(LEXTEXT, LEXLENG, LINENO); } else { ECHO; } } } [{}] { put_brace(LEXTEXT); } /* New line */ \n { DEFAULT_END_OF_LINE_ACTION if (pre_here_document == 1) { pre_here_document = 0; yy_push_state(HEREDOCUMENT); } } . { put_char(LEXTEXT[0]); } %% void php_parser_init(FILE *ip) { BEGIN(INITIAL); DEFAULT_BEGIN_OF_FILE_ACTION }