From 5a665f06544312903e53b9524e844235b871bd08 Mon Sep 17 00:00:00 2001 From: buraq Date: Thu, 5 May 2005 23:21:12 +0000 Subject: scala.xml: markup handler behaviour controlled ... scala.xml: markup handler behaviour controlled by mixin --- config/list/library.lst | 1 + .../scala/xml/parsing/ConstructingHandler.scala | 6 +- sources/scala/xml/parsing/ConstructingParser.scala | 37 +++--------- sources/scala/xml/parsing/MarkupHandler.scala | 53 ++++++++++++---- sources/scala/xml/parsing/MarkupParser.scala | 70 ++++++++++++---------- .../xml/parsing/ValidatingMarkupHandler.scala | 30 ++++++++++ 6 files changed, 120 insertions(+), 77 deletions(-) create mode 100644 sources/scala/xml/parsing/ValidatingMarkupHandler.scala diff --git a/config/list/library.lst b/config/list/library.lst index 670e328265..ff1967ee6a 100644 --- a/config/list/library.lst +++ b/config/list/library.lst @@ -262,6 +262,7 @@ xml/parsing/MarkupParser.scala xml/parsing/FactoryAdapter.scala xml/parsing/NoBindingFactoryAdapter.scala xml/parsing/TokenTests.scala +xml/parsing/ValidatingMarkupHandler.scala xml/path/Expression.scala diff --git a/sources/scala/xml/parsing/ConstructingHandler.scala b/sources/scala/xml/parsing/ConstructingHandler.scala index e62617f933..2810fb1ad5 100644 --- a/sources/scala/xml/parsing/ConstructingHandler.scala +++ b/sources/scala/xml/parsing/ConstructingHandler.scala @@ -1,9 +1,11 @@ package scala.xml.parsing; /** implementation of MarkupHandler that constructs nodes */ -class ConstructingHandler extends MarkupHandler { +abstract class ConstructingHandler(presWS: Boolean) extends MarkupHandler { - def element(pos: int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = + val preserveWS = presWS; + + def elem(pos: int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = Elem(pre, label, attrs, pscope, nodes:_*); diff --git a/sources/scala/xml/parsing/ConstructingParser.scala b/sources/scala/xml/parsing/ConstructingParser.scala index f53a1a7843..cf06398458 100644 --- a/sources/scala/xml/parsing/ConstructingParser.scala +++ b/sources/scala/xml/parsing/ConstructingParser.scala @@ -1,31 +1,8 @@ package scala.xml.parsing ; object ConstructingParser { - def fromSource(inp: scala.io.Source): ConstructingParser = - fromSource(new ConstructingHandler(), inp); - - def fromSource(theHandle: ConstructingHandler, inp: scala.io.Source): ConstructingParser = { - - - val p = new ConstructingParser() { - val input = inp; - override val handle = theHandle; - def nextch = - if(input.hasNext) { - ch = input.next; - pos = input.pos; - } else - eof = true; - - override val preserveWS = true; - - /** report a syntax error */ - def reportSyntaxError(str: String): Unit = { - //Console.println(inp.descr+":"+scala.io.Position.toString(pos)+":"+str); - inp.reportError(pos, str) - } - - }; + def fromSource(inp: scala.io.Source, preserveWS: Boolean) = { + val p = new ConstructingParser(inp, preserveWS); p.nextch; p } @@ -33,11 +10,11 @@ object ConstructingParser { /** an xml parser. parses XML and invokes callback methods of a MarkupHandler */ -abstract class ConstructingParser extends MarkupParser { - - val handle = new ConstructingHandler(); +class ConstructingParser(inp: scala.io.Source, presWS:Boolean) +extends MarkupHandler +with MarkupParser(inp) +with ConstructingHandler(presWS) { - /** this method assign the next character to ch and advances in input */ - def nextch: Unit; + val handle = this; } diff --git a/sources/scala/xml/parsing/MarkupHandler.scala b/sources/scala/xml/parsing/MarkupHandler.scala index c1e5fa7c2e..77d1dfb479 100644 --- a/sources/scala/xml/parsing/MarkupHandler.scala +++ b/sources/scala/xml/parsing/MarkupHandler.scala @@ -1,21 +1,19 @@ package scala.xml.parsing; -import scala.collection.immutable ; -import scala.collection.mutable ; -import scala.collection.Map ; +import scala.xml.dtd._ ; /** class that handles markup - provides callback methods to MarkupParser */ abstract class MarkupHandler { - /** mapping from prefixes to namespaces - var namespace: immutable.Map[String,String] = - new immutable.TreeMap[String,String] - .update("","") - .update("xml","http://www.w3.org/XML/1998/namespace"); - */ + /** returns true is this markup handler is validing */ + val isValidating: Boolean = false; - /** callback method that is invoked by MarkupParser after fully - * parsing element fully. + /** if true, does not remove surplus whitespace */ + val preserveWS: Boolean; + + var decls: List[scala.xml.dtd.Decl] = Nil; + + /** callback method invoked by MarkupParser after parsing an element. * * @param pos the position in the sourcefile * @param pre the prefix @@ -23,14 +21,45 @@ abstract class MarkupHandler { * @param attrs the attributes (metadata) * @param args the children of this element */ - def element(pos: int, pre: String, label: String, attrs: MetaData, scope:NamespaceBinding, args: NodeSeq): NodeSeq; + def elem(pos: int, pre: String, label: String, attrs: MetaData, scope:NamespaceBinding, args: NodeSeq): NodeSeq; + /** callback method invoked by MarkupParser after parsing PI. + */ def procInstr(pos: Int, target: String, txt: String): NodeSeq; + /** callback method invoked by MarkupParser after parsing comment. + */ def comment(pos: Int, comment: String ): NodeSeq; + /** callback method invoked by MarkupParser after parsing entity ref. + */ def entityRef(pos: Int, n: String): NodeSeq; + /** callback method invoked by MarkupParser after parsing text. + */ def text(pos: Int, txt:String): NodeSeq; + def elemDecl(n: String, cmstr: String): Unit = {} + + def attListDecl(name: String, attList: List[AttrDecl]): Unit = {} + + def parameterEntityDecl(name: String, edef: EntityDef): Unit = + decls = ParameterEntityDecl(name, edef) :: decls; + + def parsedEntityDecl(name: String, edef: EntityDef): Unit = + decls = ParsedEntityDecl(name, edef) :: decls; + + def unparsedEntityDecl(name: String, extID: ExternalID, notat: String): Unit = + {} + + def notationDecl(notat: String, extID: ExternalID): Unit = + {} + + def peReference(name: String): Unit = + decls = PEReference( name ) :: decls; + + /** report a syntax error */ + def reportSyntaxError(str: String): Unit; + } + diff --git a/sources/scala/xml/parsing/MarkupParser.scala b/sources/scala/xml/parsing/MarkupParser.scala index 3096e5879d..9297aacbe4 100644 --- a/sources/scala/xml/parsing/MarkupParser.scala +++ b/sources/scala/xml/parsing/MarkupParser.scala @@ -9,23 +9,22 @@ package scala.xml.parsing; +import scala.io.Source; import scala.xml.dtd._ ; + /** an xml parser. parses XML 1.0, invokes callback methods of a MarkupHandler * and returns whatever the markup handler returns. Use ConstructingParser * if you just want to parse XML to construct instances of scala.xml.Node. */ -abstract class MarkupParser with TokenTests { +abstract class MarkupParser(input: Source): MarkupHandler with TokenTests { // // variables, values // - /** the handler of the markup */ + /** the handler of the markup, should return this */ val handle: MarkupHandler; - /** if true, does not remove surplus whitespace */ - val preserveWS: Boolean; - /** holds the position in the source file */ var pos: Int = _; @@ -40,8 +39,6 @@ abstract class MarkupParser with TokenTests { var dtd: DTD = null; - var decls: List[scala.xml.dtd.Decl] = Nil; - var eof: Boolean = false; // @@ -167,13 +164,16 @@ abstract class MarkupParser with TokenTests { //var xEmbeddedBlock = false; /** this method assign the next character to ch and advances in input */ - def nextch: Unit; + def nextch: Unit = { + if(input.hasNext) { + ch = input.next; + pos = input.pos; + } else + eof = true; + } //final val enableEmbeddedExpressions: Boolean = false; - /** report a syntax error */ - def reportSyntaxError(str: String): Unit; - /** munch expected XML token, report syntax error for unexpected */ def xToken(that: Char): Unit = { @@ -431,9 +431,10 @@ abstract class MarkupParser with TokenTests { } /*}*/ } + val list = ts.toList; // 2do: optimize seq repr. new NodeSeq { - val theSeq = ts.toList; + val theSeq = list; } } // content(NamespaceBinding) @@ -491,7 +492,7 @@ abstract class MarkupParser with TokenTests { xToken('>'); this.dtd = new DTD { override var externalID = extID; - override val decls = MarkupParser.this.decls.reverse; + override val decls = handle.decls.reverse; } } @@ -521,9 +522,9 @@ abstract class MarkupParser with TokenTests { Utility.prefix(qname) match { case Some(pre) => val local = qname.substring(pre.length()+1, qname.length()); - handle.element(pos, pre, local, aMap, scope, ts ); + handle.elem(pos, pre, local, aMap, scope, ts ); case _ => - handle.element(pos, null, qname, aMap, scope, ts ); + handle.elem(pos, null, qname, aMap, scope, ts ); } } @@ -667,7 +668,7 @@ abstract class MarkupParser with TokenTests { ch match { case '%' => nextch; - decls = PEReference(xName) :: decls; + handle.peReference(xName); xToken(';'); xSpace; //peReference @@ -721,8 +722,7 @@ abstract class MarkupParser with TokenTests { nextch; val cmstr = cbuf.toString(); cbuf.setLength( 0 ); - val cm = ContentModel.parse(cmstr); - decls = ElemDecl(n, cm)::decls; + handle.elemDecl(n, cmstr); } /** <! attlist := ATTLIST @@ -773,7 +773,7 @@ abstract class MarkupParser with TokenTests { cbuf.setLength(0); } nextch; - decls = AttListDecl(n, attList.reverse) :: decls + handle.attListDecl(n, attList.reverse); } /** <! element := ELEMENT @@ -791,15 +791,14 @@ abstract class MarkupParser with TokenTests { } val n = xName; xSpace; - //Console.println("hello"); - val res = ch match { + ch match { case 'S' | 'P' => //sy val extID = externalID(); if(isParameterEntity) { xSpaceOpt; xToken('>'); - ParameterEntityDecl(n, ExtDef(extID)) + handle.parameterEntityDecl(n, ExtDef(extID)) } else { // notation? @@ -810,26 +809,24 @@ abstract class MarkupParser with TokenTests { val notat = xName; xSpaceOpt; xToken('>'); - UnparsedEntityDecl(n, extID, notat); - } else + handle.unparsedEntityDecl(n, extID, notat); + } else { nextch; - ParsedEntityDecl(n, ExtDef(extID)); - + handle.parsedEntityDecl(n, ExtDef(extID)); + } } case '"' | '\'' => - //Console.println("hello 2"); val av = xAttributeValue(); xSpaceOpt; xToken('>'); - //Console.println("hello 3"); if(isParameterEntity) - ParameterEntityDecl(n, IntDef(av)) + handle.parameterEntityDecl(n, IntDef(av)); else - ParsedEntityDecl(n, IntDef(av)); + handle.parsedEntityDecl(n, IntDef(av)); } - //Console.println("res = "+res); - decls = res :: decls; + + {} } // entityDecl /** 'N' notationDecl ::= "OTATION" @@ -857,7 +854,14 @@ abstract class MarkupParser with TokenTests { error("PUBLIC or SYSTEM expected"); xSpaceOpt; xToken('>'); - decls = NotationDecl(notat, extID) :: decls; + handle.notationDecl(notat, extID) } + /** report a syntax error */ + def reportSyntaxError(str: String): Unit = { + //Console.println(inp.descr+":"+scala.io.Position.toString(pos)+":"+str); + input.reportError(pos, str) + } + + } diff --git a/sources/scala/xml/parsing/ValidatingMarkupHandler.scala b/sources/scala/xml/parsing/ValidatingMarkupHandler.scala new file mode 100644 index 0000000000..a0ee7f4479 --- /dev/null +++ b/sources/scala/xml/parsing/ValidatingMarkupHandler.scala @@ -0,0 +1,30 @@ +package scala.xml.parsing ; + +import scala.xml.dtd._ ; + +abstract class ValidatingMarkupHandler extends MarkupHandler { + + final override val isValidating = true; + + final override def elemDecl(name: String, cmstr: String): Unit = + decls = ElemDecl( name, ContentModel.parse(cmstr)) :: decls; + + final override def attListDecl(name: String, attList: List[AttrDecl]): Unit = + decls = AttListDecl( name, attList) :: decls; + + final override def parameterEntityDecl(name: String, edef: EntityDef): Unit = + decls = ParameterEntityDecl( name, edef) :: decls; + + final override def parsedEntityDecl(name: String, edef: EntityDef): Unit = + decls = ParsedEntityDecl( name, edef) :: decls; + + final override def unparsedEntityDecl(name: String, extID: ExternalID, notat: String): Unit = + decls = UnparsedEntityDecl( name, extID, notat) :: decls; + + final override def notationDecl(notat: String, extID: ExternalID): Unit = + decls = NotationDecl( notat, extID) :: decls; + + final override def peReference(name: String): Unit = + decls = PEReference( name ) :: decls; + +} -- cgit v1.2.3