📄 php_parser.y
字号:
%{//// This file is part of the aMule Project.//// Copyright (c) 2003-2006 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (C) 2005-2006Froenchenko Leonid ( lfroen@amule.org )//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// 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 2 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, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//#include <stdio.h>#include <string.h>#include "php_syntree.h"int yylex();// add item to syntree listPHP_SYN_NODE *add_statement_2_list(PHP_SYN_NODE *list, PHP_SYN_NODE *st){ if ( st && list) { PHP_SYN_NODE *last = list; while ( last->next_node ) { last = last->next_node; } last->next_node = st; return list; } else if ( st ) { return st; } else { return list; }}PHP_SYN_NODE *add_branch_2_elseif(PHP_SYN_NODE *list, PHP_SYN_NODE *branch){ if ( list ) { PHP_SYN_NODE *curr_if = list; while ( curr_if->node_if.code_else ) { curr_if = curr_if->node_if.code_else; } curr_if->node_if.code_else = branch; return list; } else { return branch; }}%}%union { PHP_SYN_NODE *syn_node; PHP_EXP_NODE *exp_node; char str_val[256];}%type <syn_node> program_tree statement top_statement function_decl_statement top_statement_list%type <syn_node> global_var_list static_var_list%type <syn_node> while_statement foreach_statement for_statement elseif_list else_statement %type <exp_node> VARIABLE variable deref_variable global_var static_var%type <exp_node> parameter_list array_pair_list array_elem%type <exp_node> switch_case_list case_list case_list_item%type <exp_node> expr expr_list for_expr exit_expr const_value function_call func_param_list assignment_list assignment_list_element%type <exp_node> FNUMBER DNUMBER STRING%type <str_val> IDENT optional_class_type/* All my tokens*/%token FNUMBER DNUMBER STRING IDENT VARIABLE%token ECHO%token EXIT%token IF DO WHILE ENDWHILE FOR ENDFOR FOREACH ENDFOREACH%token DECLARE ENDDECLARE AS CONST GLOBAL UNSET ISSET EMPTY%token SWITCH ENDSWITCH CASE DEFAULT BREAK CONTINUE%token FUNCTION RETURN%token CLASS INTERFACE EXTENDS IMPLEMENTS OBJECT_OPERATOR%token HASH_ASSIGN LIST ARRAY%token CLASS_SCOPE/* Things with precedence*/%left ','%right PRINT%left '=' PLUS_EQ MINUS_EQ MUL_EQ DIV_EQ CONCAT_EQ MOD_EQ AND_EQ OR_EQ XOR_EQ SL_EQ SR_EQ%left '?' ':'%left LOG_OR%left LOG_XOR%left LOG_AND%left BOOLEAN_OR%left BOOLEAN_AND%left '|'%left '^'%left '&'%nonassoc IS_EQ IS_NOEQUAL IS_IDENTICAL IS_NOIDENTICAL%nonassoc '<' IS_SMALLER_OR_EQ '>' IS_GREATER_OR_EQ%left SL SR%left '+' '-' '.'%left '*' '/' '%'%right '!'%nonassoc INSTANCEOF%right '~' INC DEC INT_CAST DOUBLE_CAST STRING_CAST ARRAY_CAST OBJECT_CAST BOOL_CAST UNSET_CAST '@'%right '['%nonassoc NEW CLONE%left ELSEIF%left ELSE%left ENDIF%right STATIC ABSTRACT FINAL PRIVATE PROTECTED PUBLIC%token START_SCRIPT END_SCRIPT%% /* Rules */program_tree: START_SCRIPT top_statement_list END_SCRIPT { g_syn_tree_top = $2; };top_statement_list: top_statement_list top_statement { $$ = add_statement_2_list($1, $2); } | /* empty */ { $$ = 0; };top_statement: statement | START_SCRIPT top_statement_list END_SCRIPT { $$ = $2; } | function_decl_statement/* | class_decl_statement */;statement: '{' top_statement_list '}' { $$ = $2; } | expr ';' { $$ = make_expr_syn_node(PHP_ST_EXPR, $1); } | GLOBAL global_var_list ';' { $$ = 0; } | STATIC static_var_list ';' { $$ = $2; } | IF '(' expr ')' statement elseif_list else_statement { $$ = make_ifelse_syn_node($3, $5, $6, $7); } | WHILE '(' expr ')' while_statement { $$ = make_while_loop_syn_node($3, $5, 1); } | DO statement WHILE '(' expr ')' ';' { $$ = make_while_loop_syn_node($5, $2, 0); } | FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement { $$ = make_for_syn_node($3, $5, $7, $9); } | SWITCH '(' expr ')' switch_case_list { $$ = make_switch_syn_node($3, $5); } | CONTINUE ';' { $$ = make_expr_syn_node(PHP_ST_CONTINUE, 0); } | CONTINUE expr ';' { $$ = make_expr_syn_node(PHP_ST_CONTINUE, $2); } | BREAK ';' { $$ = make_expr_syn_node(PHP_ST_BREAK, 0); } | BREAK expr ';' { $$ = make_expr_syn_node(PHP_ST_BREAK, $2); } | RETURN ';' { $$ = make_expr_syn_node(PHP_ST_RET, 0); } | RETURN expr ';' { $$ = make_expr_syn_node(PHP_ST_RET, $2); } | ECHO expr_list ';' { $$ = make_expr_syn_node(PHP_ST_ECHO, $2); } | UNSET '(' variable_list ')' ';' { } | FOREACH '(' expr AS variable ')' foreach_statement { $$ = make_foreach_loop_syn_node($3, 0, $5, $7, 0); } | FOREACH '(' expr AS variable HASH_ASSIGN variable ')' foreach_statement { $$ = make_foreach_loop_syn_node($3, $5, $7, $9, 0); } | FOREACH '(' expr AS variable HASH_ASSIGN '&' variable ')' foreach_statement { $$ = make_foreach_loop_syn_node($3, $5, $8, $10, 1); } | DECLARE '(' decl_list ')' statement { } | DECLARE '(' decl_list ')' ':' top_statement_list ENDDECLARE { } | ';' { $$ = 0; };decl_list: IDENT '=' const_value { } | decl_list ',' IDENT '=' const_value { };expr_list: expr { $$ = make_exp_1(PHP_OP_LIST, 0); $$->exp_node = $1; } | expr_list ',' expr { PHP_EXP_NODE *last = $1; while ( last->next) last = last->next; last->next = make_exp_1(PHP_OP_LIST, 0); last->next->exp_node = $3; $$ = $1; };variable_list: variable | variable_list ',' variable;/* This IS implemented. global_var/static itself initialize ptrs as needed*/global_var_list: global_var { $$ = 0; } | global_var_list ',' global_var { };global_var: VARIABLE { const char *varname = get_scope_var_name(g_current_scope, $1->var_si_node->var); PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, varname); PHP_SCOPE_ITEM *gsi = get_scope_item(g_global_scope, varname); if ( gsi && (gsi->type == PHP_SCOPE_VAR) ) { free_var_node(si->var); php_exp_tree_free($1); gsi->var->ref_count++; si->var = gsi->var; } else { php_report_error(PHP_ERROR, "There is no such global var"); } };static_var_list: static_var { $$ = 0; } | static_var_list ',' static_var { };static_var : VARIABLE { $1->var_node->flags |= PHP_VARFLAG_STATIC; $$ = $1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -