view trunk/src/dil/doc/Parser.d @ 737:f88b5285b86b

Implemented DDocEmitter. Fixed quite a few bugs.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 09 Feb 2008 02:00:20 +0100
parents c204b6a9e0ef
children 35184354a502
line wrap: on
line source

/++
  Author: Aziz Köksal
  License: GPL3
+/
module dil.doc.Parser;

import dil.lexer.Funcs;
import dil.Unicode;
import common;

class IdentValue
{
  string ident;
  string value;
  this (string ident, string value)
  {
    this.ident = ident;
    this.value = value;
  }
}

/// Parses text of the form:
/// ident = value
/// ident2 = value2
///          more text
struct IdentValueParser
{
  char* p;
  char* textEnd;

  IdentValue[] parse(string text)
  {
    if (!text.length)
      return null;

    p = text.ptr;
    textEnd = p + text.length;

    IdentValue[] idvalues;

    string ident, nextIdent;
    char* bodyBegin, nextBodyBegin;

    // Init.
    findNextIdent(ident, bodyBegin);
    // Continue.
    while (findNextIdent(nextIdent, nextBodyBegin))
    {
      idvalues ~= new IdentValue(ident, makeString(bodyBegin, nextIdent.ptr));
      ident = nextIdent;
      bodyBegin = nextBodyBegin;
    }
    // Add last ident value.
    idvalues ~= new IdentValue(ident, makeString(bodyBegin, textEnd));
    return idvalues;
  }

  bool findNextIdent(ref string ident, ref char* bodyBegin)
  {
    while (p < textEnd)
    {
      skipWhitespace();
      if (p >= textEnd)
        break;
      auto idBegin = p;
      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
      {
        do // IdChar*
          p++;
        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
        auto idEnd = p;

        skipWhitespace();
        if (p < textEnd && *p == '=')
        {
          p++;
          skipWhitespace();
          bodyBegin = p;
          ident = makeString(idBegin, idEnd);
          return true;
        }
      }
      skipLine();
    }
    return false;
  }

  void skipWhitespace()
  {
    while (p < textEnd && (isspace(*p) || *p == '\n'))
      p++;
  }

  void skipLine()
  {
    while (p < textEnd && *p != '\n')
      p++;
    p++;
  }
}

char[] makeString(char* begin, char* end)
{
  return begin[0 .. end - begin];
}