doujianjian2060 2016-12-19 06:39
浏览 48
已采纳

执行php脚本,不带循环或分支语句[关闭]

A PHP parser that can strip all the looping statements and branching statements and execute other

PHP codes eg:-

input

<?php
if(1){
echo "hello";
}
while(1){
echo "world";
}

output

<?php
echo "hello";
echo "world";
  • 写回答

1条回答 默认 最新

  • douqiaoru2583 2016-12-21 11:14
    关注

    This is extremely hard to do without a full language parser.

    You can do this with a program transformation system (PTS). These are tools that can parse source code into compiler data structures (often Abstract Syntax Trees [ASTs]), can make changes to the ASTs, and then can regenerate valid source text from the modified compiler data structures.

    A weak PTS will only let you walk the tree/inspect/change it procedurally, in the classic way a compiler does it. With this approach, you must be intimately familiar with the data structures (e.g., you have to know the precise structure of the tree), and for a real language, there's a lot of detail to know and get right. This works if you have lots of enthusiasm.

    A good PTS will let you provide it source-to-source transformations that it will use to search/change the tree. Such rewrites look like:

      when you see *thispattern*, replace it by *thatpattern*, if *condition*
    

    where thispattern and thatpattern are patterns written in the source langauge being transformed. The PTS takes care of converting them to corresponding compiler data structures so you can get by with a lot less knolwedge.

    In OP's case, he needs a PTS that can parse and transform PHP.

    The only "good" PTS I know that can do this off-the-shelf is our DMS Software Reengineering Toolkit with its PHP front end.

    You have to write a short DMS metaprogram to open and read the file, get the transforms and apply them, and then prettyprint the result (oversimplifying a bit for clarity):

     (define main
        (action (procedure void)
            (= AST  (Registry:Parse PHPDomain `my_file.php'))
            (Registry:ApplyTransforms AST (. `my_rewrite_rules.rsl') (. `strip_control_flow'))
            (local (= [os OutputStream:Stream] (OutputSteam:Open `updated_my_file.php'))=
                   (Registry:PrettyPrint os PHPDomain AST))
                   (= os (OutputStream:Close os))
            )local
        )action
      )define
    

    The bulk of the work is accomplished by DMS rewrite rules in the file "my_rewrite_rules.rsl":

     domain PHP~PHP5.
    
     rule strip if_then(c: expression, s: statement):
         statement -> statement =
     " if (\c) \s" ->  "\s".
    
     rule strip if_then_else(c: expression, s1: statement, s2: statement):
         statement -> statement =
     " if (\c) \s1 else \s2" -> " { \s1 \s2 } ".
    
     rule strip while(c: expression, s: statement):
         statement -> statement =
     " while (\c) \s" ->  "\s".
    
     rule strip catch( b1: statements, l: catch_clauses, t: type, e: expression, b2: statements):
         statement -> statement =
     " try { \b1 } \l catch ( \t \e ) { \b2 } "
     -> " { try { \b1 } \l ; \b2 } ".
    
     rule strip_trivial_try( b1: statements):
         statement -> statement =
     " try { \b1 } " -> "{ \b1 }".
    
     rule strip_useless_block( b:statements, s: statements):
        statements -> statements =
     "  { \b } \s " ->  " \b \s ".
    
     ruleset strip_control_flow = {
         strip_if_then,
         strip_if_then_else,
         strip_while,
         strip_catch,
         strip_trivial_try,
         strip_useless_block }
    

    etc. I didn't cover all the cases but it should be obvious how to proceed.

    To explain the above: DMS rewrite rules take the form

       rule rulename ( pattern_variable_declarations):
           syntaxcategory -> syntaxcategory
       "thispattern" -> "thatpattern".
    

    thispattern and thatpattern are written inside metaquotes "..." that distinguish source program pattern text from the syntax of the rewrite rule language itself. Withing metaquotes, one finds source language text intermixed with pattern variables \x whose syntax category is declared as x: category in the pattern variable declarations. You do have to know the major syntax categories of the language (e.g., "statement" vs. "statements" vs "expression" but you don't have know about all the internal structure of while loop.

    The ruleset groups a set of interesting named rules into a convenient bundle that can be applied in a batch; you can see how this ruleset is mentioned in the DMS metaprogram.

    A trick used when writing this ruleset is to have each rule strip its controlled-content elements into a block { ... }, because blocks are acceptable as statements. The cleanup rule strip_useless_blocks then gets rid of any egregious blocks that are created.

    You can see more about how DMS rewrite rules are written here.

    These rewrite rules will incrementally convert OP's program throught a series of stages that follow (you could prettyprint the full ASTs after each transform to see this):

    Start:

    <?php
    if(1){
    echo "hello";
    }
    while(1){
    echo "world";
    }
    

    after strip_if_then:

    <?php
    {
    echo "hello";
    }
    while(1){
    echo "world";
    }
    

    after strip_while:

    <?php
    {
    echo "hello";
    }
    {
    echo "world";
    }
    

    after 1st application of strip_useless_block:

    <?php
    echo "hello";
    {
    echo "world";
    }
    

    after 2nd application of strip_useless_block:

    <?php
    echo "hello";
    echo "world";
    

    and we have OP's desired result. This is a lot more spectacular on a big file.

    So, OP's task is fairly easy to do with a good PTS.

    I'll admit I have no clue as to why somebody would want strip out the control flow like this. But the point of a PTS is you can configure to carry out arbitrary code change tasks that are difficult to do by hand.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64