Index: parser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/api/parser.inc,v
retrieving revision 1.41.2.40
diff -u -F '^f' -r1.41.2.40 parser.inc
--- parser.inc	2 Feb 2010 07:54:15 -0000	1.41.2.40
+++ parser.inc	2 Feb 2010 08:28:51 -0000
@@ -6,6 +6,16 @@
  * The PHP documentation parser that generates content for api.module.
  */
 
+module_load_include('inc', 'pgp', 'engine/pgp.parser');
+module_load_include('inc', 'pgp', 'engine/pgp.reader');
+module_load_include('inc', 'pgp', 'engine/pgp.writer');
+module_load_include('inc', 'pgp', 'engine/pgp.editor');
+module_load_include('inc', 'pgp', 'engine/pgp.list');
+module_load_include('inc', 'pgp', 'engine/pgp.object');
+
+// Constant to allow for switching between API parser and Grammar Parser.
+define('USE_PARSER', 'YES');
+
 function api_parse_file($callback, $file_path, $branch, $file_name) {
   $docblock = array(
     'object_name' => $file_name,
@@ -59,6 +69,8 @@ function api_parse_html_file($docblock) 
  * Read in the file at the given path and parse its documentation.
  */
 function api_parse_php_file($docblock) {
+if (USE_PARSER == 'NO') {
+
   $docblock['code'] = api_format_php($docblock['source']);
   $docblocks = array($docblock);
 
@@ -168,6 +180,149 @@ function api_parse_php_file($docblock) {
 
   api_save_documentation($docblocks);
 }
+else {
+  api_parse_php_file_with_pgp($docblock);
+}
+}
+
+/**
+ * Returns a PGPEditor object. (Singleton)
+ *
+ * @return PGPEditor
+ */
+function api_get_editor() {
+  static $editor;
+  if (!$editor) {
+    $editor = new PGPEditor();
+  }
+  return $editor;
+}
+
+/**
+ * Read in the file at the given path and parse its documentation.
+ *
+ * @param array $docblock
+ *   An array of the documentation block.
+ */
+function api_parse_php_file_with_pgp($docblock) {
+  // Edit grammar statements.
+  $editor = api_get_editor();
+
+  // Build grammar statements.
+  $reader = $editor->getReader();
+  $reader->setSnippet($docblock['source']);
+  $reader->addTokenNames();
+  $reader->buildGrammar();
+
+  // Retrieve items of interest.
+  $statements = $reader->getStatements();
+  if (!$statements) {
+    // This is a text file or template file with no functions, constants, etc.
+    $docblock['code'] = api_format_php($docblock['source']);
+    api_save_documentation(array($docblock));
+    // Free up memory.
+    $reader->reset();
+    pgp_log_memory_use('reset');
+    return;
+  }
+
+  // Reserve the first array slot for the file documentation block.
+  $docblocks = array();
+  $docblock['code'] = api_format_php($docblock['source']);
+  $docblocks[] = $docblock;
+
+  // Set default documenation block array for items other than the file.
+  $default_block = array(
+    'object_name' => '',
+    'branch' => $docblock['branch'],
+    'object_type' => '',
+    'file_name' => $docblock['file_name'],
+    'title' => '',
+    'code' => '',
+    'modified' => $docblock['modified'], // Only needed for 'file' item, but it simplifies parameters in other functions.
+    'start_line' => 0,
+    'see' => '',
+    'class' => '', // TODO Added this
+  );
+
+  api_documentation_loop($statements, $default_block, $docblocks);
+
+  // Free up memory.
+  $reader->reset();
+
+  api_save_documentation($docblocks);
+}
+
+/**
+ * Build a list of documentation items.
+ *
+ * @param array $statements
+ *   A PGPBody object of body statements.
+ * @param array $docblock
+ *   The default documentation block item for the file.
+ * @param array $docblocks
+ *   The array of documentation block items for the file.
+ */
+function api_documentation_loop($statements, $default_block, &$docblocks) {
+  $editor = api_get_editor();
+
+  // Traverse statement list to gather documentation items.
+  $current = $statements->first();
+  while ($current->next != NULL) {
+    $statement = $current->data;
+    $type = is_object($statement) ? $statement->type : $statement['type'];
+    // Common processing.
+    switch ($type) {
+//      case T_INTERFACE:
+      case T_CLASS:
+      case T_FUNCTION:
+      case T_DEFINE:
+      case T_GLOBAL:
+        $docblock = $default_block;
+        $docblock['object_type'] = $editor->statementTypeToString($statement);
+        $docblock['object_name'] = $default_block['class'] . $editor->statementOperandToText($statement);
+        $docblock['title'] = $editor->statementOperandToText($statement);
+        $docblock['start_line'] = 0; // TODO
+
+        $docblock['content'] = $editor->commentToString($statement->comment);
+        unset($statement->comment);
+        $docblock['code'] = api_format_php("<?php\n". $statement->toString() ."\n?".">");
+
+        if (in_array($statement->type, array(T_CLASS, T_FUNCTION))) {
+          $docblock['signature'] = $editor->functionGetSignature($statement);
+        }
+        break;
+
+      case T_DOC_COMMENT:
+        $docblock = $default_block;
+        $docblock['content'] = $editor->commentToString($statement);
+        break;
+
+      default:
+        $docblock = array();
+        continue;
+
+//      case T_CONST:
+//      case T_VAR:
+//        $docblock = api_documentation_global($statement, $branch_name, $file_name);
+//        break;
+    }
+    if (!empty($docblock)) {
+      $docblocks[] = $docblock;
+    }
+
+    // Additional recursive processing on statements with bodies.
+    switch ($type) {
+//      case T_INTERFACE:
+      case T_CLASS:
+        $default_block['class'] = $docblock['object_name'] . '::';
+      case T_FUNCTION:
+        api_documentation_loop($statement->body, $default_block, $docblocks);
+        break;
+    }
+    $current = $current->next;
+  }
+}
 
 /**
  * Find functions called in a formatted block of code.
