diff src/dil/doc/Parser.d @ 806:bcb74c9b895c

Moved out files in the trunk folder to the root.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sun, 09 Mar 2008 00:12:19 +0100
parents trunk/src/dil/doc/Parser.d@3b34f6a95a27
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/doc/Parser.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,131 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.doc.Parser;
+
+import dil.lexer.Funcs;
+import dil.Unicode;
+import common;
+
+/// A pair of strings.
+class IdentValue
+{
+  string ident;
+  string value;
+  this (string ident, string value)
+  {
+    this.ident = ident;
+    this.value = value;
+  }
+}
+
+/// Parses text of the form:
+/// <pre>
+/// ident = value
+/// ident2 = value2
+///          more text
+/// </pre>
+struct IdentValueParser
+{
+  char* p; /// Current pointer.
+  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 = p, nextBodyBegin;
+
+    // Init.
+    findNextIdent(ident, bodyBegin);
+    // Continue.
+    while (findNextIdent(nextIdent, nextBodyBegin))
+    {
+      idvalues ~= new IdentValue(ident, textBody(bodyBegin, nextIdent.ptr));
+      ident = nextIdent;
+      bodyBegin = nextBodyBegin;
+    }
+    // Add last ident value.
+    idvalues ~= new IdentValue(ident, textBody(bodyBegin, textEnd));
+    return idvalues;
+  }
+
+  /// Returns the text body. Trailing whitespace characters are not included.
+  char[] textBody(char* begin, char* end)
+  {
+    // The body of A is empty, e.g.:
+    // A =
+    // B = some text
+    // ^- begin and end point to B (or to this.textEnd in the 2nd case.)
+    if (begin is end)
+      return "";
+    // Remove trailing whitespace.
+    while (isspace(*--end) || *end == '\n')
+    {}
+    end++;
+    return makeString(begin, end);
+  }
+
+  /// Finds the next "Identifier =".
+  /// Params:
+  ///   ident = set to Identifier.
+  ///   bodyBegin = set to the beginning of the text body (whitespace skipped.)
+  /// Returns: true if found.
+  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++;
+  }
+}
+
+/// Returns a string slice ranging from begin to end.
+char[] makeString(char* begin, char* end)
+{
+  assert(begin && end && begin <= end);
+  return begin[0 .. end - begin];
+}