parser

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

 

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

Класс "Самодокументирование парсерного кода"

Yuriy V. Vorontsov (Че) 24.04.2004 19:18 / 24.04.2004 19:20

Вчера наткнулся на сабж у egr'а на http://www.egoroff.spb.ru.
То ли потому, что не смог зарегистрироваться (ошибка какая-то всё время говорит, что я уже зарегистрирован). То ли потому, что код с сайта странно работал, решил написать свой (всегда так с парсером:)).

Товарищи, посмотрите кому интересно этот класс. Пока он только документирует методы такого вида:
# comment
# xxx
@method[xxx]
...code ...
Такой шаблон в принципе является удовлетворительным, но хочется большего, к тому же может я что-то не учёл...

В планах сделать ещё описание глобальных переменных класса, тех которые будут видны для пользователя (например как, text или name, в классе file), но пока не понимаю, как лучше их документировать...

Итак, кому интересно возьмите код, просто скопируйте в файл (весь код), и запустите:
@default[param1;param2]
$result[^if(def $param1){$param1}{$param2}]


@checked[param;value]
$result[^if($param eq $value || (!def $param && $value eq "0")){checked}]


@main[]
<form method="GET">
	Путь к папке с библиотеками: <input name="library" value="^default[$form:library;/]"><br>
	Маска (в regexp'е): <input name="mask" value="^default[$form:mask;\.p^$]"><br>
	Просмотривать вложенные папки:
		<input type="radio" name="in" id="1" value="1" ^checked[$form:in;1]><label for=1>Да</label> /
		<input type="radio" name="in" id="0" value="0" ^checked[$form:in;0]><label for=0>Нет</label><br>
	<input name="run" type="submit">
</form>

^if(def $form:run){
	<HR width="100%">
	$autodocs[^autodocs::create[
		$.path[$form:library]
		$.mask[^untaint[as-is]{$form:mask}]
		$.in(^form:in.int(0))
	]]
	^autodocs.scan[]
}


###########################
@CLASS
autodocs




@auto[]
$CONTENT[^table::create{path}]




# Конструктор
# 1. init = путь к папку где сканировать
# 2. init.path = путь к папку где сканировать
#    init.mask = маска в regexp
#    init.in = (1/0) открывать вложенные папки
@create[init]
$PATH[/]
$MASK[\.p^$]
$INSIDE(0)

^if($init is string){
	$PATH[$init]
}{
	^if($init is hash){
		^if(def $init.path){
			$PATH[$init.path]
		}

		^if(def $init.mask){
			$MASK[$init.mask]
		}

		^if(def $init.in){
			$INSIDE(^init.in.int(1))
		}
	}{
		^throw[autodocs.create;$init;Входной параметр задан не верно, это может быть string или hash.]
	}
}




# Начать сканирование
@scan[]
^scandir[$PATH]
^if($CONTENT){
	^CONTENT.menu{
		^open[$CONTENT.path]
	}
}
#$result[]




# Рекурсивный просмотр папок
@scandir[folder][folder;list]
$list[^file:list[$folder]] 
^list.menu{
	^if(^list.name.match[$MASK][]){
		^add[$folder/$list.name]
	}

	^if($INSIDE && (-d "$folder/$list.name")){
		^scandir[$folder/$list.name]
	}
}
#$result[]



# Добавить файл в стэк обработки
@add[file]
^CONTENT.append{$file}
#$result[]



# Обрезать ужас моего не знания regexp'а
@cut[string;also]
^if(def $string){
	$result[^string.match[\n$also][g]{}]
}{
	$result[]
}



# Обрезать ужас моего не знания regexp'а и символы комментариев
@change_comment[string]
^if(def $string){
#	$result[^string.match[\n+][g]{^#0D}]
	$result[^string.match[#+][g]{}]
}{
	$result[]
}



@unescape_br[string]
^if(def $string){
	$string[^string.match[\n\n+][g]{<p>}]
	$result[^string.match[\n][g]{<br>}]
}{
	$result[]
}



# открыть файл
@open[file][f;HELP;table;GHELP]
^if(-f $file){	
	$f[^file::load[text;$file]]
	$f[
$f.text
]

	$HELP[^table::create{method	comment}]
	$GHELP[^hash::create[]]

	$table[^f.match[((\n#^[^^\n^]*)*)(\n@^[^^\n^]*)(\n[^^\n]*)][g]]
	$f[]

	^table.menu{
		^if(^table.3.match[@(CLASS|BASE|USE)][]){
			$GHELP.[My^cut[$table.3;@]][
				$.value[^cut[$table.4]]
				$.comment[^change_comment[$table.1]]
			]
		}{
			^HELP.append{^cut[$table.3]	^change_comment[$table.1]}
		}
	}
	$table[]

	^make[$file;$GHELP;$HELP]

	$HELP[]
	$GHELP[]

#	$result[]
}{
	^throw[autodocs.open;$file;;${file}: Такой файл не найден]
}



@make[file;GHELP;HELP][body]
$body[
	^if(def $GHELP.MyCLASS){
		<H1>Класс: $GHELP.MyCLASS.value</H1>

		^if(def $GHELP.MyCLASS.comment){
			<h3>$GHELP.MyCLASS.comment</h3>
		}
	}{
		<H1>Класс: MAIN</H1>
		<h3>Расширение базовых функций Parser3</h3>
	}

	<H2>Файл $file<H2>

	^if($HELP){
		<table border=1>
		^HELP.menu{
			<tr>
				<td align="left" valign="top" width="10%">
					<pre>$HELP.method</pre>
					<ul>^unescape_br[$HELP.comment]</ul>
				</td>
			</tr>
		}
		</table>
	}

	<HR width=100%>
]
$body

#$result[]


  • Класс "Самодокументирование парсерного кода", Yuriy V. Vorontsov (Че) 24.04.2004 19:18 / 24.04.2004 19:20