view anagram/agcore/cf.syn @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -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);
}

}