$ENTRY Go { = <Open 'w' 5 'testtime.txt'> <Putout 5 <TIME >> <XI ('xi9.xsl')> <Putout 5 <TIME >> ; } /* Интерпретатор XSLT, написанный с целью его суперкомпиляции. Экспериментальная версия, обладающая рядом недостатков: - не обрабатываются тэги вида <! ... > , <? ... ?>, - условные операторы, - сортировка. Проще перечислить, что обрабатывается - это видно по тексту программы. */ * Функции, используемые на этапе суперкомпиляции. * Преобразование в составные символы: $EXTRN XiImpl; *$EXECUTABLE XiImpl; * Обращение к парсеру из XML в рефал: $EXTRN XML_REF2; *$EXECUTABLE XML_REF2; * Функции, используемые на этапе исполнения * построенной суперкомпилятором программы. * Реализация (xsl:value-of select= e.Tag): $EXTRN Get_In; * Парсер в рефал-выражение: $EXTRN XML_REF1; * Парсер из рефала в XML: $EXTRN REF_XML; /* Один из способов организации работы суперкомпилятора на неигрушечном примере. e.NameXSLT - наименование файла e.XSLT, содержащего трансформации, e.NameXML - наименование трансформируемого файла e.XML. Оба они преобразутся парсером в рефал-выражение, но e.XSLT на этапе суперкомпиляции, а e.XML на этапе выполнения порожденной SCP4 программы. Поэтому приходится вынужденно вводить два имени функции парсера XML_REF. REF_XML - обратный парсер, переводит результат работы программы, порожденной SCP4, в XML. */ XI { (e.NameXSLT) , <XML_REF2 e.NameXSLT>: e.XSLTa , <XiImpl e.XSLTa>: e.XSLT , <XML_REF1 >: e.XML = <REF_XML <XIBegin (e.XSLT) (e.XML) >>; } XIBegin { (((Xsl Stylesheet e.1) e.2)) (e.XML) = <Apply Fict (e.2) (e.XML) (e.2)>; } * Нахождение (Xsl Template (Match Is s.Tag1)) * Формат обращения: * <Apply s.Tag (e.XSLT) (e.XML) (e.ALL)> * где s.Tag - текущий тэг, * e.All - начальный e.XSLT, который не меняется * в процессе суперкомпиляции. Apply { s.Tag (e.XSLT) (s.a e.1) (e.All) = s.a <Apply s.Tag (e.XSLT) (e.1) (e.All)>; s.Tag (e.XSLT) ( ) (e.All) = ; s.Tag (((Xsl Template (Match Is s.Tag s.Tag1)) e.1) e.2) (((s.Tag1) e.In) e.on) (e.All) = <Int s.Tag1 (e.1) (e.In) (e.All)> <Apply s.Tag (e.All) (e.on) (e.All)>; s.Tag (((Xsl Template (Match Is s.Tag1 s.Tag2)) e.1) e.2) (((s.Tag3) e.In) e.on) (e.All) = <Apply s.Tag (e.2) (((s.Tag3) e.In) e.on) (e.All)>; s.Tag (((Xsl Template (Match Is s.Tag1)) e.1) e.2) (((s.Tag1) e.In) e.on) (e.All) = <Int s.Tag1 (e.1) (e.In) (e.All)> <Apply s.Tag (e.All) (e.on) (e.All)>; s.Tag (((Xsl Template (Match Is s.Tag1)) e.1) e.2) (((s.Tag2) e.In) e.on) (e.All) = <Apply s.Tag (e.2) (((s.Tag2) e.In) e.on) (e.All)>; s.Tag ( ) (((s.Tag2) e.In) e.on) (e.All) = <Apply s.Tag (e.All) (e.on) (e.All)>; } * Интерпретатор одного (Xsl Template (Match Is s.Tag1)) Int { s.Tag ( ) (e.XML) (e.All) = ; s.Tag (s.a e.1) (e.XML) (e.All) = s.a <Int s.Tag (e.1) (e.XML) (e.All)>; s.Tag (((Xsl e.XSLT) e.2) e.3) (e.XML) (e.All) = <IntXsl s.Tag ((Xsl e.XSLT) e.2) (e.XML) (e.All)> <Int s.Tag (e.3) (e.XML) (e.All)>; s.Tag (((e.1) e.2) e.3) (e.XML) (e.All) = ((e.1) <Int s.Tag (e.2) (e.XML) (e.All)> ) <Int s.Tag (e.3) (e.XML) (e.All)>; } * Обработка одного правила трансформаций IntXsl { s.Tag ((Xsl Apply-templates)) (e.XML) (e.All) = <Apply s.Tag (e.All) (e.XML) (e.All)>; s.Tag ((Xsl Element (Name Is e.N)) e.1) (e.XML) (e.All) = <Elem (e.N) <Int s.Tag (e.1) (e.XML) (e.All)>>; s.Tag ((Xsl Attribute (Name Is e.N)) e.1) (e.XML) (e.All) = (Attr e.N Is <Int s.Tag (e.1) (e.XML) (e.All)>); s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) (((s.Tag1 e.0) e.In) e.on) (e.All) = <Int s.Tag1 (e.1) (e.In) (e.All)> <IntXsl s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) (e.on) (e.All)>; s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) ((e.In) e.on) (e.All) = <IntXsl s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) (e.on) (e.All)>; s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) ( ) (e.All) = ; s.Tag ((Xsl Value-of (Select Is e.Tag1))) (e.In) (e.All), <Get_In (e.Tag1) e.In>:e.n = e.n; * e.1 = e.1; } Elem { * только один Attribute (e.N) (Attr e.1) e.2 = ((e.N (e.1)) e.2); }