From 45f3196c8f49b4103d467fc99f138ce5e564858d Mon Sep 17 00:00:00 2001 From: buraq Date: Wed, 26 May 2004 13:26:22 +0000 Subject: fixes --- .../tools/scalac/ast/parser/MarkupParser.scala | 100 +++++++++++++++++++-- .../scala/tools/scalac/ast/parser/Scanner.scala | 60 +++++++++++-- sources/scala/xml/ProcInstr.scala | 26 ++++-- sources/scala/xml/Utility.scala | 4 +- 4 files changed, 169 insertions(+), 21 deletions(-) (limited to 'sources') diff --git a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala index 66f9c96a62..19ecbf1194 100644 --- a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala +++ b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala @@ -34,7 +34,12 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { val _append = Name.fromString("append"); val _collection = Name.fromString("collection"); val _xml = Name.fromString("xml"); + val _Comment = Name.fromString("Comment"); + val _CharData = Name.fromString("CharData"); val _Node = Name.fromString("Node"); + val _None = Name.fromString("None"); + val _Some = Name.fromString("Some"); + val _ProcInstr = Name.fromString("ProcInstr"); val _Text = Name.fromString("Text"); val _EntityRef = Name.fromString("EntityRef"); @@ -53,6 +58,14 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { private def _scala_Seq( pos: int ) = p.convertToTypeId( _scala( pos, _Seq )); + + private def _scala_None( pos: int ) = + _scala( pos, _None ) ; + + private def _scala_Some( pos: int ) = + p.convertToConstr( _scala( pos, _Some )); + + private def _string( pos: int ) = p.convertToTypeId( make.Ident( pos, _String ) ); @@ -62,12 +75,23 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { private def _scala_xml_Node( pos: int ) = _scala_xml( pos, _Node ); - private def _scala_xml_Text( pos: int ) = - p.convertToConstr( _scala_xml( pos, _Text )); private def _scala_xml_EntityRef( pos: int ) = p.convertToConstr( _scala_xml( pos, _EntityRef )); + private def _scala_xml_Comment( pos: int ) = + p.convertToConstr( _scala_xml( pos, _Comment )); + + private def _scala_xml_CharData( pos: int ) = + p.convertToConstr( _scala_xml( pos, _CharData )); + + private def _scala_xml_ProcInstr( pos: int ) = + p.convertToConstr( _scala_xml( pos, _ProcInstr )); + + private def _scala_xml_Text( pos: int ) = + p.convertToConstr( _scala_xml( pos, _Text )); + + private def _scala_collection( pos: int, name: Name ) = make.Select( pos, _scala( pos, _collection ), name ); @@ -153,6 +177,37 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { def makeText( pos: int, txt:String ):Tree = makeText( pos, gen.mkStringLit( pos, txt )); + // create + def makeComment( pos: int, comment:scala.xml.Comment ):Tree = + makeComment( pos, gen.mkStringLit( pos, comment.text )); + + // create + def makeCharData( pos: int, charData:scala.xml.CharData ):Tree = + makeCharData( pos, gen.mkStringLit( pos, charData.text )); + + // create scala.xml.Text here <: scala.xml.Node + def makeProcInstr( pos: int, procInstr:scala.xml.ProcInstr ):Tree = + procInstr.text match { + case Some(txt) => + makeProcInstr( pos, + gen.mkStringLit( pos, procInstr.target ), + makeSome( pos, gen.mkStringLit( pos, txt ))); + case _ => + makeProcInstr( pos, + gen.mkStringLit( pos, procInstr.target ), + makeNone( pos )); + } + + def makeNone( pos: int ):Tree = _scala_None( pos ); + + def makeSome( pos: int, txt:Tree ):Tree = { + val constr = make.Apply( pos, + _scala_Some( pos ), + Predef.Array[Tree] ( txt )); + make.New( pos, constr ); + } + + def makeText( pos: int, txt:Tree ):Tree = { val constr = make.Apply( pos, _scala_xml_Text( pos ), @@ -160,6 +215,28 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { make.New( pos, constr ); } + def makeCharData( pos: int, txt:Tree ):Tree = { + val constr = make.Apply( pos, + _scala_xml_CharData( pos ), + Predef.Array[Tree] ( txt )); + make.New( pos, constr ); + } + + def makeComment( pos: int, txt:Tree ):Tree = { + val constr = make.Apply( pos, + _scala_xml_Comment( pos ), + Predef.Array[Tree] ( txt )); + make.New( pos, constr ); + } + + def makeProcInstr( pos: int, target:Tree, txt:Tree ):Tree = { + val constr = make.Apply( pos, + _scala_xml_ProcInstr( pos ), + Predef.Array[Tree] ( target, txt )); + make.New( pos, constr ); + } + + def makeXMLpat(pos:int, n:Name, args:Array[Tree]):Tree = mkXML(pos, true, gen.mkStringLit( pos, n.toString() ), args); @@ -319,10 +396,11 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { * the caller has to resynchronize with s.token = EMPTY; s.nextToken; */ def xExpr:Tree = { - val pos = s.pos; + var pos = s.pos; val Tuple2( elemName, attrMap ) = xTag; if( s.ch == '/' ) { // empty element - s.xToken('/'); s.xToken('>'); + s.xToken('/'); + s.xToken('>'); makeXML( pos, elemName, Tree.EMPTY_ARRAY, attrMap ); } else { // handle content s.xToken('>'); @@ -332,14 +410,22 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser ) { if( s.xScalaBlock ) { ts.append( xScalaExpr ); } else { + pos = s.pos; s.ch match { - case '<' => // another tag s.xNext; s.ch match { case '/' => exit = true; // end tag - case '!' => val _ = s.xComment; - case _ => ts.append( xExpr ); // parse child + case '!' => + s.xNext; + if( '[' == s.ch ) // CDATA + ts.append( makeCharData( pos, s.xCharData )); + else // comment + ts.append( makeComment( pos, s.xComment )); + case '?' => // PI + s.xNext; + ts.append( makeProcInstr( pos, s.xProcInstr )); + case _ => ts.append( xExpr ); // child } case '{' => diff --git a/sources/scala/tools/scalac/ast/parser/Scanner.scala b/sources/scala/tools/scalac/ast/parser/Scanner.scala index cbcbe48bd6..9b3646c032 100644 --- a/sources/scala/tools/scalac/ast/parser/Scanner.scala +++ b/sources/scala/tools/scalac/ast/parser/Scanner.scala @@ -1114,27 +1114,77 @@ class Scanner(_unit: Unit) extends TokenData { new String( Predef.Array[char]( i.asInstanceOf[char] )) } + /** '"{char} ) ']]>' + * + * see [15] + */ + def xCharData:scala.xml.CharData = { + xToken('['); + xToken('C'); + xToken('D'); + xToken('A'); + xToken('T'); + xToken('A'); + xToken('['); + val sb:StringBuffer = new StringBuffer(); + while (true) { + if( ch==']' && + { sb.append( ch ); xNext; ch == ']' } && + { sb.append( ch ); xNext; ch == '>' } ) { + sb.setLength( sb.length() - 2 ); + xNext; + return scala.xml.CharData( sb.toString() ); + } else sb.append( ch ); + xNext; + } + return null; // this cannot happen; + }; + + /** Comment ::= '' * * see [15] */ - def xComment:String = { + def xComment:scala.xml.Comment = { val sb:StringBuffer = new StringBuffer(); - xToken('!'); xToken('-'); xToken('-'); while (true) { - xNext; if( ch=='-' && { sb.append( ch ); xNext; ch == '-' } ) { sb.setLength( sb.length() - 1 ); xNext; xToken('>'); - return sb.toString(); + return scala.xml.Comment( sb.toString() ); } else sb.append( ch ); + xNext; } - return ""; // this cannot happen; + return null; // this cannot happen; }; + /** '?' {Char})]'?>' + * + * see [15] + */ + def xProcInstr:scala.xml.ProcInstr = { + val sb:StringBuffer = new StringBuffer(); + val n = xName; + if( xIsSpace ) { + xSpace; + while( true ) { + if( ch=='?' && { sb.append( ch ); xNext; ch == '>' } ) { + sb.setLength( sb.length() - 1 ); + xNext; + return scala.xml.ProcInstr( n.toString(), Some(sb.toString()) ); + } else + sb.append( ch ); + xNext; + } + }; + xToken('?'); + xToken('>'); + scala.xml.ProcInstr( n.toString(), None ); + } + /** munch expected XML token, report syntax error for unexpected */ def xToken(that:char):unit = { diff --git a/sources/scala/xml/ProcInstr.scala b/sources/scala/xml/ProcInstr.scala index 159c5a18d9..9b27e489fb 100644 --- a/sources/scala/xml/ProcInstr.scala +++ b/sources/scala/xml/ProcInstr.scala @@ -16,7 +16,7 @@ package scala.xml; * @param text text contained in this node, may not contain "?>" **/ -case class ProcInstr( target:String, text:String ) extends Node { +case class ProcInstr( target:String, text:Option[String] ) extends Node { val z:Seq[Char] = target; z match { case Seq('X'|'x','M'|'m','L'|'l') => @@ -25,9 +25,11 @@ case class ProcInstr( target:String, text:String ) extends Node { } if( !Utility.isName( target ) ) throw new IllegalArgumentException(target+" must be an XML Name"); - else if( text.indexOf("?>" ) != -1 ) - throw new IllegalArgumentException(text+" may not contain \"?>\""); - + else text match { + case Some(txt) => if( txt.indexOf("?>" ) != -1 ) + throw new IllegalArgumentException(txt+" may not contain \"?>\""); + case _ => + } /** the constant "#PI" */ final def label = "#PI"; @@ -41,7 +43,17 @@ case class ProcInstr( target:String, text:String ) extends Node { /** hashcode for this PI */ override def hashCode() = target.hashCode() * 7 + text.hashCode(); - /** returns "" */ - final override def toString() = ""; - + /** returns "" */ + final override def toString() = { + val sb = new StringBuffer(" + sb.append(' '); + sb.append(txt); + case _ => + }; + sb.append("?>"); + sb.toString() + } } diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala index dea4edc354..aab2f6b63f 100644 --- a/sources/scala/xml/Utility.scala +++ b/sources/scala/xml/Utility.scala @@ -41,7 +41,7 @@ object Utility { def toXML( n:Node ):String = n match { case Text( t ) => escape( t ); - case _:EntityRef => + case _:EntityRef | _:Comment | _:ProcInstr => n.toString(); case _ => val s = new StringBuffer(); @@ -54,7 +54,7 @@ object Utility { def toXML( n:Node, s:StringBuffer ):Unit = n match { case Text( t ) => s.append( escape( t ) ); - case _:EntityRef => + case _:EntityRef | _:Comment | _:ProcInstr => s.append( n.toString() ); case x:Node => { s.append('<'); -- cgit v1.2.3