%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; }
""<%" { put_string(LEXTEXT); BEGIN PHP; }
"" { 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
}