summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-05-26 13:26:22 +0000
committerburaq <buraq@epfl.ch>2004-05-26 13:26:22 +0000
commit45f3196c8f49b4103d467fc99f138ce5e564858d (patch)
treece032501b4f1ce4ab8a6db9f23bbe63bea54663c /sources
parentca09668e88504786eff94ad778b8c1d23ce9574a (diff)
downloadscala-45f3196c8f49b4103d467fc99f138ce5e564858d.tar.gz
scala-45f3196c8f49b4103d467fc99f138ce5e564858d.tar.bz2
scala-45f3196c8f49b4103d467fc99f138ce5e564858d.zip
fixes
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/scalac/ast/parser/MarkupParser.scala100
-rw-r--r--sources/scala/tools/scalac/ast/parser/Scanner.scala60
-rw-r--r--sources/scala/xml/ProcInstr.scala26
-rw-r--r--sources/scala/xml/Utility.scala4
4 files changed, 169 insertions, 21 deletions
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] ))
}
+ /** '<! CharData ::= [CDATA[ ( {char} - {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 ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
*
* 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;
};
+ /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {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 "<?"+text+"?>" */
- final override def toString() = "<?"+text+"?>";
-
+ /** returns "<?"+target+(" "+text)?+"?>" */
+ final override def toString() = {
+ val sb = new StringBuffer("<?");
+ sb.append(target);
+ text match {
+ case Some(txt) =>
+ 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('<');