yaml_parser.anubis 4.3 KB
/*
 * Created by PyramIDE.
 * User: フランスのトトロ aka (David RENÉ) 
 * Date: 07/06/2016
 * Time: 23:15
 * © Calexium 
 */


read yaml_type.anubis
read tools/streams.anubis
read tools/string.anubis
read system/string.anubis

type YAML_Parser_Info:
  yaml_p_info(Int indent_size, Int level).

define Maybe(String)
  _read_key
  (
    Stream        current_line,
    List(Word8)   so_far
  )=
  failure.
  
  if read_byte(current_line) is
  {
    failure       then  failure,
    success(char) then
      if      in_word   then
        
      else if in_single_quote then
      else if 
        if char
  .
  
define Maybe(String)
  read_key
  (
    Stream  current_line
  )=
  _read_key(current_line, []).
  
define Maybe(YAML_Key_Value)
  read_key_value 
  (
    Stream            s,
    YAML_Parser_Info  p_info,
    Stream            current_line,  
  )=
  if read_key(current_line) is
  {
    failure       then failure,
    success(key)  then failure
//      if read_value(s, p_info, current_line) is
//      {
//        failure         then failure,
//        success(value)  then 
//          success(key_value(key, var(value)))
//      }
  }
  .
  
public define List(YAML_Key_Value)
  get_yaml_map
  (
    Stream            s,
    YAML_Parser_Info  p_info,
    Stream            current_line,
    List(YAML_Key_Value)  so_far
  )=
  if read_key_value(s, p_info, current_line) is
  {
    failure then 
      println("can't read key value");
      reverse(so_far),
    success(key_value) then
      if read_line(s) is
      {
        failure       then  reverse(so_far),
        success(line) then
          with line_s = make_stream(line),
          //skip all blanks of begin of line
          skip_blanks(line_s);
          with indent = current_column(line_s),
          get_yaml_map(s, p_info, line_s, [key_value . so_far])
      }
  }.
  
public define Maybe(YAML_Document)
  get_yaml_document_content
  (
    Stream        s,
    YAML_Document doc
  )=
  if read_line(s) is
  {
    failure       then  success(doc)
    success(line) then
      with line_s = make_stream(line),

      //skip all blanks of begin of line
      skip_blanks(line_s);
      with indent = current_column(line_s),
      
      if read_byte(line_s) is
      {
        failure     then
          println("skipping blank line");        
          get_yaml_document_content(s, doc), //blank line
          
        success(c)  then
          //check for comment
          if c = '#' then
          //println("skipping comment ["+line+"]");
            get_yaml_document_content(s, doc)
        
          //check for item of the list
          else if c = '-' then
            println("list item indent["+indent+"]["+line+"]");
            get_yaml_document_content(s, doc)
          
          //check for entry of the map
          else
            println("map entry indent["+indent+"]["+line+"]");
            with list_key_val = get_yaml_map(s, yaml_p_info(indent, 0), line_s, []),
            
            if list_key_val is 
            {
              [] then  
                println("Can't get map entries");
                get_yaml_document_content(s, doc),
              [_ . _] then
                since doc is yaml_document(nodes),
                nodes <- [map(var(list_key_val)) . *nodes];
                get_yaml_document_content(s, yaml_document(nodes)) 
            }
                       
      } //read_byte
  }. //read_line
  
public define Maybe(YAML_Document)
  get_yaml_document
  (
      Stream  s,
  )=
  if read_line(s) is
  {
    failure       then failure,
    success(line) then
      if start_with(line, "---") then
        println("Start parsing YAML document");
        get_yaml_document_content(s, yaml_document(var([])))
      else
        get_yaml_document(s)
  }.
  
public define YAML
  parse_YAML_file
  (
    Stream                    s,
    Var(List(YAML_Document))  docs
  )=
  if get_yaml_document(s) is
  {
    failure       then yaml(var(reverse(*docs))),
    success(doc)  then 
      docs <- [doc . *docs];
      parse_YAML_file(s, docs)
  }.
  
public define YAML
  parse_YAML_file
  (
    Stream s
  )=
  if read_line(s) is
  { 
    failure       then  yaml(var([])),
    success(line) then
      if start_with(line, "%YAML 1.1") then
        println("%YAML 1.1 file");
        parse_YAML_file(s, var([]))
      else  
        yaml(var([]))
  }.