diff anagram/agcore/p.cpp @ 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/anagram/agcore/p.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,214 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * p.cpp
+ */
+
+#include "agdict.h"
+#include "assert.h"
+#include "bpe3.h"
+#include "binsort.h"
+#include "config.h"
+#include "cs.h"
+#include "data.h"
+#include "dict.h"
+#include "error.h"
+#include "lexeme.h"
+#include "p.h"
+#include "pgg24-defs.h"
+#include "q1a.h"
+#include "q1glbl.h"
+#include "rule.h"
+#include "stacks.h"
+#include "tsd.h"
+#include "token.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+AgString            etr_file_name;
+AgString            infile_name("");
+int                 parse_abort_flag = 0;
+AgString            simple_file_name;
+int                 syntax_error_flag = 0;
+AgBalancedTree<int> valueToken;
+
+static void open_result_windows(void) {
+  LOGSECTION("open_result_windows");
+  LOGV(unres_con->nt) LCV(prr->nt) LCV(key_mess->nt);
+  if (unres_con->nt) {
+    log_error("Grammar is ambiguous. See Conflicts Window");
+  }
+  if (prr->nt) {
+    log_error("Conflicts resolved by precedence rules");
+  }
+  if (key_mess->nt) {
+    log_error("Keyword anomalies found");
+  }
+}
+
+static void checkValueTokens(void) {
+  LOGSECTION("checkValueTokens");
+  int n = valueToken.size();
+  LOGV(n);
+  int k;
+  AgBalancedTree<int> badRules;
+  for (k = 0; k < n; k++) {
+    Token token = valueToken[k];
+    int nRules = token->ruleList.size();
+    LOGV(token) LCV(nRules) LCV(token->value_type);
+    int i;
+    for (i = 0; i < nRules; i++) {
+      Rule rule = token.rule(i);
+      if (rule->proc_name || rule->length() == 0) {
+	continue;
+      }
+      LOGV(rule) LCV(rule->proc_name) LCV(rule->length()) 
+	LCV(rule->length() ? rule.token(0)->value_type : 0);
+      LOGV(token->value_type) LCV(rule.token(0)->value_type);
+
+      if (token->value_type == rule.token(0)->value_type) {
+	continue;
+      }
+      LOGS("Bad rule") LV(rule);
+      badRules.insert((int)rule);
+    }
+  }
+
+  for (Each<Rule> r; r.loopNotFinished(); r.getNext()) {
+    //if (r->proc_name) continue;
+    n = r->elementList.size();
+    int j;
+    int variableCount = 0;
+    for (j = 0; j < n; j++) {
+      RuleElement element = r->elementList[j];
+      if (element.cVariable) {
+        variableCount++;
+        if (r->proc_name == 0) {
+	  continue;
+	}
+        if ((int)element.token->value_type == void_token_type) {
+          ssprintf("Parameter %s has type void",
+		   cVariableList[element.cVariable].pointer());
+          log_error(r->line, r->col);
+        }
+      }
+      if (element.token->immediate_action) {
+	variableCount = 0;
+      }
+    }
+    if (r->proc_name == 0 && variableCount) {
+      badRules.insert((int) r);
+    }
+  }
+  n = badRules.size();
+  for (k = 0; k < n; k++) {
+    char buf[100];
+    Rule r = badRules[k];
+    sprintf(buf, "Missing reduction procedure, R%03d", (int) r);
+    errorList.push(Error(r->line, r->col, buf));
+  }
+}
+
+void new_syntax_analyzer(void) {
+  LOGSECTION("new_syntax_analyzer");
+  q1();
+  LOGS("Returned from q1");
+  nstates = nits;
+  build_parse_table();
+  LOGS("Parse table built");
+  checkValueTokens();
+  LOGS("Tokens checked");
+  open_result_windows();
+  LOGS("Result windows open");
+  syntax_state = syntax_analyzed;
+}
+
+void scan_input(void) {
+  LOGSECTION("scan_input");
+  unsigned i, *l;
+
+  Rule ruleZero = Rule::create();
+  ruleZero->prim_tkn = Token(0);
+
+  prod_dict = null_list_dict();
+  LOGS("ready to parse");
+  parse();
+  LOGS("parse complete");
+
+  prod_dict = delete_list_dict(prod_dict);
+  nprods = bnf_table->nt;
+  if (!(syntax_error_flag || parse_abort_flag)) {
+    if (nprods == 0) {
+      log_error("No productions in syntax file");
+      errorList.top().setFatal();
+    }
+  }
+  if (syntax_error_flag ||
+      parse_abort_flag ||
+      nprods == 0) {
+    syntax_state = syntax_error;
+    return;
+  }
+  syntax_state = syntax_parsed;
+  if (default_input_type == 0) {
+    default_input_type = int_token_type;
+  }
+  for (Each<Token> token; token.loopNotFinished(); token.getNext()) {
+    if (token->value_type) {
+      continue;
+    }
+    token->value_type = (!token->non_terminal_flag || token->token_set_id) ?
+      default_input_type : default_token_type;
+  }
+#ifdef INCLUDE_LOGGING
+  if (174 < Token::count()) {
+    Token token174 = Token(174);
+    LOGV(token174->immediate_action) LCV(token174->ruleList.size());
+  }
+#endif
+  LOGS("call set_universe");
+  set_universe();
+  LOGS("call check_key_reserve");
+  check_key_reserve();
+  LOGS("call build_sets");
+  build_sets();
+  LOGS("call set_lexemes");
+  set_lexemes();
+  if (grammar_token == 0 && !(syntax_error_flag || parse_abort_flag)) {
+    log_error("No grammar token specified");
+    errorList.top().setFatal();
+  }
+  nprods = bnf_table->nt;
+
+  ibnf_table = spec_tsd(nprods,2);
+  l = (unsigned *) bnf_table->sb;
+  for (i = 0; i < nprods; i++,l += 2) {
+    at(ibnf_table, l[1], l[0]);
+  }
+
+  LOGS("Sort bnf tables");
+  LOGV(nprods);
+  sort_tuples(bnf_table, 2);
+  sort_tuples(ibnf_table, 1);
+
+  AgStack<RuleElement> elementStack;
+  if (disregard_token) {
+    elementStack.push(RuleElement(disregard_token,0));
+  }
+  elementStack.push(RuleElement(grammar_token, 0));
+
+  if ((int)map_token_number[grammar_token].value_type != void_token_type) {
+    valueToken.insert(grammar_token);
+  }
+
+  LOGS("Set up ruleZero->elementList");
+  ruleZero->elementList = AgArray<RuleElement>(elementStack);
+  summarize_grammar();
+  bnf_table = delete_tsd(bnf_table);
+  no_assertions = 0;
+}
+