summaryrefslogtreecommitdiff
path: root/sources/scala/xml/dtd/ContentModel.scala
blob: 42885c3e073df8f257b83a8aa19263bc1fd80132 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package scala.xml.dtd ;


object ContentModel extends scala.util.regexp.WordExp {
  type _labelT = ElemName;
  type _regexpT = RegExp;

  case class ElemName(name: String) extends Label {
    override def toString() = "ElemName(\""+name+"\")";
  }

  def parse(s: String): ContentModel = Parser.parse( s );

  /*
  def isMixed(alt: Alt): Boolean = {
    val it = alt.rs.elements;
    it.next == PCDATA_ && {
      while( it.hasNext && it.next.isInstanceOf[Letter] ) {} ;
      !it.hasNext
    }
  }
  */

  def getLabels(r: RegExp): scala.collection.Set[String] = {
    val s = new scala.collection.mutable.HashSet[String]();
    def traverse1(xs: Seq[RegExp]): Unit = {
      val it = xs.elements;
      while( it.hasNext )
        traverse( it.next );
      }
    def traverse(r: RegExp): Unit = {
      r match {
        case Letter(ElemName( name )) => s += name;
        case Star(  x @ _  ) => traverse( x ); // bug if x@_*
        case Sequ( xs @ _* ) => traverse1(xs);
        case Alt(  xs @ _* ) => traverse1(xs);
      }
    }
    traverse( r );
    return s
  }

  def toString(r: RegExp):String = {
    val sb = new StringBuffer();
    toString(r, sb);
    sb.toString();
  }

  /* precond: rs.length >= 1 */
  private def toString(rs: Seq[RegExp], sb: StringBuffer, sep: Char): Unit = {
    val it = rs.elements;
    toString(it.next, sb);
    for(val z <- it) {
      sb.append( sep );
      toString( z, sb );
    }
  }

  def toString(c: ContentModel, sb: StringBuffer): StringBuffer = c.match {

      case ANY    =>
        sb.append("ANY");

      case EMPTY    =>
        sb.append("EMPTY");

      case PCDATA =>
        sb.append("(#PCDATA)");

      case ELEMENTS( r ) =>
        toString(r, sb)

      case MIXED( r ) =>
        sb.append("(#PCDATA"); toString(r, sb); sb.append( ')' )

  }

  def toString(r: RegExp, sb:StringBuffer): StringBuffer = {
    r match {
      case Eps     =>
        sb

      case Sequ(rs @ _*) =>
        sb.append( '(' ); toString(rs, sb, ','); sb.append( ')' );

      case Alt(rs @ _*) =>
        sb.append( '(' ); toString(rs, sb, '|'); sb.append( ')' );

      case Star(r: RegExp) =>
        sb.append( '(' ); toString(r, sb); sb.append( ")*" );

      case Letter(ElemName(name)) =>
        sb.append(name);

    }
  }
}

sealed abstract class ContentModel {
  override def toString(): String = {
    val sb = new StringBuffer();
    toString(sb);
    sb.toString();
  }

  def toString(sb:StringBuffer): StringBuffer;
}

case object PCDATA extends ContentModel {
  def toString(sb:StringBuffer): StringBuffer = sb.append("(#PCDATA)");
}
case object EMPTY extends ContentModel {
  def toString(sb:StringBuffer): StringBuffer = sb.append("EMPTY");
}
case object ANY extends ContentModel {
  def toString(sb:StringBuffer): StringBuffer = sb.append("ANY");
}

case class  MIXED(r:ContentModel.RegExp) extends ContentModel {
  def toString(sb:StringBuffer): StringBuffer =  {
    sb.append("(#PCDATA|");
    ContentModel.toString(r, sb);
    sb.append(")*");
  }
}

case class  ELEMENTS(r:ContentModel.RegExp) extends ContentModel {
  def toString(sb:StringBuffer): StringBuffer =
    ContentModel.toString(r, sb);

}