Mercurial > ~dholland > hg > ag > index.cgi
diff examples/mpp/token.h @ 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/token.h Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,258 @@ +/* + * AnaGram, a System for Syntax Directed Programming + * C Macro preprocessor + * Token handling definitions + * + * Copyright 1993 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. + */ + +#ifndef TOKEN_H +#define TOKEN_H + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include "charsink.h" +#include "strdict.h" + +extern string_dictionary td; + + +// define token identification codes + +enum token_id { + END_OF_FILE =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 + 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 +}; + +struct token { + unsigned handle; // token dictionary index + token_id id; // token type +}; + +// Token sink class + +class token_sink { +public: + virtual ~token_sink() {} + virtual token_sink &operator << (token) = 0; + virtual token_sink &operator << (token *) = 0; + friend int error(token_sink &); +}; + + +// Token accumulator +// Member functions that are not inline are in token.cpp + +class token_accumulator : public token_sink { + token *cs; + unsigned *xs; + unsigned csx; + unsigned xsx; + unsigned csmax; + unsigned xsmax; +public: + +// Constructor + + token_accumulator(int nc, int nx = 1); + + +// Destructor + + ~token_accumulator(); + + +// Reset token accumulator + + friend token_accumulator &reset(token_accumulator &); + + +// Change levels + + token_accumulator& operator ++(){ + assert(xsx); // Room for another level? + xs[--xsx] = csx; + return *this; + } + + token_accumulator& operator --() { + csx = xs[xsx++]; + assert(xsx < xsmax); // Have to leave last level active + return *this; + } + + +// Push data + + token_sink& operator << (token c) { + assert(csx < csmax); // room for data? + cs[csx++] = c; + return *this; + } + + token_sink &operator << (token *tp); + + token_sink &operator << (token_accumulator &t) { + assert(this != &t); // prevent disaster + return *this << (token *) t; + } + +// Pop data + + token_accumulator &operator >> (token &c); + + +// Access data + + //token &operator [](unsigned); + + operator token *() { + cs[csx].id = END_OF_FILE; + cs[csx].handle = 0; + return &cs[xs[xsx]]; + } + + +// Concatenate token strings + + friend token_accumulator& concat(token_accumulator &); + + +// Make permanent copy of token string + + friend token *copy(token_accumulator &); + + +// Get size of token string + + friend unsigned size(token_accumulator &s); + +// Check for error + + friend int error(token_accumulator &t); + +}; + + inline unsigned size(token_accumulator &s) { + return s.csx - s.xs[s.xsx]; + } + + inline int error(token_accumulator &t) { + return t.csx >= t.csmax || t.xsx >= t.xsmax; + } + + + +// Token Translator class + +class token_translator : public token_sink { + character_sink *cs; + int space_required; +public: + + +// Constructor + + token_translator(character_sink *sink) { + cs = sink; + space_required = 0; + } + + +// Accept data + + token_sink &operator << (token t) { + if (space_required && t.id > 128) *cs << ' '; + *cs << td[t.handle]; + space_required = t.id > 128; + return *this; + } + + token_sink &operator << (token *tp); + + +// Check for error; + friend int error(token_sink &) {return 0;} +}; + +#endif