diff options
author | buraq <buraq@epfl.ch> | 2003-11-07 12:08:55 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-11-07 12:08:55 +0000 |
commit | 9bf060b7c96d7a4662530a04e25622fc1b3a7e43 (patch) | |
tree | 70f1b0fb3ca55a252c88131fcada1fb23580f2ca | |
parent | cc00fa9f4324d03b86786f81117163b30fe3db81 (diff) | |
download | scala-9bf060b7c96d7a4662530a04e25622fc1b3a7e43.tar.gz scala-9bf060b7c96d7a4662530a04e25622fc1b3a7e43.tar.bz2 scala-9bf060b7c96d7a4662530a04e25622fc1b3a7e43.zip |
xml path expressions and a (not yet working) pa...
xml path expressions and a (not yet working) parser for them
-rw-r--r-- | sources/scala/xml/path/Expression.scala | 7 | ||||
-rw-r--r-- | sources/scala/xml/path/Parser.scala | 55 | ||||
-rw-r--r-- | sources/scala/xml/path/Scanner.scala | 48 | ||||
-rw-r--r-- | sources/scala/xml/path/Tokens.scala | 23 |
4 files changed, 131 insertions, 2 deletions
diff --git a/sources/scala/xml/path/Expression.scala b/sources/scala/xml/path/Expression.scala index 4fec113a9b..d9f81d5836 100644 --- a/sources/scala/xml/path/Expression.scala +++ b/sources/scala/xml/path/Expression.scala @@ -10,6 +10,7 @@ object Expression { abstract class Expression ; +/* case class Node[T<:Element]( conds:Condition* ) extends Expression { type t = T; @@ -17,6 +18,8 @@ case class Node[T<:Element]( conds:Condition* ) extends Expression { x.isInstanceOf[t]; } }; +*/ +case class Node( label:String, cond:Option[List[List[Expression]]] ) extends Expression ; case class Attribute( name:String ) extends Expression; @@ -24,7 +27,7 @@ case object Wildcard extends Expression; case object Descendant extends Expression; -abstract class Condition ; - +/* case class Present(attr:Attribute) extends Condition; case class Equals(attr:Attribute, str:String) extends Condition; +*/ diff --git a/sources/scala/xml/path/Parser.scala b/sources/scala/xml/path/Parser.scala new file mode 100644 index 0000000000..e7828fe716 --- /dev/null +++ b/sources/scala/xml/path/Parser.scala @@ -0,0 +1,55 @@ +package scala.xml.path ; + +class Parser( it:Iterator[char] ) with Scanner( it ) { + + def acc( tok:int ) = { + if( token != tok ) error("unexpected token") else {}; + nextToken + } + + def parseString( xpath:String ) = { + //initScanner( new IterableString( xpath )); + expr + } + + def expr:List[Expression] = { + var es : List[Expression] = Nil; + while( token != ENDTOK ) token.match { + + case AT => + nextToken; es = Attribute( ident ) :: es; + + case DOT => + nextToken; acc( SLASH ); + + case IDENT => + val label = value; nextToken; val cs = conds; es = Node( label, cs ) :: es ; + + case SLASH => + nextToken; + + case SLASHSLASH => + nextToken; es = Descendant :: es ; + + case STAR => + nextToken; es = Wildcard :: es; + + } + es.reverse; + } + + def conds = token match { + case LBRACKET => + nextToken; + var cond :List[List[Expression]] = List( expr ); + while( COMMA == token ) { cond = expr :: cond } + acc( RBRACKET ); + Some( cond.reverse ) + case _ => + None + } + + def ident = { + val label = value; acc(IDENT); label + } +} diff --git a/sources/scala/xml/path/Scanner.scala b/sources/scala/xml/path/Scanner.scala new file mode 100644 index 0000000000..81c251d055 --- /dev/null +++ b/sources/scala/xml/path/Scanner.scala @@ -0,0 +1,48 @@ +package scala.xml.path ; + +class Scanner( it:Iterator[char] ) with Tokens { + + val ENDCH : char = (-1).asInstanceOf[char]; + + var c : char = '%'; + var token : int = 0; + var value : String = ""; + + def next = if( it.hasNext ) { c = it.next } else { c = ENDCH }; + + def nextToken = if( ENDCH == c ) ENDTOK else c match { + case '@' => AT + case ',' => COMMA + case '.' =>{ + next; + if ( '.' == c ) { next; token = DOTDOT } else { token = DOT } + } + case '=' =>next; token = EQUALS + case '[' =>next; token = LBRACKET + case ']' =>next; token = RBRACKET + case '/' =>{ + next; + if ( '/' == c ) { next; token = SLASHSLASH } else { token = SLASH } + } + case '*' =>next; token = STAR + case _ =>getIdentOrKeyword; + } + + def isIdentChar = ('a' <= c && c <= 'z'); + + def getIdentOrKeyword = { + val str = getIdent; token = IDENT /* + keywords.get( str ) match { + case Some( tok ) => value=""; token = tok + case None => token = IDENT + }*/ + } + + def getIdent:String = { + var cs = List(c); + next; + while ( isIdentChar ) { cs = c::cs; next } + cs.foldLeft ("") { (c,s) => s+c } + } + +} diff --git a/sources/scala/xml/path/Tokens.scala b/sources/scala/xml/path/Tokens.scala new file mode 100644 index 0000000000..d88b372335 --- /dev/null +++ b/sources/scala/xml/path/Tokens.scala @@ -0,0 +1,23 @@ +package scala.xml.path ; + +/** Tokens for XPath expressions + */ + +class Tokens { + + final val AT = 0; + final val COMMA = AT + 1; + final val DOT = COMMA + 1; + final val DOTDOT = DOT + 1; + final val EQUALS = DOTDOT + 1; + final val IDENT = EQUALS + 1; + final val LBRACKET = IDENT + 1; + final val RBRACKET = LBRACKET + 1; + final val SLASH = RBRACKET + 1; + final val SLASHSLASH = SLASH + 1; + final val STAR = SLASHSLASH + 1; + + final val ENDTOK = STAR + 1; + + +} |