Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разборка вызова функции, change("1", "privet", 123); 
:(
    Опции темы
Sannis
Дата 15.8.2007, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.8.2007
Где: Москва

Репутация: 1
Всего: 13



Здравствуйте.

Есть строка следующего вида:
Код

change("1", "privet", 123);


Нужно разобрать её на "имя функции" и массив аргументов. Аргументы могут быть либо числовыми, либо строками в кавычках или апострофах, число аргументов заранее неизвестно. 

P.S. Если есть какая-нибудь специализированная библиотека для таких вещей, подскажите smile


--------------------
Я Критик Джим, раньше писал моды для IPB 1.3.x-2.3.x, а теперь продвигаю Node.js в массы.
PM MAIL WWW   Вверх
Glip
Дата 15.8.2007, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 473
Регистрация: 30.12.2006

Репутация: 1
Всего: 18





--------------------
user posted image
PM MAIL   Вверх
Sannis
Дата 15.8.2007, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.8.2007
Где: Москва

Репутация: 1
Всего: 13



Во-первых, нужно фильтровать ввод, функции может не существовать или быть другое количество параметров, а во-вторых проблема не в том как вызвать, а как раз наоборот, как из строки вызова определить параметры.


--------------------
Я Критик Джим, раньше писал моды для IPB 1.3.x-2.3.x, а теперь продвигаю Node.js в массы.
PM MAIL WWW   Вверх
Glip
Дата 15.8.2007, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 473
Регистрация: 30.12.2006

Репутация: 1
Всего: 18



func_ get_ arg
func_ get_ args
func_ num_ args

или я всетаки не понял задачу.




--------------------
user posted image
PM MAIL   Вверх
Sannis
Дата 15.8.2007, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.8.2007
Где: Москва

Репутация: 1
Всего: 13



Этой функции может и не быть, есть просто строка текста. Представьте что вы пишите интерпретатор.


--------------------
Я Критик Джим, раньше писал моды для IPB 1.3.x-2.3.x, а теперь продвигаю Node.js в массы.
PM MAIL WWW   Вверх
Glip
Дата 15.8.2007, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 473
Регистрация: 30.12.2006

Репутация: 1
Всего: 18



с трудом могу представить зачем мне интерпретатор на php smile
но мысль понял. к сожалению ничего конкретного в таком случае не подскажу.


--------------------
user posted image
PM MAIL   Вверх
WildRAID
Дата 16.8.2007, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.8.2007

Репутация: нет
Всего: нет



Пожалуйста:

Код

<?php
if(!isset($input_str))
{
?>
<html>
<body>
<form method=post>
Введите строку вызова функции:<br>
<input type=text size=80 name='input_str'><br>
<br>
<input type=submit value='Поехали!'>
</form>
</body>
</html>
<?
}
else
{
$func_name = trim(strtok($input_str, "("));
$func_arg_str = trim(strtok(")"));

$tok = trim(strtok($func_arg_str, ","));
$curr_arg = 1;
$dont_quit = 0;
while($tok != "")
{
    $toklen = strlen($tok) - 1;

    if($tok[0] == '"' and $tok[$toklen] == '"')
    {
        $arg[$curr_arg] = substr($tok, 1, $toklen - 1);
    }
    elseif($tok[0] == "'" and $tok[$toklen] == "'")
    {
        $arg[$curr_arg] = substr($tok, 1, $toklen - 1);
    }
    elseif(is_numeric($tok))
    {
        $arg[$curr_arg] = intval($tok);
    }
    else
    {
        echo "Некорректно обозначен аругмент №" . $curr_arg . " ";
        exit();
    }
    $curr_arg++;
    $tok = trim(strtok(","));
}
echo "Имя функции: " . $func_name . "<br>";
foreach($arg as $key=>$value)
{
echo "Аргумент " . $key . ": " . $value . " " . gettype($value) . "<br>";
}
}
?>


Проверить в действии можно здесь:

http://vizjerei.com/function.php

strtok - полезная штука. smile 

Это сообщение отредактировал(а) WildRAID - 16.8.2007, 08:57
PM MAIL   Вверх
Glip
Дата 16.8.2007, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 473
Регистрация: 30.12.2006

Репутация: 1
Всего: 18



ну да, наверное. вот так с ходу: а если в строковом аргументе функции будет запятая?
вероятно получим "Некорректно обозначен аругмент №" ?

ну вот например проверьте printf('%s', 'привет, привет')

надо еще дорабатывать  smile


Цитата(WildRAID @  16.8.2007,  08:55 Найти цитируемый пост)
strtok - полезная штука.

а в чем её преимущества перед explode() или split() ?


Это сообщение отредактировал(а) Glip - 16.8.2007, 09:48


--------------------
user posted image
PM MAIL   Вверх
WildRAID
Дата 16.8.2007, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.8.2007

Репутация: нет
Всего: нет



Да, не подумал об этом. smile 

Цитата

а в чем её преимущества перед explode() или split() ?


Только в том, что она описана в той небольшой книжке по php, которая у меня есть. ;) Пока учусь, заодно форумы читаю.

