parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Опять проблемы с antistatic (обработка блоков)

Pa1n 18.09.2005 21:13

В продолжении к http://www.parser.ru/forum/?id=44562
Хочу сказать спасибо всем за ответы.А теперь к делу:
#################################################################################################
# грузит + кеширует + процессит + исполняет код обработчика
@prepareProcesess[dataProcessID][dataProcessMain;dataProcessFileName;dataProcessFile;dataProcessBody]
# обработчик может быть еще не загружен
^if(!$PROCESSES.[$dataProcessID].processBodyLoaded){
#	замена имени @main[...] обработчика
	$dataProcessMain[process_${dataProcessID}_main]
	^try{
#		полный путь до обработчика
		$dataProcessFileName[${SYSTEM.processDir}$PROCESSES.[$dataProcessID].filename]
		$dataProcessFile[^file::load[text;$dataProcessFileName]]
#		тело обработчика
		$dataProcessBody[^taint[as-is][$dataProcessFile.text]]
	
#		компиляция обработчика в текущем (класс engine) контексте
		^process{@${dataProcessMain}^[blockParam^;blockBody^]
$dataProcessBody}[
#			$.main[$dataProcessMain]
			$.file[$dataProcessFileName]
			]
			
#		добавление информации в хеш о main dataProcess
		$PROCESSES.[$dataProcessID].main[$$dataProcessMain]
	}{
#		что-то случилось при чтении и компиляции
#		для использования в debug целях закомментировать
		$exception.handled(1)
	}
#	в любом случае сохранить, что была предзагрузка
#	никогда не приведет к повторной компиляции обработчика
	$PROCESSES.[$dataProcessID].processBodyLoaded(1)

}
#end @prepareProcesess[]
#################################################################################################
# запуск обработчиков объектов
# в принципе, то-же самое что executeBlock, но обработчику объекта может сваиться от передачи ему пустых параметров :) 
@executeProcess[dataProcessID]
# подготовка обработчика к использованию
^prepareProcesess[$dataProcessID]
# запуск обработчика
^if($PROCESSES.[$dataProcessID].main is junction){
# запуск обработчика
	$result[^PROCESSES.[$dataProcessID].main[]]
}{
#	нужно убрать кактус с подоконника
	$result[]
}
#end @executeProcess[]



#################################################################################################
# запуск обработчиков блоков
@executeBlock[dataProcessID;blockParam;blockBody]
# подготовка обработчика к использованию
^prepareProcesess[$dataProcessID]
# запуск обработчика
^if($PROCESSES.[$dataProcessID].main is junction){
	$result[^PROCESSES.[$dataProcessID].main[$blockParam;$blockBody]]
}{
	$result[]
}
#end @executeBlock[]
#################################################################################################
@printBlock[blockFields][data]
^if(^blockFields.is_not_empty.int(0)){

#	сбор параметров блока
	$blockParams[^parseBlockParams[$blockFields.attr]]
#	сбор тела
	$blockData[^taint[as-is][$blockFields.data]]

#	передача управления обработчику блока (если есть)
	^if(^blockFields.data_process_id.int(0)){
		$blockData[^executeBlock[$blockFields.data_process_id;$blockParams;$blockData]]	
	}
#	замена спец конструкций в теле блока
	$blockData[^parseBlockPostProcess[$blockParams;$blockData]]

#	вывод блока
	$result[<$blockFields.name>$blockData</$blockFields.name>]
}{
#	пустой блок без обработчика
	$result[]
}
#end @printBlock[]



#################################################################################################
# из переданного xml формирует hash с параметрами обработки блока
@parseBlockParams[blockAttr]

# хэш блока
$result[^hash::create[]]

^if(def $blockAttr){
	^try{
#		xdoc документ с атрибутами блока
		$params[^xdoc::create{<?xml version="1.0" encoding="$request:charset"?>
			<params>
				^taint[as-is][$blockAttr]
			</params>
		}]	
#		выборка список параметров
		$params[^params.select[/params/*]]
#		сбор хэша блока
		^for[i](0;$params-1){
			$node[$params.$i]
			$result.[$node.nodeName][$node.firstChild.nodeValue]
		}
	}{
#		если произошла ошибка сборки (обработки) xml
#		как result - пустой хэш
		^if($exception.type eq xml){$exception.handled(1)}
   	}
}
#end @parseBlockParams[]
#################################################################################################
# парсер блоков
# подразумевается вызов из обработчиков объектов
# для обработки блока name контекстного объекта -> ^parseBlock[name]
# для обработки блока name объекта с ID 777 (в его контексте) -> ^parseBlock[name;777]
@parse_block[name;objectID][object;oldObjectID;allBlocks;nameBlocks]

# подмена контекстного объекта
^if(^objectID.int(0) && $objectID != $OBJECT.id){
#	объект подмены
	$object[$OBJECT_HASH.[$objectID]]
	^if(def $object){
#		сохрание id контекстного объекта для будущего сосстановления
		$oldObjectID($OBJECT.id)
#		подмена $OBJECT
		$OBJECT[$object]
	}
}

# загрузка блоков
^if(!$BLOCKS.[$OBJECT.id].isLoaded){
	$allBlocks[^getSqlBlocks[$.where[object_id = $OBJECT.id AND block.is_published = 1]]]
#	хэш блоков по полю name
	$allBlocks[^allBlocks.hash[name][$.distinct[tables]]]
#	добавление блоков к хэш для повторного обращения
	$BLOCKS.[$OBJECT.id][$allBlocks]
#	бит - блоки загружены
	$BLOCKS.[$OBJECT.id].isLoaded(1)
}

# кусок хэша с блоками name
$nameBlocks[$BLOCKS.[$OBJECT.id].[$name]]

^if(def $nameBlocks){
#	обработка найденых блоков
	$result[^nameBlocks.menu{^printBlock[$nameBlocks.fields]}]
}{
#	совсем ничего нет
	$result[]
}

# возврат контекстного объекта
^if($oldObjectID){
#	обратная подмена подмена $OBJECT
	$OBJECT[$OBJECT_HASH.[$oldObjectID]]
}
#end @parse_block[]



#################################################################################################
# для обратой совместимости
@parseBlock[name;objectID]
$result[^parse_block[$name;$objectID]]
#end @parseBlock[]
Поправил немного код теперь обработчику передаётся 2 параметра(blockParam и blockBody).При обработке блока ошибки про maximum parameters больше нет, но появилась другая ошибка:
В работе Parser произошла ошибка:

call canceled - endless recursion detected

Ошибку вызвал этот фрагмент:
if
Ошибка произошла при работе с файлом:

//classes/engine.p, строка номер 352

Вот что говорится в FAQ об этой ошибке:

Подобное сообщение появляется, если парсеру кажется, что код зациклился. Очень часто причиной может быть некорректная или очень глубокая рекурсия (более 1000 вызовов).
Последовательность операций, которая привела к ошибке:
(от самой последней вверху списка до самой первой внизу)

* prepareProcesess: //classes/engine.p строка 407
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
..................................................
И так далее...
Я понял, что код зациклился, но не могу найти причину зацикливания.
Пожалуйста помогите найти причину ошибки, буду очень благодарен.

  • Опять проблемы с antistatic (обработка блоков), Pa1n 18.09.2005 21:13