diff examples/mpp/krc.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/examples/mpp/krc.syn	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,550 @@
+{
+/*
+ * AnaGram, a System for Syntax Directed Programming
+ * C Macro preprocessor
+ * Sample C Grammar
+ * Compatible with Kernighan and Ritchie, 2nd. Edition.
+ *
+ * Copyright 1993-2000 Parsifal Software. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "mpp.h"
+
+stack<unsigned> id_stack(100,20);
+
+}
+[
+  grammar token = program              // Define grammar token
+ ~nest comments                        // Make it explicitly ANSI
+  sticky { statement}                  // resolves if-then-else conflict
+  event driven
+  // far tables                        // uncomment for 16 bit environment
+ ~allow macros
+  input values                         // token input
+  line numbers
+  //escape backslashes                 // uncomment if using MSVC++
+  error trace                          // for diagnosing errors
+  parser name = cc                     // parser will be cc()
+  parser file name = "krc.cpp"
+  header file name = "krc.h"
+  default input type = token
+ ~test range                           // not necessary
+  enum {                               // See TOKEN.H
+    eof               =0,
+    SPACE             =' ',
+    ANDAND            ='A', // "&&"
+    ANDassign,              // "&="
+    ARROW,                  // "->"
+    CONCAT,                 // "##"
+    DECR,                   // "--"
+    DIVassign,              // "/="
+    ELLIPSIS,               // "..."
+    EQ,                     // "=="
+    ERassign,               // "^="
+    GE,                     // ">="
+    ICR,                    // "++"
+    LE,                     // "<="
+    LS,                     // "<<"
+    LSassign,               // "<<="
+    MODassign,              // "%="
+    MINUSassign,            // "-="
+    MULTassign,             // "*="
+    NE,                     // "!="
+    ORassign,               // "|="
+    OROR,                   // "||"
+    PLUSassign,             // "+="
+    RS,                     // ">>"
+    RSassign,               // ">>="
+    CHARACTERconstant,      // character constant
+    STRINGliteral,          // character string
+    UNSIGNEDqualifier =97,
+    LONGqualifier,
+    FLOATqualifier,
+    HEXconstant       =129,
+    OCTconstant,
+    DECconstant,
+    FLOATconstant,          // real
+    NAME,
+    AUTO,                   // "auto"
+    BREAK,                  // "break"
+    CASE,                   // "case"
+    CHAR,                   // "char"
+    CONSTANT,               // "const"
+    CONTINUE,               // "continue"
+    DEFAULT,                // "default"
+    DO,                     // "do"
+    DOUBLE,                 // "double"
+    ELSE,                   // "else"
+    ENUM,                   // "enum"
+    EXTERN,                 // "extern"
+    FLOAT,                  // "float"
+    FOR,                    // "for"
+    GOTO,                   // "goto"
+    IF,                     // "if"
+    INT,                    // "int"
+    LONG,                   // "long"
+    REGISTER,               // "register"
+    RETURN,                 // "return"
+    SHORT,                  // "short"
+    SIGNED,                 // "signed"
+    SIZEOF,                 // "sizeof"
+    STATIC,                 // "static"
+    STRUCT,                 // "struct"
+    SWITCH,                 // "switch"
+    TYPEDEF,                // "typedef"
+    UNION,                  // "union"
+    UNSIGNED,               // "unsigned"
+    VOIDkey,                // "void"
+    VOLATILE,               // "volatile"
+    WHILE,                  // "while"
+    UNRECOGNIZED,
+  }
+]
+
+program
+ -> translation unit, eof
+
+translation unit
+ -> external declaration
+ -> translation unit, external declaration
+
+external declaration
+ -> function definition
+ -> declaration
+
+function definition
+ -> declarator, compound statement
+ -> declarator, declaration list, compound statement
+ -> declaration specifiers, declarator, compound statement
+ -> declaration specifiers, declarator, declaration list, compound statement
+
+declaration
+ -> declaration specifiers:m, init declarator list?, ';'  =mark_typedef(m);
+
+declaration list
+ -> declaration
+ -> declaration list, declaration
+
+(int) declaration specifiers
+ -> storage class specifier
+ -> type specifier                                        =0;
+ -> type qualifier                                        =0;
+ -> declaration specifiers:m, storage class specifier:v   =m | v;
+ -> declaration specifiers, type specifier
+ -> declaration specifiers, type qualifier
+
+(int) storage class specifier
+ -> AUTO              =0;
+ -> REGISTER          =0;
+ -> STATIC            =0;
+ -> EXTERN            =0;
+ -> TYPEDEF           =1;
+
+type specifier
+ -> VOIDkey | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED
+ -> struct or union specifier
+ -> enum specifier
+ -> typedef name
+
+type qualifier
+ -> CONSTANT
+ -> VOLATILE
+
+struct or union specifier
+ -> struct or union, identifier?, !++id_stack;,
+   '{', struct declaration list, '}' =--id_stack;
+ -> struct or union, identifier
+
+
+struct or union
+ -> STRUCT
+ -> UNION
+
+struct declaration list
+ -> struct declaration
+ -> struct declaration list, struct declaration
+
+init declarator list
+ -> init declarator
+ -> init declarator list, ',', init declarator
+
+init declarator
+ -> declarator
+ -> declarator, '=', initializer
+
+struct declaration
+ -> specifier qualifier list, struct declarator list, ';'
+
+specifier qualifier list
+ -> type specifier
+ -> type qualifier
+ -> specifier qualifier list, type specifier
+ -> specifier qualifier list, type qualifier
+
+struct declarator list
+ -> struct declarator
+ -> struct declarator list, ',', struct declarator
+
+struct declarator
+ -> declarator
+ -> declarator?, ':', constant expression
+
+enum specifier
+ -> ENUM, identifier?, '{', enumerator list, '}'
+ -> ENUM, identifier
+
+enumerator list
+ -> enumerator
+ -> enumerator list, ',', enumerator
+
+enumerator
+ -> identifier
+ -> identifier, '=', constant expression
+
+declarator
+ -> direct declarator
+ -> pointer, direct declarator
+
+direct declarator
+ -> identifier:n                          =id_stack << n.handle;
+ -> '(', declarator, ')'
+ -> direct declarator, '[', constant expression?, ']'
+ -> direct declarator, '(', parameter type list, ')'
+ -> direct declarator, '(', identifier list?, ')'
+
+pointer
+ -> '*', type qualifier list?
+ -> '*', type qualifier list?, pointer
+
+type qualifier list
+ -> type qualifier
+ -> type qualifier list, type qualifier
+
+parameter type list
+ -> parameter list
+ -> parameter list, ',', ELLIPSIS
+
+parameter list
+ -> parameter declaration
+ -> parameter list, ',', parameter declaration
+
+parameter declaration
+ -> declaration specifiers, declarator
+ -> declaration specifiers, abstract declarator?
+
+identifier list
+ -> identifier
+ -> identifier list, ',', identifier
+
+initializer
+ -> assignment expression
+ -> '{', initializer list, '}'
+ -> '{', initializer list, ',', '}'
+
+initializer list
+ -> initializer
+ -> initializer list, ',', initializer
+
+type name
+ -> specifier qualifier list, abstract declarator?
+
+abstract declarator
+ -> pointer
+ -> direct abstract declarator
+ -> pointer, direct abstract declarator
+
+direct abstract declarator
+ -> '(', abstract declarator, ')'
+ -> '[', constant expression?, ']'
+ -> direct abstract declarator, '[', constant expression?, ']'
+ -> '(', parameter type list?, ')'
+ -> direct abstract declarator, '(', parameter type list?, ')'
+
+(token) identifier, typedef name
+ -> NAME:n                         =check_typedef(n);
+
+statement
+ -> labeled statement
+ -> expression statement
+ -> compound statement
+ -> selection statement
+ -> iteration statement
+ -> jump statement
+
+labeled statement
+ -> identifier, ':', statement
+ -> CASE, constant expression, ':', statement
+ -> DEFAULT, ':', statement
+
+expression statement
+ -> expression?, ';'
+
+compound statement
+ -> '{', statement list?, '}'
+ -> '{', declaration list, statement list?, '}'
+
+statement list
+ -> statement
+ -> statement list, statement
+
+selection statement
+ -> IF, '(', expression, ')', statement
+ -> IF, '(', expression, ')', statement, ELSE, statement
+ -> SWITCH, '(', expression, ')', statement
+
+iteration statement
+ -> WHILE, '(', expression, ')', statement
+ -> DO, statement, WHILE, '(', expression, ')', ';'
+ -> FOR, '(', expression?, ';', expression?, ';', expression?, ')',
+      statement
+
+jump statement
+ -> GOTO, identifier, ';'
+ -> CONTINUE, ';'
+ -> BREAK, ';'
+ -> RETURN, expression?, ';'
+
+expression
+ -> assignment expression
+ -> expression, ',', assignment expression
+
+assignment expression
+ -> conditional expression
+ -> unary expression, assignment operator, assignment expression
+
+assignment operator
+ -> '=' | MULTassign | DIVassign | MODassign | PLUSassign | MINUSassign
+ -> LSassign | RSassign | ANDassign | ORassign | ERassign
+
+conditional expression
+ -> logical or expression
+ -> logical or expression, '?', expression, ':', conditional expression
+
+constant expression
+ -> conditional expression
+
+logical or expression
+ -> logical and expression
+ -> logical or expression, OROR, logical and expression
+
+logical and expression
+ -> inclusive or expression
+ -> logical and expression, ANDAND, inclusive or expression
+
+inclusive or expression
+ -> exclusive or expression
+ -> inclusive or expression, '|', exclusive or expression
+
+exclusive or expression
+ -> and expression
+ -> exclusive or expression, '^', and expression
+
+and expression
+ -> equality expression
+ -> and expression, '&', equality expression
+
+equality expression
+ -> relational expression
+ -> equality expression, EQ, relational expression
+ -> equality expression, NE, relational expression
+
+relational expression
+ -> shift expression
+ -> relational expression, '<', shift expression
+ -> relational expression, '>', shift expression
+ -> relational expression, LE, shift expression
+ -> relational expression, GE, shift expression
+
+shift expression
+ -> additive expression
+ -> shift expression, LS, additive expression
+ -> shift expression, RS, additive expression
+
+additive expression
+ -> multiplicative expression
+ -> additive expression, '+', multiplicative expression
+ -> additive expression, '-', multiplicative expression
+
+multiplicative expression
+ -> cast expression
+ -> multiplicative expression, '*', cast expression
+ -> multiplicative expression, '/', cast expression
+ -> multiplicative expression, '%', cast expression
+
+cast expression
+ -> unary expression
+ -> '(', type name, ')', cast expression
+
+unary expression
+ -> postfix expression
+ -> ICR, unary expression
+ -> DECR, unary expression
+ -> unary operator, cast expression
+ -> SIZEOF, unary expression
+ -> SIZEOF, '(', type name, ')'
+
+unary operator
+ -> '&' | '*' | '+' | '-' | '~' | '!'
+
+postfix expression
+ -> primary expression
+ -> postfix expression, '[', expression, ']'
+ -> postfix expression, '(', argument expression list?, ')'
+ -> postfix expression, '.', identifier
+ -> postfix expression, ARROW, identifier
+ -> postfix expression, ICR
+ -> postfix expression, DECR
+
+primary expression
+ -> identifier
+ -> constant
+ -> STRINGliteral
+ -> '(', expression, ')'
+
+argument expression list
+ -> assignment expression
+ -> argument expression list, ',', assignment expression
+
+constant
+ -> HEXconstant
+ -> OCTconstant
+ -> DECconstant
+ -> FLOATconstant
+ -> CHARACTERconstant
+
+
+{                                           // Embedded C
+#include <stack.h>
+
+
+// Macro Definitions
+
+#define INPUT_CODE(T) (T).id
+#define SYNTAX_ERROR  syntax_error(PCB.error_message)
+
+
+// Variable definitions
+
+static int use_count = 0;
+symbol_type_enum symbol_table[N_SYMBOLS];
+
+
+/*
+  mark_typedef() gets a non_zero argument for typedef statements, a zero
+  argument otherwise. If the argument is non-zero it marks all stacked
+  identifiers as typedef_names. It then resets the id stack.
+*/
+
+static void mark_typedef(int mask) {
+  unsigned x;
+  if (mask) {
+    while (size(id_stack)) {
+      id_stack >> x;
+      symbol_table[x] = typedef_name;
+    }
+    return;
+  }
+  reset(id_stack);
+}
+
+/*
+  check_typedef() resolves a semantically determined productin by determining
+  whether a token is a typedef_name or not.  If so it changes the reduction
+  token appropriately.
+*/
+
+static token check_typedef(token t) {
+  if (symbol_table[t.handle] == typedef_name)
+    CHANGE_REDUCTION(typedef_name);
+  return t;
+}
+
+
+// Member Functions for Class c_parser
+
+// Constructor
+
+/*
+  This parser has no provisions for multiple simultaneous parses or for
+  recursion. The purpose of use_count is to make sure that there is only one
+  copy of the parser active at any time.
+*/
+
+
+c_parser::c_parser() {
+  assert(use_count == 0);
+  use_count++;
+  reset(id_stack);
+  memset(symbol_table, 0, sizeof(symbol_table));
+  init_cc();                                // init parse
+}
+
+
+// Destructor
+
+c_parser::~c_parser() {
+  use_count--;                              // Makes parser available
+}
+
+
+// Reset Parser
+
+c_parser &reset(c_parser &c) {
+  reset(id_stack);
+  memset(symbol_table, 0, sizeof(symbol_table));
+  init_cc();                                // init parse
+  return c;
+}
+
+
+// Transmit token to c_parser
+
+/*
+  The overloaded operator "<<" is used to transmit data to a parser.
+  Newline tokens are filtered out, since they are passed along by the
+  token scanner only in case text output of the preprocessor is
+  required.
+
+  If the parser has encountered an error, there is no point in giving
+  it any further input.
+
+  Otherwise, the input_code and input_value fields of the pcb are set
+  up and cc() is called to deal with the token.
+*/
+
+token_sink &c_parser::operator << (token c) {
+  if (PCB.exit_flag != AG_RUNNING_CODE || (int) c.id == '\n') return *this;
+  PCB.input_code = c.id;
+  PCB.input_value = c;
+  cc();
+  return *this;
+}
+
+token_sink &c_parser::operator << (token *s) {
+  while (s->id != END_OF_FILE && PCB.exit_flag == AG_RUNNING_CODE) {
+    if ((int) s->id == 10) continue;
+    PCB.input_code = s->id;
+    PCB.input_value = *s++;
+    cc();
+  }
+  return *this;
+}
+
+}                                           // End Embedded C
+