Ушел искать информацию про explode() и split().
PM MAIL   Вверх
GiV
Дата 17.8.2007, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 13.7.2006
Где: rus|53

Репутация: 2
Всего: 9



Если идти путем вложенных функций, то что-то вроде этого
Код

<?php
$str = 'test(change("1", privet(\'ass\', "aaa", 566 , \'rr\'), 123), ttt(123));';
$str = 'ddd(11,test(\'ass\', "aaa", re(222,444), 566 , \'rr\'), 2222, opppa( "ku", 1sa( false ), 12 ));';
$str = 'change("1", "privet", 123);';

$parsedFunctions = array();
$functions = array();

for ($i=0, $j=-1; $i<=strlen($str); $i++)
{

    if ( $str[ $i ] == ',' OR $str[ $i ] == ' ' OR $str[ $i ] == "'" OR $str[ $i ] == '"' )
    { 
        if ( $lexem )
        {
            $functions[ $j ]['args'][] = $lexem; 
            $lexem = '';
        } 
        
        continue;    
    }
    
    if ( $str[ $i ] == '(' )
    {     
        $function = array('name' => $lexem, 'args' => array());

        if ( count($functions) )
        {     
            $functions[ $j ]['args'][] = 'function_' . $lexem;
        }
                
        $j++; 
                
        array_push( $functions, $function );     
        $lexem = '';
        
        continue;
    }
    
    if ( $str[ $i ] == ')' )
    {
        $function = array_pop($functions); 
        
        $j--;
        
        if ( $lexem )
        {
            $function['args'][] = $lexem;  
            $lexem = '';
        }  
          
        $parsedFunctions[ $function['name'] ] = $function['args'];

        continue;
    }
    
    $lexem .=  $str[ $i ] ;
}

foreach ( $parsedFunctions as $name => $function)
{
    foreach ( $function as  $argPos => $arg )
    {
        if ( strpos($arg, 'function_') === 0 )
        {
            $functionName = str_replace( 'function_', '', $arg );
            $functionParams = implode(',', $parsedFunctions[ $functionName ] );
            $parsedFunctions[ $name ][ $argPos ]  = $functionName . '(' . $functionParams . ')';   
        }
    } 
}

print_r( $parsedFunctions );



Если вложенности не будет то
Код

<?php
$str = 'change("1", "privet", 123);';

preg_match('~([a-zA-Z0-9_]{1,})\((.+?)\)~s', $str, $matches);

print_r($matches);


Это сообщение отредактировал(а) GiV - 17.8.2007, 18:34
PM MAIL WWW ICQ   Вверх
GiV
Дата 17.8.2007, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 13.7.2006
Где: rus|53

Репутация: 2
Всего: 9



Разделители внутри параметров

Код

<?php
$str = 'test(change("1", privet(\'ass\', "aaa", 566 , \'rr\'), 123), ttt(123));';
//$str = 'ddd(11,test(\'ass\', "aaa", re(222,444), 566 , \'rr\'), 2222, opppa( "ku", 1sa( false ), 12 ));';
$str = 'change("\' 1 32323", "pr\'i\'vet",  \'ddd"\', 123);';

$parsedFunctions = array();
$functions = array();

