|
|
|
| Доброе время суток, уважаемые форумчане, у меня в настоящее время возникла некторая проблема, помощь в решении которой хотелось бы услышать :)))
Есть строчка:
operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );
|
есть выражение:
'#([a-z0-9\._@]+)|[.,;+-/=*]|(\(.+\))|(\[.+\])|\"[^\"]*\"#i'
|
и получается результат:
Array
(
[0] => operator
[1] => @var_type
[2] => @var_name
[3] => [ = @var_data ] (, @var_type @var_name [ = @var_data ]
[4] => ;
)
|
возникла проблема, что первые квадратные скобки должны быть в 3 строчке, следом круглые скобки и всё их содержимое в 4 позиции и в пятой точка с запятой.
при всех моих попытках объеденяются скобки, помогите в решении сией задачи.
Попутно возникает вопрос, как можно выделить кавычки и пропустить в исходной строчке последовательность \" ?
Заранее премного благодарен, с уважением, Kotsugai. | |
|
|
|
|
автор: xx7 (26.01.2009 в 23:05) |
|
|
для: kotsugai
(26.01.2009 в 21:12)
| | не понятно есть-ли только эта такая строка
, или есть текст содержащий массу таких и других строк.
По вопросу похоже на реализацию подсветки синтаксиса , какого-то из языков программирования ,
такое наверное не сделать одним выражением .
под \* имелось ввиду что-то типа /*таких*/ комментариев ?
А так просто в выражении \[.+\] жадный модификатор + , который вберёт всё до последней закрывающей \]
, можно инвертировать жадность как "+?" | |
|
|
|
|
автор: xx7 (26.01.2009 в 23:09) |
|
|
для: xx7
(26.01.2009 в 23:05)
| | прибавил размеру буквам ,) оказалось \" ;)
тогда не понятно выделять-ли строку в каычках , или строку в скобках , если какая-либо из строк внутри другой строки | |
|
|
|
|
|
|
|
для: xx7
(26.01.2009 в 23:05)
| | А так просто в выражении \[.+\] жадный модификатор + , который вберёт всё до последней закрывающей \]
+ ставил для того, чтобы повторялся оператор точка, по поводу жадности не знал, спасибо
по поводу языка программирования, ты почти попал в точку, мне нужно разделить символы на группы и то что в скобках и кавычках я потом повторно просканирую, потому мне нужно чтобы
скобки были парными
по поводу груп строчек и кавычек мне нужно, чтобы выделялись кавычки с пропуском последовательностей \"
чтобы в кавычках шло как одно целое также со скобками
поясню:
[ = @var_data ] (, @var_type @var_name [ = @var_data ] );
отделить первую группу скобок от второй
[ = @var_data ]
и вторая:
(, @var_type @var_name [ = @var_data ] )
и в случае парных скобок (выражение, (выражение)) не определял как
(выражение, (выражение)
или
(выражение)) | |
|
|
|
|
|
|
|
для: kotsugai
(27.01.2009 в 11:40)
| | также удовлетворю твоё любопытсво
вот примеры анализируемых строчек:
operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );
create number num_1;
operator variable var_1;
operator var_1,var_2=34868.0,var_3;
duplicate @array[var1,var2,(var3)];
print "qwrqwr qwrqwr", "wetwet\wet", @array[34];
|
у меня строчка разделяется на более мелкие группы - срез (знаки припинания, слова, то что в скобках )
потом то же делается для маски и затем сверяются оба среза
если ни одна из масок не совпадает с исходным утверждением, оператор не существует
для синтаксиса проверка более простая, делается срез выражения, в исходной строке исключаются повторные пробелы и лишние знаки, затем идет сверка обоих строк
если они совпадают, то синтаксис верный, если нет - ошибка :))))
прототип языка - MySQL, пришлось на нем программировать и есть изъяны, которые нынче собираюсь исправить и улучшить | |
|
|
|
|
автор: xx7 (27.01.2009 в 18:25) |
|
|
для: kotsugai
(27.01.2009 в 11:45)
| | >по поводу жадности не знал, спасибо
да ладно, не стОит ,) тем-более я незаметивши обозвал квантификатор (оператор повторения)
, модификатором :)
Насчёт анализа строк, думаю такое лучше делать на perl или на си.
В php немного затёрто понятие строки как массива , нет возможности обратиться к части строки начиная с нужного индекса, а только к символу , как $string{$x}, или можно просто получить чакть как substr($string, $x)
С выражениями примерно так-же , нет циклов где можно было-бы обрабаывать каждое совпадение
и изменять по мере надобности само выражение в условии цикла
, а есть только такие "полуавтоматы"( незнаю правильно-ли обозвал :))
, как например preg_replace_callback()
можно сделать типа цикла, в простейшем случае например такого
<pre style="font:normal 105% Lucida Console"><?
$txt = 'operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );
create number num_1;
operator variable var_1;
operator var_1,var_2=34868.0,var_3;
duplicate @array[var1,var2,(var3)];
print "qwrqwr qwrqwr\"\\\\", "w\"et\we", @array[34];
';
$str = '([\'"])(?>(?:\x5c.|(?!\1).)?[^\x5c"\']*)+\1\s*';
$ind = '\[[^\]]*\]\s*';
$re2 = '#' . $str . '|' . $ind .'|([\.0-9]+)'
.'|(@?[A-Za-z][0-9A-Z_a-z]*)|([,;=])#';
function xpars($m){
print_r($m);
static $opr = false; // оператора небыло
$color = ($opr) ? 'darkred': 'darkblue';
if (!isset($m[1])) return '<i style="color:blue">'
. $m[0] .'</i>';
if ($m[1]) return '<i style="color:red">'
. $m[0] .'</i>';
if ($m[2]) return '<b style="color:darkgreen">'
. $m[0] .'</b>';
if ($m[3]) {
if (!$opr) {
$opr = true;
}
return '<b style="color:'
. $color .'">'. $m[0] .'</b>';
}
if ($m[4]) {
if ($m[0] == ';') $opr = false;
return '<b style="font:bold 130% impact">'
. $m[0] .'</b>';
}
return $m[0];
}
print $txt = preg_replace_callback($re2, 'xpars', $txt);
?>
|
Но получается у меня чем качественнее пытаюсь разобрать такое, тем медленнее всё это работает
само по себе построение шаблона как набор альтернатив 'первое|второе|третье|......' неслабо замедляет всё это дело
плюс ещё пожоже придётся использовать ещё вызовы preg_функций() внутри callback-функции
, например чтобы не искать так оператор среди одинаковых слов, а выбрать вса слова и обозначить какое для чего.
, или для разбора @array[@var[1], var2[2][1]] , придётся использовать (?(R)) в шаблоне , что тоже не намного облегчит анализ .
Ещё и не видно пока операторов кроме "=" , а думаю они наверняка есть
полностью всё правильно разобрать в таких более-менее сложных синтаксисах, можно только воссоздав логику самого интерпритатора этих комманд,
(а они обычно используют или посимвольное чтение , или например сишную sscanf()),
или заставить сам интерпритатор разобрать всё это | |
|
|
|
|
автор: xx7 (27.01.2009 в 18:30) |
|
|
для: xx7
(27.01.2009 в 18:25)
| | >понятие строки как массива
наверное жотел сказать что затёрто понятие работы с указателями :) | |
|
|
|
|
|
|
|
для: xx7
(27.01.2009 в 18:30)
| | во спс, ток я несколько проще сделал, покапался и узнал про такую хорошую вещь, как рекурсия, вот что вышло:
function id_analyse($message)
{
$msk1 = '(@?[\w\d_.]+)'; // операторы и переменные
$msk2 = '(\d+(,\d+)?)'; // числа
$msk3 = '[.,;+-/=*]'; // разделители и операторы
$msk4 = '\(((?>[^()]+)|(?R))*\)'; // круглые скобки
$msk5 = '\[((?>[^\[\]]+)|(?R))*\]'; // квадратные скобки
preg_match_all ('#'.$msk1.'|'
.$msk2.'|'
.$msk3.'|'
.$msk4.'|'
.$msk5.'|\"[^\"]*\"#i',$message,$buff);
//preg_match_all('#"([^"])*"#i',$message,$buff);
echo '<pre>'.$message.'<br>';
print_r($buff[0]);
echo '</pre><hr>';
return $buff[0];
}
|
правд со скобками запарка вышла :(
не срабатывает на строчке
print "qwrqwr qwrqwr", "wetwet\"wet", @array[34];
|
и числа всеж в мск_1 проверяются :)))))
т.е. пройдут числа 23.34_wqr | |
|
|
|
|
автор: xx7 (28.01.2009 в 01:00) |
|
|
для: kotsugai
(28.01.2009 в 00:09)
| | есть несколько способов пропускать заэкранированное
, типа такого например
<?
'#'.$msk1.'|'
.$msk2.'|'
.$msk3.'|'
.$msk4.'|'
.$msk5.'|'
.'"(?>(?:\x5c.)?[^\x5c"]*)+"#i'
|
только со слэшами всё время непонятки, даже если строка в апострофах , нужно ставить в ней два двойных, чтобы получить двойной слэш
и в php , почему-то у меня многое только получается только если в выражениях ставить \x5c вместо слэша
(с подмасками тоже замечал баги , но щас точно не воспроизведу) | |
|
|
|
|
автор: xx7 (28.01.2009 в 01:08) |
|
|
для: kotsugai
(28.01.2009 в 00:09)
| | [\w\d_.] не совсем точно [\w\.] это то-же самое
[.,;+-/=*] здесь лучше всё экранировать , например "-" будет понят как диапазон символов от + до /
и модификатор ./i наверное не нужен | |
|
|
|
|