view tests/agcl/oldagsrc/y2ag.syn @ 17:12171da8943f

Don't refer to CVS.
author David A. Holland
date Tue, 31 May 2022 01:56:37 -0400
parents 13d2b8934445
children
line wrap: on
line source

{/*

YACC to AnaGram converter.
Copyright (c) Jerome T. Holland, 1993
All Rights Reserved.

Converts YACC files to AnaGram, attempting to preserve comments.
Does not convert semantic actions.

*/}


[
  line numbers
  nest comments
  parser file name = "#.cpp"
  parser name = y2ag
  sticky { name}
]


/*****

 Character Set Definitions

*****/

anything        = ~eof
backslash       = '\\'
c literal elem  = ~(single quote + double quote + backslash + eof)
digit           = '0-9'
dot             = '.'
double quote    = '"'
eof             =  -1 + 0 + 26
escapes         = 'n' + 'r' + 'b' + 't' + 'f'
letter          = 'a-z' + 'A-Z' + '_'
printing char   = 33..126
simple c char   = ~('$' + '{' + '}' + single quote + double quote + eof)
single quote    = '\''


/*****

 YACC file specification

*****/

grammar
 -> elc?,
    definition block,
    mark, elc?,
    c code block?,
    rule section,
    tail, eof

mark = "%%"

definition block
 -> definitions      ={if (size(config))
                         out << "\n[\n" << (char *) config << "]\n";}

/*****

 White space definitions

*****/

white
 -> ' ' + '\t' + '\v' + '\f' + '\r' + '\n'
 -> comment

comment
 -> comment text, "*/"                      =comments << "*/";

comment text
 -> "/*"                                    =comments << "/*";
 -> comment text, anything:x                =comments << x;

elc
 -> '\n' + '\v' + '\f', comment?        =reset(white),out << '\n',dump_comments("", "");
 -> ' ' + '\t', comment?                =reset(white), dump_comments("\t", "");
 -> comment                             =reset(white), dump_comments("", "");
 -> elc, '\n' + '\v' + '\f', comment?   =out << '\n', dump_comments("", "");
 -> elc, ' ' + '\t', comment?           =dump_comments("\t", "");

blc
 -> '\n' + '\v' + '\f':c, comment?      =reset(white), dump_comments("", "");
 -> ' ' + '\t':c, comment?              =reset(white) << c,dump_comments("", "");
 -> comment                             =reset(white),dump_comments("", "");
 -> blc, '\n' + '\v' + '\f':c, comment? =dump_comments("\t", "");
 -> blc, ' ' + '\t':c, comment?         =white << c, dump_comments("", "");

clc
 -> '\n' + '\v' + '\f':c, comment?      =reset(white),out << cs, cs = "", dump_comments("", "");
 -> ' ' + '\t':c, comment?              =reset(white) << c,dump_comments("", "");
 -> comment                             =reset(white),dump_comments("", "");
 -> clc, '\n' + '\v' + '\f':c, comment? =out << cs, cs = "",dump_comments("", "");
 -> clc, ' ' + '\t':c, comment?         =white << c, dump_comments("", "");

/*****

 Definition statements

*****/

definitions
 ->
 -> definitions, definition                 =dump_comments("\n","\n");

definition
 -> start, identifier, elc? ={
      out.printf("[ grammar token = %s ]\n",(char *) name);
      grammar_tag = "";
    }
 -> union, union text, elc?
 -> c code block
 -> token, print token list, elc?      =out << '\n';
 -> left, print prec list, blc?       =config << "}\n";
 -> right, print prec list, blc?      =config << "}\n";
 -> nonassoc, print prec list, blc?   =config << "}\n";
 -> type, type name, print token list,
     elc?                              =out << '\n';
 -> expect statement, elc?             =out << '\n';

union text
 -> '{', decl, '}'

decl
 -> {decl name | decl white | decl star | decl term}/...  =reset(name);

decl term
 -> ';' ={
  int decl_ndx = decl_dict << decl_name;
  int type_ndx = decl_dict << (char *) type_acc;
  decl_table[decl_ndx] = type_ndx;
  reset(type_acc);
  reset(name);
  *decl_name = 0;
 }

decl name
 -> name  =type_acc << (char *) decl_name, strcpy(decl_name, name), reset(name);

decl white
 -> white...  ={if (*decl_name) type_acc << (char *) decl_name << ' ', *decl_name = 0;}

decl star
 -> {'*'  =type_acc << (char *) decl_name << '*', *decl_name = 0;}...

expect statement
 -> "%expect", elc?, number:n =out.printf("/* expect %d unresolved conflicts */\n",n);

left
 -> {"%left" | "%<"},
      white?...                             =config << "  left {";

nonassoc
 -> {"%nonassoc" | "%binary" | "%2"},
      white?...                             =config << "  nonassoc {";

right
 -> {"%right" | "%>"},
      white?...                             =config << "  right {";

start
 -> "%start", white?...

token
 -> {"%token" | "%term" | "%0"},
     white?...

type
 -> "%type", white...            // =out << '(';

type name
 -> '<', white?..., name, white?...,
    '>', elc? =out << '(' << decl_dict[decl_table[decl_dict[name]]] << ") ", reset(name);

union
 -> "%union", white?...

print token list
 -> tag?, identifier                        =out << (char *) name, cs = ", ";

 -> print token list, elc, identifier  =out << cs << (char *) name;
 -> print token list, elc?, ',', elc?,
      identifier                            =out << cs << (char *) name;
 -> print token list, elc,
      number:n        =out.printf(" = %d\n",n);

