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

📄 xml.csp

📁 c-smile 一个语法类似与JS 又有点像C++的 编译器
💻 CSP
字号:
//|
//| xml package
//| TIL language (http://terra-informatica.org) 
//| author: Andrew Fedoniuk
package xml;

function escape(t) {
  return t.replace('&',"&amp;",'<',"&lt;",'>',"&gt;",'"',"&quot;",'\'',"&apos;"); 
}
function unescape(t) 
{ 
  if(t.like("*&*;*")) return t.replace("&lt;",'<',"&gt;",'>',"&quot;",'"',"&apos;",'\'',"&amp;",'&');
  /* TODO char codes */
  return t;
}

//|
//| micro DOM implementation
//|

class node {
    var _value;
    function node(v)    { _value = v; }
    function toString() { return "\n<!--WARNING:toString not defined-->\n" ; }    
}

class pi: node {
    function pi(v)      { node(v); }
    function toString() { return string::printf("<?%s?>",unescape(_value)) ; }
} 
class comment: node {
    function comment(v) { node(v); }
    function toString() { return string::printf("<!--%s-->",unescape(_value)); }
} 
class cdata: node {
    function cdata(v)   { node(v); }
    function toString() { return string::printf("![CDATA[%s]]>",unescape(_value)); }
} 

//|    
//| simple element has only text value, no children 
//|
class simple_element: node {
    var     _name;
    var     _attributes;
   
    function simple_element(name,atts,content) {
      node(content);
      _name = name;
      _attributes = atts;
    }
//|    
//| access to children in form of property
//|
    property children() {  /* nothing here */ return null; }
//| 
//| access to attributes 
//| e.g. :  a = xnode["name"];  
//|
    function [](n,v) 
    {
      if(!is_undefined(v)) // set 
      {
        if(!_attributes) _attributes = new map();
        _attributes[n] = v;
        return v;
      } 
      if(_attributes) return _attributes[n];
      return null;
    }
//|    
//| value here is just all text children
//| always returns string
//|
    property value(v) {  
    // read/write  
      if(!is_undefined(v)) _value = v;
      return _value;
    }
//|    
//| creates string representation of content
//| always returns string
//|
    function valueToString() {  
      //out.printf("DEBUG: (%s) valueToString\n",_name);
      if(_value) return unescape(_value);
      return "";
    }
  
    function toString() {
      var i;
      var s = "<" + _name;
      if(_attributes) 
          for (i = 0; i < _attributes.length; i++) 
            s += string::printf(" %s=\"%s\"",_attributes.key(i),unescape(_attributes.value(i)));
      if(_value)
        s += (" >" + valueToString() + string::printf("</%s>", _name));
      else 
        s += " />";  
      return s;
    }
}

//|    
//| element has text value(s) and/or children 
//|
class element: simple_element 
{
  
    function element(name,atts,content) { simple_element(name,atts,content); }
//|    
//| value here is just all text children
//| always returns string
//|
    property value() {  
      // read only 
      if(!_value) return "";
      var i,v = ""; 
      for(i = 0; i < _value.length; i++) if(is_string(_value[i])) v += _value[i];
      return v;
    }
//|    
//| returns first element with the given tag_name
//|
    function child(tag_name)
    {
      if(_value) {
        var i; 
        for(i = 0; i < _value.length; i++) 
          if( (_value[i] instanceof xml::simple_element) && 
              (_value[i]._name == tag_name) ) return _value[i];
      }
      return null;
    }
//|    
//| tag_name here is template of tag name.
//| returns 1) array of subelements with the given tag_name
//|      or 2) map of subelements with the given tag_name and having attribute att_name.
//|            key of the map is value of att_name (these values supposed to be unique
//|            among all children of given element)
//|
    function elements(tag_name,att_name)
    {
      var r;
      if(att_name) // map
      { 
        r = new map();
        if(!_value) return r; 
        var i; 
        for(i = 0; i < _value.length; i++) 
        {
           var el = _value[i];
           if( el instanceof xml::simple_element && el._name.like(tag_name)) 
           {
              var a = el[att_name];
              if( a ) r[a] = el;
           }    
        }   
      } else {  // array
        r = new array();
        if(!_value) return r; 
        var i; 
        for(i = 0; i < _value.length; i++) 
        {
           var el = _value[i];
           if( el instanceof simple_element && el._name.like(tag_name)) 
              r.push(el);
        }   
      }
      return r;
    }
    function valueToString() {  
      if(_value) 
      {
        var i,v = ""; 
        for(i = 0; i < _value.length; i++)
          v += is_string(_value[i])? unescape(_value[i]): string(_value[i]);
        return v;
      }
      return "";
    }
}