for ($i=0, $j=-1; $i<=strlen($str); $i++)
{

    if ( $str[ $i ] == "'" )
    {
        $apostopheOpened =  !$apostopheOpened;   
    }
    
    if ( $str[ $i ] == '"' )
    {
        $quoteOpened =  !$quoteOpened;
    }
    
    if ( $str[ $i ] == ',' OR $str[ $i ] == ' ' AND ( !$apostopheOpened OR !$quoteOpened )  )
    { 
        if ( $lexem )
        {
            $functions[ $j ]['args'][] = $lexem; 
            $lexem = '';
        } 
        
        continue;    
    }
    
    if ( $str[ $i ] == '(' )
    {     
        $function = array('name' => $lexem, 'args' => array());

        if ( count($functions) )
        {     
            $functions[ $j ]['args'][] = 'function_' . $lexem;
        }
                
        $j++; 
                
        array_push( $functions, $function );     
        $lexem = '';
        
        continue;
    }
    
    if ( $str[ $i ] == ')' )
    {
        $function = array_pop($functions); 
        
        $j--;
        
        if ( $lexem )
        {
            $function['args'][] = $lexem;  
            $lexem = '';
        }  
          
        $parsedFunctions[ $function['name'] ] = $function['args'];

        continue;
    }
    
    $lexem .=  $str[ $i ] ;
}

foreach ( $parsedFunctions as $name => $function)
{
    foreach ( $function as  $argPos => $arg )
    {
        if ( strpos($arg, 'function_') === 0 )
        {
            $functionName = str_replace( 'function_', '', $arg );
            $functionParams = implode(',', $parsedFunctions[ $functionName ] );
            $parsedFunctions[ $name ][ $argPos ]  = $functionName . '(' . $functionParams . ')';   
        }
    } 
}

print_r( $parsedFunctions );

PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 17.8.2007, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Код

function parseFunc($string)
{
   $result = array("FuncName" => "", "Args" => array());
   $tokens = token_get_all("<?php function $string ?>");
   if ($tokens[3][0] != T_STRING) return false;
   $result["FuncName"] = $tokens[3][1];
   for($i = 5; $i < count($tokens) - 4; $i++)
   {
      if (is_array($tokens[$i]))
      {
         switch($tokens[$i][0])
         {
            case T_CONSTANT_ENCAPSED_STRING :
            case T_LNUMBER :
            case T_STRING :
            case T_VARIABLE :
               $result["Args"][] = $tokens[$i][1];
         }
      }
   }
   return $result;
}

$str = 'change("1\'", "privet\"", \'str\', 3, 04, 0xF5, true, CONSTANT,$variable);';
var_dump(parseFunc($str));

Здесь не проверяется корректность аргументов, но это уже легко доработать.
PM MAIL   Вверх
Sannis
Дата 26.8.2007, 03:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.8.2007
Где: Москва

Репутация: 1
Всего: 13



GiV, sTa1kEr, Спасибо. Так и склонился к версии писать анализалор самому, регулярками тут не обойтись. 3 странички в блокноте, было чем на пляжу заняться, дебаг на бумаге - красота smile


--------------------
Я Критик Джим, раньше писал моды для IPB 1.3.x-2.3.x, а теперь продвигаю Node.js в массы.
PM MAIL WWW   Вверх
Sannis
Дата 29.8.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.8.2007
Где: Москва

Репутация: 1
Всего: 13



sTa1kEr, а библиотека токенайзера вкомпилирована в ядро PHP4/5 или его может не быть на некоторых серверах?


--------------------
Я Критик Джим, раньше писал моды для IPB 1.3.x-2.3.x, а теперь продвигаю Node.js в массы.
PM MAIL WWW   Вверх
sTa1kEr
Дата 30.8.2007, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Цитата(Sannis @  29.8.2007,  23:27 Найти цитируемый пост)
sTa1kEr, а библиотека токенайзера вкомпилирована в ядро PHP4/5 или его может не быть на некоторых серверах? 

Вероятность что она будет не доступна крайне мала. Только если специально при компиляции отключить. Tokenizer Functions
Цитата

Requirements
No external libraries are needed to build this extension.

Installation
Beginning with PHP 4.3.0 these functions are enabled by default. For older versions you have to configure and compile PHP with --enable-tokenizer. You can disable tokenizer support with --disable-tokenizer. 

The windows version of PHP has built in support for this extension. You do not need to load any additional extension in order to use these functions.

Note: Built-in support for tokenizer is available as of PHP 4.3.0. 



Это сообщение отредактировал(а) sTa1kEr - 30.8.2007, 08:34
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.0601 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.