zoukankan      html  css  js  c++  java
  • php 加入 unless 语法

    1. php 的版本 :PHP 7.3.0-dev (cli) (built: Mar 18 2018 00:28:55) ( NTS )

    2. unless

      语法结构:

      unless($cond){

        statement;

      }

      语法作用:

      当 $cond 为假的时候,执行 statement 语句。

    3. 代码修改

      词法分析文件 : Zend/zend_language_scanner.l , 大约 1195 的地方,添加 5 -7 行、 13 - 15 行内容 :

     1 <ST_IN_SCRIPTING>"while" {
     2     RETURN_TOKEN(T_WHILE);
     3 }
     4 
     5 <ST_IN_SCRIPTING>"unless" {
     6     RETURN_TOKEN(T_UNLESS);
     7 }
     8 
     9 <ST_IN_SCRIPTING>"endwhile" {
    10     RETURN_TOKEN(T_ENDWHILE);
    11 }
    12 
    13 <ST_IN_SCRIPTING>"endunless" {
    14     RETURN_TOKEN(T_ENDUNLESS);
    15 }

      语法分析文件 :  Zend/zend_language_parser.y , 添加内容:

      文件大约 271 行处, 添加 T_UNLESS 和 T_ENDUNLESS 内容:

    1 reserved_non_modifiers:
    2       T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
    3     | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE
    4     | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY
    5     | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
    6     | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
    7     | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
    8     | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_UNLESS | T_ENDUNLESS
    9 ;

      文件大约 152 行处, 添加 2 和 4 行 的内容:

    1 %token T_WHILE      "while (T_WHILE)"
    2 %token T_UNLESS     "unless (T_UNLESS)"
    3 %token T_ENDWHILE   "endwhile (T_ENDWHILE)"
    4 %token T_ENDUNLESS  "endunless (T_ENDUNLESS)"

      大约 235 行处 , 增加 unless_statement :

    %type <ast> expr optional_expr while_statement unless_statement for_statement foreach_variable 

        大约 428 行处, 增加 3 和 4 行的内容 :

    1     |    T_WHILE '(' expr ')' while_statement
    2             { $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); }
    3     |   T_UNLESS '(' expr ')' unless_statement
    4             { $$ = zend_ast_create(ZEND_AST_UNLESS, $3, $5); }

       大约 598 行处 ,增加 6 - 9 行的内容 :

    1 while_statement:
    2         statement { $$ = $1; }
    3     |    ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
    4 ;
    5 
    6 unless_statement:
    7         statement { $$ = $1; } 
    8     |   ':' inner_statement_list T_ENDUNLESS ';'  { $$ = $2; }
    9 ;

      Zend/zend_ast.h 的头文件中 ,大约 134 行处 , 增加 2 行的内容:   

    1     ZEND_AST_GROUP_USE,
    2     ZEND_AST_UNLESS,
    3 
    4     /* 3 child nodes */

      Zend/zend_ast.c 的文件中, 函数 zend_ast_export_stmt 内,大约 915 行处, 添加 7 行的内容:

     1 zend_ast_export_indent(str, indent);
     2 zend_ast_export_indent(str, indent);
     3 zend_ast_export_ex(str, ast, 0, indent);
     4 switch (ast->kind) {
     5     case ZEND_AST_LABEL:
     6     case ZEND_AST_IF:
     7     case ZEND_AST_UNLESS:
     8     case ZEND_AST_SWITCH:
     9     case ZEND_AST_WHILE:
    10     case ZEND_AST_TRY:
    11     case ZEND_AST_FOR:
    12     case ZEND_AST_FOREACH:
    13     case ZEND_AST_FUNC_DECL:
    14     case ZEND_AST_METHOD:
    15     case ZEND_AST_CLASS:
    16     case ZEND_AST_USE_TRAIT:
    17     case ZEND_AST_NAMESPACE:
    18     case ZEND_AST_DECLARE:
    19         break;
    20     default:
    21     smart_str_appendc(str, ';');
    22         break;
    23     }
    24 smart_str_appendc(str, '
    ');

      Zend/zend_compile.c 的文件中 ,

      大约 4667 行, 添加 zend_compile_ unless 函数 :

     1 void zend_compile_unless(zend_ast *ast)
     2 {
     3     zend_ast *cond_ast = ast->child[0];
     4     zend_ast *stmt_ast = ast->child[1];
     5     znode cond_node;
     6     
     7     uint32_t opnum_cond;
     8     
     9     zend_compile_expr(&cond_node,cond_ast);
    10     
    11     opnum_cond = zend_emit_cond_jump(ZEND_JMPNZ,&cond_node,0);
    12 
    13     zend_compile_stmt(stmt_ast);
    14 
    15     zend_update_jump_target_to_next(opnum_cond);
    16 }

      zend_compile_stmt 函数中, 大约 8200 行处 :

    1 case ZEND_AST_IF:
    2         zend_compile_if(ast);
    3     break;
    4 case ZEND_AST_UNLESS:
    5     zend_compile_unless(ast);
    6     break;

    4. 删除 Zend 目录下的 zend_language_parser.c 和 zend_language_scanner.c 文件,重新编译,安装 php .

    5. 测试代码:

    1 <?php
    2 unless(0)
    3 {
    4     echo "Hello the world!
    ";
    5 }
    6 
    7 unless(0):
    8     echo "Hello the world!
    ";
    9 endunless;

    输出:

    1 root@ubuntu:~/tmp# php a.php 
    2 Hello the world!
    3 Hello the world!

    参考:

    http://www.laruence.com/2010/07/16/1648.html

  • 相关阅读:
    Vue项目根据不同运行环境打包项目
    [Vue CLI 3] @vue/cli-plugin-eslint 源码分析
    [Vue CLI 3] 插件开发中的 genCacheConfig 细节研究
    [Vue CLI 3] 配置解析之 parallel
    [Vue CLI 3] 配置 webpack-bundle-analyzer 插件
    [Vue CLI 3] 插件开发之 registerCommand 到底做了什么
    [Vue CLI 3] Uglify 相关的应用和设计
    [Vue CLI 3] vue inspect 的源码设计实现
    [Vue CLI 3] 配置解析之 indexPath
    [Vue CLI 3] 配置解析之 css.extract
  • 原文地址:https://www.cnblogs.com/jingjingdidunhe/p/8594713.html
Copyright © 2011-2022 走看看