view anagram/agcore/cf.syn @ 4:bebb2ba69e1d

maybe help with getting tex to fail properly on error
author David A. Holland
date Sat, 18 Apr 2020 17:12:17 -0400
parents 13d2b8934445
children
line wrap: on
line source

{
/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 *
 * cf.syn - Configuration file module
 */

#include "port.h"

#include "agstring.h"
#include "assert.h"
#include "cf-defs.h"
#include "cint.h"
#include "config.h"
#include "configparam.h"
#include "error.h"
#include "file.h"
#include "operations.h"
#include "stacks.h"
#include "textfile.h"

//#define INCLUDE_LOGGING
#include "log.h"
}

[
  auto resynch
  context type = cint
  grammar token = config file
 ~declare pcb
  diagnose errors
  lines and columns
  line numbers
 ~allow macros
  line numbers
  error frame
  nest comments
 ~test range
  token names
  pointer input
  default token type = int
  parser file name = "#.cpp"
  line numbers path = "cf.syn"
  escape backslashes
]

any digit = digit + hex letter
backslash = '\\'
blank char = ' ' + '\t'
carriage return = '\r'
digit = '0-9'
double quote = '"'
eof = 0 + 26
eol chars = newline + carriage return
hex letter = 'a-f' + 'A-F'
letter = 'a-z' + 'A-Z' + '_'
newline = '\n'
nonoctal digit = any digit - octal digit
octal digit = '0-7'
simple string char = ~eof - (any digit + double quote + backslash + eol chars)
tab = '\t'
vertical space = '\f' + '\v'

equals
 -> '=', space?

minus
 -> '-', space?

plus
 -> '+', space?

tilde
 -> '~', space?

left parenthesis
 -> '(', space?

right parenthesis
 -> ')', blank?...


config file
 -> blank?..., [global parameter | end of line]/..., eof

(void) global parameter
 -> name                          =ConfigParam::set(1, cfErrorHandler); //cf_gp4(1);
 -> tilde, name                   =ConfigParam::set(0, cfErrorHandler); //cf_gp4(0);
 -> name, equals, data type       =ConfigParam::set(cfErrorHandler);    //cf_gp2();
 -> name, equals, keyword string  =ConfigParam::set(cfErrorHandler);    //cf_gp3();
 -> name, equals, number:n        =ConfigParam::set(n, cfErrorHandler); //cf_gp5(n);

(void) data type
 -> name
 -> name, abstract declarator  =concat_string();

(void) abstract declarator
 -> indirect data type
 -> direct abstract declarator
 -> indirect data type, direct abstract declarator  =concat_string();


(void) direct abstract declarator
 -> {left parenthesis =scs('('),0;}, abstract declarator,
     right parenthesis =concat_string(), acs(')');

(void) pointer
 -> star
 -> star, name  =concat_string();

(void) star
 -> '*', blank?... =sss(" *");

(void) indirect data type
 -> pointer
 -> indirect data type, pointer  =concat_string();

(void) name string
 -> letter:a   =scs(a);
 -> name string, letter + digit :a =acs(a);
 -> name string, blank..., letter + digit :a =acs(' '), acs(a);

name
 -> name string, blank?...

blank
 -> blank char
 -> c comment

space
 -> blank...
 -> blank..., continuation
 -> continuation

continuation
 -> comment, next line
 -> next line

next line
 -> carriage return?, newline
 -> carriage return?, newline, blank...

white
 -> blank
 -> carriage return?, newline
 -> comment, carriage return?, newline

end of line
 -> comment, carriage return?, newline
 -> carriage return?, newline
 -> end of line, white
 -> end of line, vertical space //form feed

comment
 -> "//", ~eol chars & ~eof?...

decimal number
 -> '1-9':d                       =d - '0';
 -> decimal number:n, '0-9':d     =10*n + d - '0';

octal number
 -> '0'                          =0;
 -> octal number:n, '0-7':d      =8*n + d - '0';

