public Grammar( string name, Expression top, ExpBuilder builder, Grammar parent ) : base(name,top) { this.Parent = parent; this.Builder = builder; }
public static string print( Expression exp, int elemDepth, bool visitRef ) { using( StringWriter str = new StringWriter() ) { exp.Visit( new ExpPrinter(str,elemDepth,visitRef) ); return str.ToString(); } }
// <a> // <b/><c>...</c><d/> // </a> // XmlReader should be immediately after reading <a>. // When this method returns, it will be immediately after </a>. private Expression Verify( Expression contentModel, Expression[] atoms ) { while(!document.EOF) { switch( document.NodeType ) { case XmlNodeType.CDATA: case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: OnText(); break; case XmlNodeType.Element: contentModel = OnElement( contentModel, atoms ); break; case XmlNodeType.EndElement: return contentModel; // nodes that are ignored case XmlNodeType.Comment: case XmlNodeType.ProcessingInstruction: document.Read(); break; default: Console.WriteLine(document.NodeType); Debug.Assert(false); break; } } return contentModel; }
internal DataExp( Datatype _dt, Expression _except, string _name ) : base(_dt.GetHashCode()*HASH_DATA, false) { // TODO: probably the epsilon reducibility is wrong. // can we treat epsilon-reducibility as an approximation? // rather than the precise value? this.except = _except; this.dt = _dt; this.name = _name; }
public ReferenceExp( string name, Expression exp ) : base(rnd.Next(),false) { this.name = name; this.exp = exp; }
protected virtual void CombineReferenceExp( ReferenceExp r, Expression body, string combine ) { if( redefiningRefExps.ContainsKey(r) ) { // this pattern is currently being redefined. redefiningRefExps[r] = true; return; // ignore the value } RefParseInfo pi = (RefParseInfo)refParseInfos[r]; if(pi==null) refParseInfos[r] = pi = new RefParseInfo(); if( pi.Combine!=null && combine!=null && pi.Combine!=combine ) { // error: inconsistent combine method ReportError( ERR_INCONSISTENT_COMBINE, r.name ); pi.Combine = null; return; } if( combine==null ) { if( pi.HeadDefined ) // error: multiple heads ReportError( ERR_MULTIPLE_HEADS, r.name ); pi.HeadDefined = true; combine = pi.Combine; } else { pi.Combine = combine; } if( r.exp==null ) r.exp = body; else { if(combine=="interleave") r.exp = Builder.CreateInterleave( r.exp, body ); else if(combine=="choice") r.exp = Builder.CreateChoice( r.exp, body ); else { // error: invalid combine value ReportError( ERR_INVALID_COMBINE, combine ); } } }
public static Expression Calc( Expression exp, Token token, ExpBuilder builder ) { return exp.Visit( new Residual(token,builder) ); }
private Expression VerifyText( Expression exp, Expression[] atoms ) { string literal; if(characters.Length==0) { literal = String.Empty; } else { literal = characters.ToString(); characters = new StringBuilder(); } bool ignorable = (literal.Trim().Length==0); Trace.WriteLine("characters: "+literal.Trim()); StringToken token = new StringToken(literal,builder,this); Expression r = Residual.Calc( exp, token, builder ); if(ignorable) exp = builder.CreateChoice( exp, r ); else exp = r; if(exp==Expression.NotAllowed) { // error: unexpected literal if(literal.Length>20) literal=literal.Substring(0,20)+" ..."; ReportError( ERR_INVALID_TEXT, literal ); } if(atoms!=null) for( int i=atoms.Length-1; i>=0; i-- ) { r = Residual.Calc( atoms[i], token, builder ); if(ignorable) atoms[i] = builder.CreateChoice( atoms[i], r ); else atoms[i] = r; } return exp; }
private Expression Verify( Expression contentModel ) { return Verify(contentModel,null); }
protected Expression OnAttribute( Expression exp, Expression[] atoms ) { if(document.Name!="xmlns" && document.Prefix!="xmlns") { Trace.WriteLine("@"+document.Name); AttributeToken token = new AttributeToken( document.NamespaceURI, document.LocalName, document.Value, this, builder ); AttFeeder feeder = new AttFeeder(builder,token); exp = exp.Visit(feeder); if( exp==Expression.NotAllowed ) { // error: bad attribute ReportError(ERR_BAD_ATTRIBUTE,document.Name); } if(atoms!=null) for( int i=0; i<atoms.Length; i++ ) atoms[i] = atoms[i].Visit(feeder); Trace.WriteLine("residual: " + ExpPrinter.printContentModel(exp)); } return exp; }
private Expression OnElement( Expression contentModel, Expression[] atoms ) { contentModel = VerifyText(contentModel,atoms); Trace.WriteLine("<"+document.Name+">"); Trace.Indent(); Trace.WriteLine("expecting: "+ ExpPrinter.printContentModel(contentModel)); ElementExp[] match = ContentModelCollector.Collect( contentModel, new XmlName(document.NamespaceURI,document.LocalName) ); if(match[0]==null) { // error: unexpected element ReportError(ERR_UNEXPECTED_ELEMENT,document.Name); } Expression combinedChild = Expression.NotAllowed; int i; for( i=0; match[i]!=null; i++ ) combinedChild = builder.CreateChoice( combinedChild, match[i].exp ); int clen = i; Expression[] cp = null; if(clen>1) { Trace.WriteLine(string.Format("{0} elements are matched",clen)); cp = new Expression[clen]; for( i=0; i<clen; i++ ) cp[i] = match[i].exp; } Trace.WriteLine("combined child: "+ ExpPrinter.printContentModel(combinedChild)); if(document.MoveToFirstAttribute()) do { combinedChild = OnAttribute( combinedChild, cp ); } while( document.MoveToNextAttribute() ); document.MoveToElement(); combinedChild = attPruner.prune(combinedChild); if(combinedChild==Expression.NotAllowed) { // error: required attribute is missing // TODO: name of required attributes ReportError(ERR_MISSING_ATTRIBUTE); } if( !document.IsEmptyElement ) { document.ReadStartElement(); combinedChild = Verify(combinedChild,cp); combinedChild = VerifyText(combinedChild,cp); Trace.Unindent(); Trace.WriteLine("</"+document.Name+">"); } else { // treat it as "" combinedChild = VerifyText(combinedChild,cp); Trace.Unindent(); Trace.WriteLine("</"+document.Name+">"); } if( !combinedChild.IsNullable ) { // error: unexpected end of element. ReportError( ERR_CONTENTMODEL_INCOMPLETE, document.Name ); } document.Read(); // read the end tag. if(cp!=null) for( i=0; i<clen; i++ ) if(!cp[i].IsNullable) match[i]=null; ElementToken e = new ElementToken(match,clen); if(atoms!=null) for( i=0; i<atoms.Length; i++ ) atoms[i] = Residual.Calc(atoms[i],e,builder); contentModel = Residual.Calc(contentModel,e,builder); Trace.WriteLine("residual: " + ExpPrinter.printContentModel(contentModel)); return contentModel; }
public static string printFragment( Expression exp ) { return print(exp,-1,false); }
public static string printContentModel( Expression exp ) { return print(exp,0,true); }
protected void Visit( Expression e ) { bool isComplex = false; if( e is BinaryExp ) isComplex = true; if( e is ReferenceExp ) isComplex = true; if(isComplex) writer.Write('('); e.Visit(this); if(isComplex) writer.Write(')'); }
protected void OptimizedChoice( Expression exp ) { if( exp is OneOrMoreExp ) { Visit( ((OneOrMoreExp)exp).exp ); writer.Write('*'); return; } else { Visit(exp); writer.Write('?'); } }