在php中读取类似lua的代码

时间:2009-06-07 20:39:13

标签: php parsing

我有一个问题...... 我得到了这样的代码,我想用PHP阅读它。

 NAME
 {
    title
    (
        A_STRING
    );

    settings
    {
        SetA( 15, 15 );
        SetB( "test" );
    }

    desc
    {
        Desc
        (
            A_STRING
        );

        Cond
        (
            A_STRING
        );  

    }
 }

我想:

$arr['NAME']['title'] = "A_STRING";
$arr['NAME']['settings']['SetA'] = "15, 15";
$arr['NAME']['settings']['SetB'] = "test";
$arr['NAME']['desc']['Desc'] = "A_STRING";
$arr['NAME']['desc']['Cond'] = "A_STRING";

我不知道应该如何开始:/。变量并不总是相同的。 有人可以给我一个关于如何解析这样一个文件的提示吗?

THX

3 个答案:

答案 0 :(得分:5)

这看起来像一个真正的语法 - 你应该使用一个解析器生成器。 This discussion应该让你开始。

已经为php制作了一些选项:lexer generator module这是一个parser generator module

答案 1 :(得分:2)

这不是答案,而是建议:

也许您可以修改输入代码以与具有类似语法的JSON兼容。 JSON解析器和生成器可用于PHP。

http://www.json.org/

http://www.php.net/json

答案 2 :(得分:0)

如果文件很简单,那么滚动你自己的自己开发的解析器可能要容易得多。无论如何,最终你最终会用词法分析器编写正则表达式。这是一个快速的黑客示例:( in.txt应包含您在上面提供的输入。)

<pre>
<?php

$input_str = file_get_contents("in.txt");
print_r(parse_lualike($input_str));

function parse_lualike($str){    
    $str = preg_replace('/[\n]|[;]/','',$str);
    preg_match_all('/[a-zA-Z][a-zA-Z0-9_]*|[(]\s*([^)]*)\s*[)]|[{]|[}]/', $str, $matches);
    $tree = array();
    $stack = array();
    $pos = 0;
    $stack[$pos] = &$tree;
    foreach($matches[0] as $index => $token){
        if($token == '{'){
            $node = &$stack[$pos];
            $node[$ident] = array();
            $pos++;
            $stack[$pos] =  &$node[$ident];
        }elseif($token=='}'){
            unset($stack[$pos]);
            $pos--;
        }elseif($token[0] == '('){
            $stack[$pos][$ident] = $matches[1][$index];
        }else{
            $ident =  $token;
        }
    }
    return $tree;
}

?>

快速解释:第一个preg_replace删除所有换行符和分号,因为它们似乎是多余的。下一部分将输入字符串分成不同的“标记”;名称,括号和之间的关系。在那里做一个print_r $matches;来看它的作用。

然后只有一个真正的hackish状态机(或读取for循环)通过令牌并将它们添加到树中。它还有一个堆栈,可以构建嵌套树。

请注意,此算法未经过测试。当呈现“现实生活”输入时,它可能会破裂。例如,值内的括号将导致麻烦。另请注意,它不会删除字符串中的引号。我会把所有这些留给别人......

但是,正如您所要求的,这是一个开始:)

干杯!

PS。为方便起见,这是上面代码的输出:

Array
(
    [NAME] => Array
        (
            [title] => A_STRING   
            [settings] => Array
                (
                    [SetA] => 15, 15 
                    [SetB] => "test" 
                )

            [desc] => Array
                (
                    [Desc] => A_STRING       
                    [Cond] => A_STRING       
                )

        )

)