hex number
 -> "0x"                       =0;
 -> "0X"                       =0;
 -> hex number:n, '0-9':d      =16*n + d - '0';
 -> hex number:n, 'A-F' + 'a-f':d      =16*n + (d&7) + 9;

simple number
 -> decimal number
 -> octal number
 -> hex number

number
 -> sign:s, simple number:n, blank?... =s*n;

sign
 -> plus?         =1;
 -> minus         =-1;

keyword string
 -> keyword string head, string,  double quote, blank?...

string
 -> string A | string B | string C

(void) keyword string head
 -> double quote =ics();

string char
 -> simple string char
 -> escape sequence

escape sequence
 -> "\\a" ='\a';
 -> "\\b" ='\b';
 -> "\\f" ='\f';
 -> "\\n" ='\n';
 -> "\\r" ='\r';
 -> "\\t" ='\t';
 -> "\\v" ='\v';
 -> "\\\\" ='\\';
 -> "\\?" = '\?';
 -> "\\'" ='\'';
 -> "\\\"" ='"';
 -> three octal:n =n==0?cf_error("Null character in string"),0 : n;

one octal
 -> backslash, '0-7':n                      =n&7;

two octal
 -> one octal:n, '0-7':d                    = n*8 + (d&7);

three octal
 -> two octal:n, '0-7':d                    = n*8 + (d&7);

octal escape
 -> {one octal | two octal}:n =
     n==0?cf_error("Null character in string"),0 : n;

hex escape
 -> "\\x", hex number:n   =n;

(void) string A
 -> string char:c               =acs(c);
 -> any digit:c                 =acs(c);
 -> string, string char:c       =acs(c);
 -> string A, any digit:c       =acs(c);
 -> string B, nonoctal digit:c  =acs(c);

(void) string B
 -> octal escape:n              =acs(n);
 -> string, octal escape:n      =acs(n);

(void) string C
 -> hex escape:n                =acs(n);
 -> string, hex escape:n        =acs(n);

(void) c comment
 -> c comment text, "*/"

(void) c comment text
 -> "/*"
 -> c comment text, ~eof

c comment, c comment text
 -> c comment text, c comment =
{ if (nest_comments) PCB.reduction_token = cf_c_comment_text_token; }

[
  hidden {
    left parenthesis, right parenthesis,
    pointer, indirect data type, name string,
    space, next line, sign, one octal, two octal, three octal,
    string A, string B, string C, c comment text, escape sequence,
    octal escape, hex escape, name string
  }
]

{

#define PARSER_STACK_OVERFLOW assert(0)
#define REDUCTION_TOKEN_ERROR assert(0)
#define SYNTAX_ERROR cf_syn_error()
#define GET_CONTEXT CONTEXT.x = PCB.column, CONTEXT.y = PCB.line

static void cf_error(const char *, int = 1);

class CfErrorHandler : public ConfigParam::ErrorHandler {
public:
  virtual ~CfErrorHandler() {}
  virtual void badParam(const char *s){cf_error(s);}
} cfErrorHandler;



static cf_pcb_type cfcb;
#define PCB cfcb

static AgString config_file;

static void read_one_config(const AgString &dir) {
  LOGSECTION("read_one_config");
  LOGV(dir);

  char delim[2];
  delim[0] = PATH_DELIMITER;
  delim[1] = 0;

  config_file = dir.concat(delim).concat("AnaGram.cfg");
  LOGV(config_file);

  text_file tf(config_file);
  cfcb.pointer = input_base = (unsigned char *) tf;
  if (input_base) cf();
}

void read_config(const AgString mydir) {
  LOGSECTION("read_config");
  LOGV(mydir);
  LOGV(work_dir_name);

  read_one_config(mydir);
  read_one_config(work_dir_name);
}

static void cf_error(const char *msg, int contextFlag) {
  int line, column;
  if (contextFlag) {
    line = CONTEXT.y;
    column = CONTEXT.x;
  }
  else {
    line = PCB.line;
    column = PCB.column;
  }
  errorList.push(Error(line, column, config_file, msg));
}

static void cf_syn_error(void) {
  reset_stk();
  cf_error(PCB.error_message, 0);
}

}