⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 check.hx

📁 ocaml编写的一个flash编译器
💻 HX
字号:
package haxe.xml;enum Filter {	FInt;	FBool;	FEnum( values : Array<String> );	FReg( matcher : EReg );}enum Attrib {	Att( name : String, ?filter : Filter, ?defvalue : String );}enum Rule {	RNode( name : String, ?attribs : Array<Attrib>, ?childs : Rule );	RData( ?filter : Filter );	RMulti( rule : Rule, ?atLeastOne : Bool );	RList( rules : Array<Rule>, ?ordered : Bool );	RChoice( choices : Array<Rule> );	ROptional( rule : Rule );}private enum CheckResult {	CMatch;	CMissing( r : Rule );	CExtra( x : Xml );	CElementExpected( name : String, x : Xml );	CDataExpected( x : Xml );	CExtraAttrib( att : String, x : Xml );	CMissingAttrib( att : String, x : Xml );	CInvalidAttrib( att : String, x : Xml, f : Filter );	CInvalidData( x : Xml, f : Filter );	CInElement( x : Xml, r : CheckResult );}class Check {	static var blanks = ~/^[ \r\n\t]*$/;	static function isBlank( x : Xml ) {		return( x.nodeType == Xml.PCData && blanks.match(x.nodeValue) );	}	static function filterMatch( s : String, f : Filter ) {		switch( f ) {		case FInt: return filterMatch(s,FReg(~/[0-9]+/));		case FBool: return filterMatch(s,FEnum(["true","false","0","1"]));		case FEnum(values):			for( v in values )				if( s == v )					return true;			return false;		case FReg(r):			return r.match(s);		}	}	static function isNullable( r : Rule ) {		switch( r ) {		case RMulti(r,one):			return( one != true || isNullable(r) );		case RList(rl,_):			for( r in rl )				if( !isNullable(r) )					return false;			return true;		case RChoice(rl):			for( r in rl )				if( isNullable(r) )					return true;			return false;		case RData(_):			return false;		case RNode(_,_,_):			return false;		case ROptional(_):			return true;		}	}	static function check( x : Xml, r : Rule ) {		switch( r ) {		// check the node validity		case RNode(name,attribs,childs):			if( x.nodeType != Xml.Element || x.nodeName != name )				return CElementExpected(name,x);			var attribs = if( attribs == null ) new Array() else attribs.copy();			// check defined attributes			for( xatt in x.attributes() ) {				var found = false;				for( att in attribs )					switch( att ) {					case Att(name,filter,defvalue):						if( xatt != name )							continue;						if( filter != null && !filterMatch(x.get(xatt),filter) )							return CInvalidAttrib(name,x,filter);						attribs.remove(att);						found = true;					}				if( !found )					return CExtraAttrib(xatt,x);			}			// check remaining unchecked attributes			for( att in attribs )				switch( att ) {				case Att(name,_,defvalue):					if( defvalue == null )						return CMissingAttrib(name,x);				}			// check childs			if( childs == null )				childs = RList([]);			var m = checkList(x.iterator(),childs);			if( m != CMatch )				return CInElement(x,m);			// set default attribs values			for( att in attribs )				switch( att ) {				case Att(name,_,defvalue):					x.set(name,defvalue);				}			return CMatch;		// check the data validity		case RData(filter):			if( x.nodeType != Xml.PCData && x.nodeType != Xml.CData )				return CDataExpected(x);			if( filter != null && !filterMatch(x.nodeValue,filter) )				return CInvalidData(x,filter);			return CMatch;		// several choices		case RChoice(choices):			if( choices.length == 0 )				throw "No choice possible";			for( c in choices )				if( check(x,c) == CMatch )					return CMatch;			return check(x,choices[0]);		case ROptional(r):			return check(x,r);		default:			throw "Unexpected "+Std.string(r);		}	}	static function checkList( it : Iterator<Xml>, r : Rule ) {		switch( r ) {		case RList(rules,ordered):			var rules = rules.copy();			for( x in it ) {				if( isBlank(x) )					continue;				var found = false;				for( r in rules ) {					var m = checkList([x].iterator(),r);					if( m == CMatch ) {						found = true;						switch(r) {						case RMulti(rsub,one):							if( one ) {								var i;								for( i in 0...rules.length )									if( rules[i] == r )										rules[i] = RMulti(rsub);							}						default:							rules.remove(r);						}						break;					} else if( ordered && !isNullable(r) )						return m;				}				if( !found )					return CExtra(x);			}			for( r in rules )				if( !isNullable(r) )					return CMissing(r);			return CMatch;		case RMulti(r,one):			if( one && !it.hasNext() )				return CMissing(r);			for( x in it ) {				var m = checkList([x].iterator(),r);				if( m != CMatch )					return m;			}			return CMatch;		default:			var found = false;			for( x in it ) {				if( isBlank(x) )					continue;				var m = check(x,r);				if( m != CMatch )					return m;				found = true;				break;			}			if( !found ) {				switch(r) {				case ROptional(_):				default: return CMissing(r);				}			}			for( x in it ) {				if( isBlank(x) )					continue;				return CExtra(x);			}			return CMatch;		}	}	static function makeWhere( path : Array<Xml> ) {		if( path.length == 0 )			return "";		var s = "In ";		var first = true;		for( x in path ) {			if( first )				first = false;			else				s += ".";			s += x.nodeName;		}		return s+": ";	}	static function makeString( x : Xml ) {		if( x.nodeType == Xml.Element )			return "element "+x.nodeName;		var s = x.nodeValue.split("\r").join("\\r").split("\n").join("\\n").split("\t").join("\\t");		if( s.length > 20 )			return s.substr(0,17)+"...";		return s;	}	static function makeRule( r : Rule ) {		switch( r ) {		case RNode(name,_,_): return "element "+name;		case RData(_): return "data";		case RMulti(r,_): return makeRule(r);		case RList(rules,_): return makeRule(rules[0]);		case RChoice(choices): return makeRule(choices[0]);		case ROptional(r): return makeRule(r);		}	}	static function makeError(m,?path) {		if( path == null )			path = new Array();		switch( m ) {		case CMatch: throw "assert";		case CMissing(r):			return makeWhere(path)+"Missing "+makeRule(r);		case CExtra(x):			return makeWhere(path)+"Unexpected "+makeString(x);		case CElementExpected(name,x):			return makeWhere(path)+makeString(x)+" while expected element "+name;		case CDataExpected(x):			return makeWhere(path)+makeString(x)+" while data expected";		case CExtraAttrib(att,x):			path.push(x);			return makeWhere(path)+"unexpected attribute "+att;		case CMissingAttrib(att,x):			path.push(x);			return makeWhere(path)+"missing required attribute "+att;		case CInvalidAttrib(att,x,f):			path.push(x);			return makeWhere(path)+"invalid attribute value for "+att;		case CInvalidData(x,f):			return makeWhere(path)+"invalid data format for "+makeString(x);		case CInElement(x,m):			path.push(x);			return makeError(m,path);		}	}	public static function checkNode( x : Xml, r : Rule ) {		var m = checkList([x].iterator(),r);		if( m == CMatch )			return;		throw makeError(m);	}	public static function checkDocument( x : Xml, r : Rule ) {		if( x.nodeType != Xml.Document )			throw "Document excepted";		var m = checkList(x.iterator(),r);		if( m == CMatch )			return;		throw makeError(m);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -