📄 phpbrowser.l
字号:
/*Copyright (c) 2003, Mo DeJongThis file is part of Source-Navigator.Source-Navigator is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as publishedby the Free Software Foundation; either version 2, or (at your option)any later version.Source-Navigator is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith Source-Navigator; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA.*//* * phpbrowser.l * * Copyright (C) 2003 Mo DeJong * * Description: * Lex input file for an php language processor. */%{#include <ctype.h>#include <stdlib.h>#include <stdio.h>#include "snptools.h"#include "lexinput.h"#include "longstr.h"#include "srchtbl.h"#include "tcl.h"#undef YY_INPUT#define YY_INPUT(buf,r,ms) (r = sn_encoded_input(buf, ms))#undef yywrap#define YY_SKIP_YYWRAPtypedef enum { OPEN_PAREN, /* '(' */ CLOSE_PAREN, /* ')' */ OPEN_BRACE, /* '{' */ CLOSE_BRACE, /* '}' */ OPEN_BRACKET, /* '[' */ CLOSE_BRACKET, /* ']' */ SEMICOLON, /* ';' */ COMMA, /* ',' */ PERIOD, /* '.' */ VARIABLE, /* $var */ ASSIGNMENT_OPERATOR, /* '=' */ ASSIGNMENT_OPERATORS, /* = -= += and so on */ COMPARISON_OPERATORS, /* == === != >= and so on */ INCREMENT_OPERATORS, /* ++ and -- */ REFERENCE_OPERATOR, /* & */ SOMEWORD, /* a sequence of text */ KEYWORD, /* a key sequence in this language */ FUNCTION_KEYWORD, /* The keyword "function" */ GLOBAL_KEYWORD, /* The keyword "global" */ INCLUDE_KEYWORD, /* The keyword "include" */ VDOUBLE_QUOTED_STRING, /* "I am a $variable string" */ DOUBLE_QUOTED_STRING, /* "I am a double quoted string" */ SINGLE_QUOTED_STRING, /* 'I am a double quoted string' */ UNKNOWN, /* Token that parser does not know about */ COMMENT, /* Emit COMMENT token only when debugging */ HTML /* Emit HTML token only when debugging */} TokenType;typedef enum { VAR_READ, VAR_WRITE, VAR_READWRITE} VarAccess;typedef struct Token { TokenType type; char * strval; /* String value of token, NULL if single character */ long start_line; int start_column; long end_line; int end_column; struct Token* vars; /* for variables embedded in a DOUBLE_QUOTED_STRING token */ struct Token* next;} Token;typedef struct NestedBracket { int count; int prefix_incr; struct Token* var; struct NestedBracket* next;} NestedBracket;typedef struct NestedFunction { char* name; char* args; int high_line; int high_col_start; int high_col_end; int line_start; int line_end; int col_start; int col_end; int brace_count; struct NestedFunction* next;} NestedFunction;/* Uncomment this to see debug output in token parsing stage *//* #define TOKEN_DEBUG */#ifdef TOKEN_DEBUGFILE* tokenout = NULL;#endifstatic char * token_dump_file = NULL;static int highlight_file = 0;Token* tokens_head = NULL;Token* tokens_tail = NULL;int token_index = 0; /* current offset from original token_head */static char group[] = "php";#define MAX_SIZE 512/* FIXME: Can't pass NULL or "" as current function (core dump) */static char* current_function = (char *) NULL;static char* current_function_args = (char *) NULL;/* line number where highlight starts and ends */static int current_function_highlight_line;/* in "function fog() {}" column of 'f' in "fog" */static int current_function_highlight_column_start;/* in "function fog() {}" column of 'g' in "fog" */static int current_function_highlight_column_end;/* line where "function" appears */static int current_function_line_start;/* line where closing brace of function appears */static int current_function_line_end;/* in "function fog() {}" column of 'f' in "function" */static int current_function_column_start;/* in "function fog() {}" column of '}' in "{}" */static int current_function_column_end;static int current_function_brace_count;static NestedFunction* function_nest_head = NULL;static NestedFunction* function_nest_tail = NULL;static int current_array_bracket_count = 0;static Token* current_array_token = NULL;static int current_array_prefix_incr = 0;static NestedBracket* array_nest_head = NULL;static NestedBracket* array_nest_tail = NULL;static int result;static SearchTable * global_var_table = (SearchTable *) NULL;static SearchTable * super_global_var_table;/* Stores the contents of a special processing mode over * multiple lines/rules. */LongString mode_buff;long mode_start_line;int mode_start_column;#define COMMENT_DUMP 0#define DQSTRING_DUMP 0#define SQSTRING_DUMP 0#define HDSTRING_DUMP 0#define HTML_DUMP 0#define MATCH_DUMP 0static YY_BUFFER_STATE original_buffer;static char* heredoc_id = (char *) NULL; /* End marker for a heredoc string */static Token* embedded_dq_string_vars_head = NULL;static Token* embedded_dq_string_vars_tail = NULL;#if MATCH_DUMPstatic void matched_pattern(char * pattern, char * text);#endifvoid enter_html_mode();static char* modestring();static void FreeGlobalEntry(SearchEntry *entry);void FreeToken(Token* tok);Token* pop_head_token();void free_head_token();void push_bracket_counter();void pop_bracket_counter();void push_function();void pop_function();void append_token(TokenType type, char* strval, long start_line, int start_column, long end_line, int end_column);void append_dqstring_var_token(char* var, long start_line, int start_column, long end_line, int end_column);void append_dqstring_token(char* strval, long start_line, int start_column, long end_line, int end_column);void emit_var_access_for_dqstring(Token* tok);char * TokenTypeToString(Token *tok);int get_num_tokens_matched(char *match);void emit_function_declaration();void emit_comment();void emit_dqstring();void emit_sqstring();void emit_hdstring();void emit_html();void emit_var_access(Token* tok, VarAccess acc);int yywrap() { return 1; }%}%x COMMENT_MODE%x HTML_MODE%x DQSTRING%s SQSTRING%s HDSTRING%x PHP%x TOKENws [ \t]wsn [ \t\n]symbol [a-zA-Z0-9_]+varname {symbol}someword {symbol}token {symbol}heredoc-id {symbol}assignment-operators ("+="|"-="|"*="|"/="|".="|"%="|"&="|"|="|"^="|"<<="|">>=")comparison-operators ("=="|"==="|"!="|"!=="|"<>"|"<"|">"|"<="|">=")increment-operators ("++"|"--")any-tokens (" "|" "{symbol}" "|" "{symbol}" "({symbol}" ")*)include-keywords ("include"|"include_once"|"require"|"require_once")keywords ("and"|"or"|"xor"|"array"|"as"|"break"|"case"|"cfunction"|"class"|"const"|"continue"|"declare"|"default"|"die"|"do"|"echo"|"else"|"elseif"|"empty"|"enddeclare"|"endfor"|"endforeach"|"endif"|"endswitch"|"endwhile"|"eval"|"exit"|"extends"|"for"|"foreach"|"if"|"isset"|"list"|"new"|"old_function"|"print"|"return"|"static"|"switch"|"unset"|"use"|"var"|"while"|"__FUNCTION__"|"__FILE__"|"__CLASS__"|"__LINE__")dq-string-token "DOUBLE_QUOTED_STRING"sq-string-token "SINGLE_QUOTED_STRING"literal-token ({someword}|{dq-string-token}|{sq-string-token})include-string-token ({dq-string-token}|{sq-string-token})function-argument-token ("VARIABLE"|"REFERENCE_OPERATOR VARIABLE"|"VARIABLE ASSIGNMENT_OPERATOR "{literal-token})function-argument-tokens (" "|" "{function-argument-token}" "("COMMA "{function-argument-token}" ")*)variable-tokens (" VARIABLE "|" VARIABLE "("COMMA VARIABLE ")+)var-array-index-token ("SOMEWORD"|"VDOUBLE_QUOTED_STRING"|"DOUBLE_QUOTED_STRING"|"SINGLE_QUOTED_STRING"|"VARIABLE")var-array-empty-tokens "OPEN_BRACKET CLOSE_BRACKET"var-array-index-tokens "OPEN_BRACKET "{var-array-index-token}" CLOSE_BRACKET")var-array-token ({var-array-empty-tokens}|{var-array-index-tokens}var-array-tokens (" "|" "{var-array-token}" "({var-array-token}" ")*)%% /* Start in HTML mode */ highlight_file = (int) sn_getopt(SN_OPT_HIGHLIGHT); token_dump_file = (char *) sn_getopt(SN_OPT_DUMP_TOKENS); enter_html_mode();<PHP>"?>" { /* PHP -> HTML mode */ #if MATCH_DUMP matched_pattern("?>", yytext); #endif enter_html_mode(); if (token_dump_file) { mode_buff.append( &mode_buff, yytext, yyleng ); } sn_advance_column(2);}<HTML_MODE>{ [^\<\n]* { #if MATCH_DUMP matched_pattern("[^\\<\\n]*", yytext); #endif #if HTML_DUMP fprintf(stderr, "html(1) \"%s\", %d\n", yytext, yyleng); #endif if (token_dump_file) { mode_buff.append( &mode_buff, yytext, yyleng ); } sn_advance_column(yyleng); } [^\<\n]*\n { #if MATCH_DUMP matched_pattern("[^\\<\\n]*\\n", yytext); #endif #if HTML_DUMP fprintf(stderr, "html(2) \"%s\", %d\n", yytext, yyleng); #endif if (token_dump_file) { mode_buff.append( &mode_buff, yytext, yyleng ); } sn_advance_line(); sn_reset_column(); } "<" { #if MATCH_DUMP matched_pattern("<", yytext); #endif #if HTML_DUMP fprintf(stderr, "html(3) \"%s\", %d\n", yytext, yyleng); #endif if (token_dump_file) { mode_buff.append( &mode_buff, yytext, yyleng ); } sn_advance_column(yyleng); } ("<?"|"<?="|"<?php"|"<?PHP") { /* HTML -> PHP mode switch */ #if MATCH_DUMP matched_pattern("(<?|<?=|<?php|<?PHP)", yytext); #endif sn_advance_column(yyleng); if (token_dump_file) { mode_buff.append( &mode_buff, yytext, yyleng ); } emit_html(); BEGIN(PHP); } /* Uncomment the next rule if you want to check to make sure * the above rules cover all possible input. A warning * "rule cannot be matched" should be printed by flex. */ /*. {}*/}<PHP>("//"|"#").*("\n"|"?>") { char * x = (char *) yytext; char * y; int newline = 0;#if MATCH_DUMP matched_pattern("(//|#).*\\n", yytext);#endif while (*x == ' ' || *x == '\t') { x++; } assert(*x == '#' || (*x == '/' && *(x+1) == '/')); if (*x == '#') { x++; } else if (*x == '/') { x += 2; } sn_advance_column(x - yytext); /* Check for ?> in the text leading up to the newline. * PHP has this special rule where a line comment * can be terminated before the newline. */ for (y=x; *y; y++) { if (*y == '?' && *(y+1) == '>') { int offset = (int) (y - yytext); yyless(offset); /* send everything after ?> back */ break; } } y = yytext + yyleng - 1; if (*y == '\n') { newline = 1; *y = 0; } /* If dumping tokens, emit a special COMMENT token. * Otherwise, insert a comment symbol and a highlight. */ if (token_dump_file) { append_token(COMMENT, x, sn_line(), sn_column() - (x - yytext), sn_line(), sn_column() + strlen(x)); } else { sn_insert_comment( /* classname */ NULL, /* funcname */ NULL, sn_current_file(), x, sn_line(), sn_column()); sn_highlight(SN_HIGH_COMMENT, sn_line(), sn_column() - (x - yytext), sn_line(), sn_column() + strlen(x)); } if (newline) { sn_advance_line(); sn_reset_column(); } else { sn_advance_column(yyleng - (x - yytext)); }}<PHP>"/*" { /* A C style multi-line comment, just like this! */#if MATCH_DUMP matched_pattern("/*", yytext);#endif BEGIN(COMMENT_MODE); sn_advance_column(2); LongStringInit(&mode_buff,0); mode_start_line = sn_line(); mode_start_column = sn_column();}<COMMENT_MODE>{ [^\*\n]* { #if MATCH_DUMP matched_pattern("[^\\*\\n]*", yytext); #endif #if COMMENT_DUMP fprintf(stderr, "comment(1) \"%s\", %d\n", yytext, yyleng); #endif mode_buff.append( &mode_buff, yytext, yyleng ); sn_advance_column(yyleng); } [^\*\n]*\n { #if MATCH_DUMP matched_pattern("[^\\*\\n]*\\n", yytext); #endif #if COMMENT_DUMP fprintf(stderr, "comment(2) \"%s\", %d\n", yytext, yyleng); #endif mode_buff.append( &mode_buff, yytext, yyleng ); sn_advance_line(); sn_reset_column(); } \*+[^\*/\n]* { #if MATCH_DUMP matched_pattern("\\*+[^\\*/\\n]*", yytext); #endif #if COMMENT_DUMP fprintf(stderr, "comment(3) \"%s\", %d\n", yytext, yyleng); #endif mode_buff.append( &mode_buff, yytext, yyleng ); sn_advance_column(yyleng); } \*+[^\*/\n]*\n {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -