diff helpgen/readhelp.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/helpgen/readhelp.syn	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,226 @@
+{
+/*
+ * AnaGram, a System for Syntax Directed Programming
+ * Copyright 1993 Parsifal Software. All Rights Reserved.
+ * Copyright 2006 David A. Holland. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * readhelp.syn - Toplevel syntax for help source file.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "utils.h"
+#include "topic.h"
+#include "helpgen.h"
+}
+
+[
+  pointer input
+  pointer type = unsigned char *
+  context type = unsigned char *
+  default token type = void
+  line numbers
+]
+
+left = 169
+right = 170
+quote = '\''
+
+range = 0..255
+eof = 0
+tab = '\t'
+nl = '\n'
+cr = '\r'
+blank = ' ' + tab
+text = ~eof & ~cr & ~nl
+
+(int) letter
+ -> text & ~blank & ~',' & ~(left + right):c = c;
+
+(void) blanks
+ -> blank
+ -> blanks, blank
+
+(void) eol
+ -> ["//", text...], cr?, nl
+
+(void) new line
+ -> cr?, nl
+
+(void) continue
+ -> blanks?, [eol, blanks?]
+
+(void) name
+ -> letter:c                       = startstr(), addstr(c);
+ -> name, letter:c                 = addstr(c);
+ -> name, blanks, letter:c         = addstr(' '), addstr(c);
+
+(const char *) title
+ -> name, blanks?                  = getstr();
+
+(void) titles
+ -> title:t                        = topic_addtitle(curtopic, t);
+ -> titles, ',', continue, title:t = topic_addtitle(curtopic, t);
+
+(long) text lines
+ -> text unit..., new line     = CONTEXT - inputdata;
+ -> text lines, text unit..., new line
+
+(void) text unit
+// -> text - (left + right + quote)
+// -> quote, ~eof
+ -> text - (left + right)
+ -> cross reference
+
+(void) cross reference
+ -> cross reference text, blanks?, right = see_xref(getstr());
+
+(void) cross reference text
+ -> left                                   = startstr();
+ -> cross reference text, letter:c         = addstr(c);
+ -> cross reference text, blanks, letter:c = addstr(' '), addstr(c);
+ -> cross reference text, blanks?, cr?, nl = addstr(' ');
+
+(long) block body
+ -> text lines
+ -> block body, blank lines, text lines
+
+(long) blank lines
+ -> new line      = CONTEXT - inputdata;
+ -> blank lines, new line
+
+(long) end block
+ -> blank lines, "##"
+ -> "##"      = CONTEXT - inputdata;
+
+(void) block
+ -> !{ startblock(); }, titles, eol, real block body = endblock();
+
+(void) real block body
+ -> blank lines?, block body:bb, end block:be = block(bb,be);
+ -> end block = block(0,0);
+
+(void) file $
+ -> blocks, eof
+
+(void) blocks
+ ->
+ -> blocks, blanks?, eol
+ -> blocks, block
+
+////////////////////////////////////////////////////////////
+//
+// string buffer
+
+{
+static char string_space[4096];
+static size_t string_pos;
+
+static void startstr(void) {
+  string_pos = 0;
+}
+
+static void addstr(int ch) { 
+  if (string_pos >= sizeof(string_space)-1) {
+    fprintf(stderr, "String buffer overflow - make string_space larger\n");
+    exit(1);
+  }
+  string_space[string_pos++] = ch;
+}
+
+static const char *getstr(void) {
+  string_space[string_pos] = 0;
+  return string_space;
+}
+}
+
+////////////////////////////////////////////////////////////
+//
+// current topic
+{
+static struct topic *curtopic;
+
+static void startblock(void) {
+  assert(curtopic == NULL);
+  curtopic = topic_create();
+}
+
+static void endblock(void) {
+  help_addtopic(curtopic);
+  curtopic = NULL;
+}
+
+static void see_xref(const char *ref) {
+  topic_addref(curtopic, ref);
+}
+
+}
+
+////////////////////////////////////////////////////////////
+//
+// pointer input support
+{
+
+#define GET_CONTEXT CONTEXT = PCB.pointer
+
+static unsigned char *inputdata;
+
+static void block(long head, long tail) {
+  long length = tail - head;
+  assert(length >= 0);
+  if (length > 0) {
+    topic_setbody(curtopic, (const char *)(inputdata+head), length);
+  }
+}
+
+static off_t getlength(int fd) {
+  struct stat st;
+  if (fstat(fd, &st) < 0) {
+    fprintf(stderr, "fstat failed: %s", strerror(errno));
+    exit(1);
+  }
+  return st.st_size;
+}
+
+void load(const char *path) {
+  char *buf;
+  off_t len;
+  int fd, r;
+
+  fd = open(path, O_RDONLY);
+  if (fd < 0) {
+    fprintf(stderr, "%s: %s\n", path, strerror(errno));
+    exit(1);
+  }
+
+  len = getlength(fd);
+  buf = domalloc(len+1);
+  r = read(fd, buf, len);
+  if (r < 0) {
+    fprintf(stderr, "%s: read: %s\n", path, strerror(errno));
+    exit(1);
+  }
+  if (r < len) {
+    fprintf(stderr, "%s: read: short count %d of %ld\n", path, r, (long) len);
+    exit(1);
+  }
+  buf[r] = 0;
+  close(fd);
+
+  inputdata = (unsigned char *) buf;
+  PCB.pointer = inputdata;
+  readhelp();
+  inputdata = NULL;
+  free(buf);
+}
+
+}
+