summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-01-18 21:18:36 +0000
committerPaul Phillips <paulp@improving.org>2010-01-18 21:18:36 +0000
commit135d4f06b174aa585af64b5253aba647982ac4a2 (patch)
tree73ca84ae254f4903feef03f7573172f992ca7e99 /src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
parente83ad1e005d40738f87da8bb2d60cf9035cfb6ca (diff)
downloadscala-135d4f06b174aa585af64b5253aba647982ac4a2.tar.gz
scala-135d4f06b174aa585af64b5253aba647982ac4a2.tar.bz2
scala-135d4f06b174aa585af64b5253aba647982ac4a2.zip
More work consolidating the XML code needlessly...
More work consolidating the XML code needlessly duplicated between the compiler and the library. Having to fix #2354 in two completely different places was I found very motivating.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala138
1 files changed, 15 insertions, 123 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 1f17f148aa..f7f6fea2c2 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -14,7 +14,6 @@ import scala.tools.nsc.util.{Position,NoPosition,SourceFile,CharArrayReader}
import scala.xml.{ Text, TextBuffer }
import scala.xml.Utility.{ isNameStart, isNameChar, isSpace }
import util.Chars.{ SU, LF }
-import scala.annotation.switch
// XXX/Note: many/most of the functions in here are almost direct cut and pastes
// from another file - scala.xml.parsing.MarkupParser, it looks like.
@@ -36,9 +35,6 @@ trait MarkupParsers
{
self: Parsers =>
- type PositionType = Position
- type InputType = CharArrayReader
-
case object MissingEndTagException extends RuntimeException with ControlException {
override def getMessage = "start tag was here: "
}
@@ -58,8 +54,16 @@ trait MarkupParsers
import Tokens.{ EMPTY, LBRACE, RBRACE }
type PositionType = Position
+ type InputType = CharArrayReader
+ type ElementType = Tree
+ type AttributesType = mutable.Map[String, Tree]
+ type NamespaceType = Any // namespaces ignored
+
+ def mkAttributes(name: String, other: NamespaceType): AttributesType = xAttributes
+
val eof = false
+ def truncatedError(msg: String): Nothing = throw TruncatedXML
def xHandleError(that: Char, msg: String) =
if (ch == SU) throw TruncatedXML
else reportSyntaxError(msg)
@@ -75,15 +79,12 @@ trait MarkupParsers
def ch = input.ch
/** this method assign the next character to ch and advances in input */
def nextch = { val result = input.ch; input.nextChar(); result }
+ def ch_returning_nextch = nextch
- var xEmbeddedBlock = false
+ def mkProcInstr(position: Position, name: String, text: String): Tree =
+ parser.symbXMLBuilder.procInstr(position, name, text)
- /** Execute body with a variable saved and restored after execution */
- def saving[A,B](getter: A, setter: (A) => Unit)(body: => B): B = {
- val saved = getter
- try body
- finally setter(saved)
- }
+ var xEmbeddedBlock = false
private var debugLastStartElement = new mutable.Stack[(Int, String)]
private def debugLastPos = debugLastStartElement.top._1
@@ -93,14 +94,10 @@ trait MarkupParsers
reportSyntaxError("in XML content, please use '}}' to express '}'")
throw ConfusedAboutBracesException
}
- private def errorNoEnd(tag: String) = {
+ def errorNoEnd(tag: String) = {
reportSyntaxError("expected closing tag of " + tag)
throw MissingEndTagException
}
- private def errorAndResult[T](msg: String, x: T): T = {
- reportSyntaxError(msg)
- x
- }
/** checks whether next character starts a Scala block, if yes, skip it.
* @return true if next character starts a scala block
@@ -128,9 +125,7 @@ trait MarkupParsers
val mid = curOffset
val value: Tree = ch match {
case '"' | '\'' =>
- nextch
- val tmp = xAttributeValue(delim)
- nextch
+ val tmp = xAttributeValue(ch_returning_nextch)
try handle.parseAttribute(r2p(start, mid, curOffset), tmp)
catch {
@@ -157,43 +152,6 @@ trait MarkupParsers
aMap
}
- /** attribute value, terminated by either ' or ". value may not contain <.
- * @param endch either ' or "
- */
- def xAttributeValue(endCh: Char): String = {
- val buf = new StringBuilder
- while (ch != endCh) {
- // well-formedness constraint
- if (ch == '<') return errorAndResult("'<' not allowed in attrib value", "")
- else if (ch == SU) throw TruncatedXML
- else buf append nextch
- }
- // @todo: normalize attribute value
- buf.toString
- }
-
- /** parse a start or empty tag.
- * [40] STag ::= '<' Name { S Attribute } [S]
- * [44] EmptyElemTag ::= '<' Name { S Attribute } [S]
- */
- def xTag: (String, mutable.Map[String, Tree]) = {
- val elemName = xName
- xSpaceOpt
-
- (elemName, xAttributes)
- }
-
- /** [42] '<' xmlEndTag ::= '<' '/' Name S? '>'
- */
- def xEndTag(startName: String) {
- xToken('/')
- if (xName != startName)
- errorNoEnd(startName)
-
- xSpaceOpt
- xToken('>')
- }
-
/** '<! CharData ::= [CDATA[ ( {char} - {char}"]]>"{char} ) ']]>'
*
* see [15]
@@ -210,36 +168,6 @@ trait MarkupParsers
xTakeUntil(handle.unparsed, () => r2p(start, start, curOffset), "</xml:unparsed>")
}
- /** CharRef ::= "&#" '0'..'9' {'0'..'9'} ";"
- * | "&#x" '0'..'9'|'A'..'F'|'a'..'f' { hexdigit } ";"
- *
- * see [66]
- */
- def xCharRef: String = {
- val hex = (ch == 'x') && { nextch; true }
- val base = if (hex) 16 else 10
- var i = 0
- while (ch != ';') {
- (ch: @switch) match {
- case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
- i = i * base + ch.asDigit
- case 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
- | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' =>
- if (!hex)
- reportSyntaxError("hex char not allowed in decimal char ref\n"
- +"Did you mean to write &#x ?");
- else
- i = i * base + ch.asDigit
- case SU =>
- throw TruncatedXML
- case _ =>
- reportSyntaxError("character '"+ch+"' not allowed in char ref")
- }
- nextch
- }
- i.toChar.toString
- }
-
/** Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
*
* see [15]
@@ -334,7 +262,7 @@ trait MarkupParsers
*/
def element: Tree = {
val start = curOffset
- val (qname, attrMap) = xTag
+ val (qname, attrMap) = xTag(())
if (ch == '/') { // empty element
xToken("/>")
handle.element(r2p(start, start, curOffset), qname, attrMap, new ListBuffer[Tree])
@@ -356,42 +284,6 @@ trait MarkupParsers
}
}
- /** actually, Name ::= (Letter | '_' | ':') (NameChar)* but starting with ':' cannot happen
- * Name ::= (Letter | '_') (NameChar)*
- *
- * see [5] of XML 1.0 specification
- *
- * pre-condition: ch != ':' // assured by definition of XMLSTART token
- * post-condition: name does neither start, nor end in ':'
- */
- def xName: String = {
- if (ch == SU) throw TruncatedXML
- else if (!isNameStart(ch))
- return errorAndResult("name expected, but char '%s' cannot start a name" format ch, "")
-
- val buf = new StringBuilder
-
- do buf append nextch
- while (isNameChar(ch))
-
- if (buf.last == ':') {
- reportSyntaxError( "name cannot end in ':'" )
- buf setLength (buf.length - 1)
- }
- buf.toString.intern
- }
-
- /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>'
- *
- * see [15]
- */
- // <?xml2 version="1.0" encoding="UTF-8" standalone="yes"?>
- def xProcInstr: Tree = {
- val n = xName
- xSpaceOpt
- xTakeUntil(handle.procInstr(_: Position, n, _:String), () => tmppos, "?>")
- }
-
/** parse character data.
* precondition: xEmbeddedBlock == false (we are not in a scala block)
*/