print prec list
 -> tag?, identifier                        =config<< (char *) name, cs = ", ";

 -> print prec list, blc, identifier        =config << cs << (char *) name;
 -> print prec list, blc?, ',', blc?,
      identifier                            =config << cs << (char *) name;
 -> print prec list, blc,
      number:n                              =config.printf("/* = %d*/",n);

tag
 -> '<', elc?, identifier, elc?, '>', elc?


/*****

 Syntax to copy C code, watching for character constants, literal strings,
 comments and nested blocks, and picking up value stack references.

*****/

c code block
 -> "%{", c text, "%}",
      white?... =out << "\n{\n" << (char *) c_code << "\n}\n",reset(c_code);

action
 -> embedded c
 -> '=', white?..., embedded c

embedded c
 -> '{', c text, '}'

c text
 ->                                         =reset(c_code), rvflag = 0;
 -> c text, c char

c char           //c char represents the content of embedded c
 -> simple c char:x      =c_code << x;
 -> '$'                  =c_code << '$';
 -> c code comment
 -> '{', nested c text, '}'                 =c_code << '}';
 -> '\'', c literal character, '\''
 ->  literal string, '"'                    =c_code << '"';

c code comment
 -> c code comment text, "*/"               =c_code << "*/";

c code comment text
 -> "/*"                                    =c_code << "/*";
 -> c code comment text, anything:x         =c_code << x;

(int) number
 -> digit:d                                 =d - '0';
 -> number:n, digit:d                       =10*n + d - '0';

[ sticky {number}]

nested c text
 ->                                         =c_code << '{';
 -> nested c text, c char

c literal character
 -> 32..176 - '\\' :x                       =c_code << '\'' << x << '\'';
 -> '\\', octal digits

octal digits
 -> '0-7':x                                 =c_code << x;
 -> octal digits, '0-7':x                   =c_code << x;

literal string
  -> '"'                                    =c_code << '"';
  -> literal string, string character

string character
 -> 32..176 - '\\' -'"':x        =c_code << x;
 -> '\\', 32..176:x              =c_code << '\\' << x;


/*****

 Rules Section

*****/

rule section
 -> [production, elc?]...


production
 -> production head, complete rules, ';'   =output_r();

production head
 -> identifier, white?..., ':'  ={
      out << (char *) name << grammar_tag;
      grammar_tag = "";
      cs = "\n -> ";
      dump_comments("\t","");
    }

complete rules
 -> complete rule
 -> rule set continuation, complete rule

rule set continuation
 -> complete rules, '|'  =output_r(), out << "\n -> ",  cs = "";

complete rule
 -> rule
 -> rule, explicit precedence

rule
 -> clc?                                =out << cs, cs = "";
 -> rule name continuation, blc?
 -> rule literal continuation, blc?
 -> rule, action, blc?

rule name continuation
 -> rule, name        ={
      output_il();
      out.printf("%s%s",cs,(char *) name); cs = ", ";
 }
rule literal continuation
 -> rule, literal:x ={
      char *fmt = "%d";
      if (isprint(x)) fmt ="'%c'";
      reset(name).printf(fmt,x);
      output_il();
      out.printf("%s%s",cs,(char *) name); cs = ", ";
    }

explicit precedence
 -> explicit precedence head, blc
 -> explicit precedence head, blc?, action, blc?

explicit precedence head
 -> prec, identifier  =out.printf(" /* %prec %s */",(char *) name);

prec
 -> {"%prec" | "%="}, white?...  =dump_comments("\t","");

identifier
 -> name
 -> literal:x                     ={
      char *fmt = "%d";
      if (isprint(x)) fmt ="'%c'";
      reset(name).printf(fmt,x);
    }

(int) literal
 -> '\'', literal character:x, '\''         =x;
 -> '"', literal character:x, '"'           =x;

(int) literal character
 -> 32..176 - '\\'
 -> '\\', 'n' = '\n';
 -> '\\', 'r' = '\r';
 -> '\\', 'b' = '\b';
 -> '\\', 't' = '\b';
 -> '\\', 'f' = '\v';
 -> '\\', 32..176 - '0-7' - escapes :x      =x&037;
 -> '\\', octal number:x                    =x;

name
 -> letter+dot:x                            =reset(name) << x;
 -> name, letter+digit:x                    =name << x;
 -> name, dot                               =name << ' ';


(int) octal number
 -> '0-7':x                                 =x-'0';
 -> octal number:v, '0-7':x                 =8*v + x-'0';

tail
 ->
 -> mark, tail code                         =out << "\n}\n";

tail code
 ->                                         =out << "\n{\n";
 -> tail code, anything:x                   =out << x;


{
#include <ctype.h>
#include <stdio.h>
#include "charsink.h"
#include "strdict.h"

string_accumulator c_code(64000);
string_accumulator comments(10000);
string_accumulator name(100);
string_accumulator white(100);
string_accumulator config(1000);
string_accumulator type_acc(100);
string_dictionary decl_dict(100);

char decl_name[100] = "";
int decl_table[100];

output_file out;

char *cs;

char *type_string = "int AG_RTV;\n";


int rvflag;

char *grammar_tag = " $";

void dump_comments(char *ps, char *cs) {
  if (size(comments) == 0) return;
  out << (char *) white << ps << (char *) comments << cs;
  reset(comments);
}

void output_r(void) {
  char *rs = "";
  char *ts = "";
  if (size(c_code) == 0) return;
  out.printf(" ={%s%s%s}", ts,(char *) c_code,rs);
  reset(c_code);
}

void output_il(void) {
  char *rs = "";
  char *ts = "";
  if (size(c_code) == 0) return;
  out.printf("%s!{\n%s%s%s}", cs, ts, (char *) c_code,rs);
  reset(c_code);
  cs = ",\n   ";
}

void main(void) {
  y2ag();
}

}                                           // End of Embedded C