//|
//| idee fixe
//|
class parser {
  var _in;
  var _error_msg;
  var _error_ln;
  var _got_eot;
// vocabulary for interning nmtokens
  static var voc = new map();
  
  function parser() { _in = null; }
  
  function intern(nmtoken) {
      if( !voc.exist(nmtoken) ) voc[nmtoken] = nmtoken;
      return voc[nmtoken];
  }
  
  function compile_atts() {
    var atts;
    while(true) {
      var n = _in.get('=',"/>",">").trim(); 
      if(_in.get_match == 2) _got_eot = true;
      if(_in.get_match != 1) break;
      
      if(!n) throw "empty name encountered";
      
      var z = _in.get('\"','\'',"/>",">").trim(); 
      if( z ) throw string::printf("bad attribute definition (%s)", n ); 
      if(_in.get_match > 2) throw "empty value encountered";
      var v = _in.get( _in.get_match == 1 ? '\"' : '\'' ); 
      if(!atts) atts = new map();
      atts[ intern(n) ] = unescape(v);
    }
    return atts;
  }
  
  function compile_tag(tag_name)
  {
    //NB already got '<'
    var c = _in.get(); // get one char
    switch(c) 
    {
      case '/': 
        { 
          var n = _in.get('>').trim(); // get until (exclusive) 
          if(tag_name != n) throw string::printf("tag '%s' not closed (%s)",tag_name,n);
          return null;
        } 
      case '?':
        { 
          var v = _in.get("?>"); 
          return new pi(v); 
        } 
      case '!': 
        {
          c = _in.get();
          if ( c == '-' )
          {
            if(_in.get() != '-') throw string::printf("bad comment: %s",_in.get("\n"));
            var v = _in.get("-->");
            return new comment(v);
          }
          else if ( c == '[' ) {
            var v = _in.get("CDATA[","\n");
            if(v) throw string::printf("expecting:'CDATA[', got:%s",v);
            v = _in.get("]]>");
            return new cdata(v);
          }
          else if( c == 'D' )
          {
            //skip doctype definition
            _in.get("OCTYPE");
            _in.get("]");_in.get(">");
            return true;
          }
          else
            throw string::printf("expecting comment or cdata, got '%c'",c);
        } break;
      default:    
        {
          var atts_map;
          _got_eot = false;
          var name = intern( new string(c) + _in.get(' ',"/>",'>').trim() );
          if(_in.get_match == 1) atts_map = compile_atts(_in);
          else if(_in.get_match == 2) _got_eot = true;
          var content;
          if(!_got_eot) 
            while(!_in.eof) 
            {
              var v = _in.get('<');
              //out.printf("DEBUG: (%s) content (%s)\n",name,content);                        
              if(v) 
              {
                if(!content) // make it string
                  content = unescape(v);  
                else // array
                  content.push(unescape(v));
              }
              v = compile_tag(name);
              if(v) {
                if( !is_array(content) ) content = content? new array(content) : new array(); 
                content.push(v);
              }
              else // this was tail of this tag
                break; 
            }
          return is_array(content)? 
                 new element(name,atts_map,content):
                 new simple_element(name,atts_map,content);   
        }
    }
  }
  function parse(in_stream)
  {
      _in = in_stream;
      var r = null;      
      try {
        do {
          if( typeof(_in.get('<')) == type::NULL) break;
          r = compile_tag(".");
          //skiping all pi's and doctypes
        } while( !(r instanceof simple_element) ); // or element
      } catch (e) { std::out.printf("ERROR:%s",e); }
      _in.close();
      return r;  
  }
}

⌨️ 快捷键说明

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