home *** CD-ROM | disk | FTP | other *** search
-
- %{
- /*
- token.lm
-
- This file defines the tokens that the Expression grammar is built on. To
- fully understand this file, you will need to understand lex. The basic
- idea is that lex scans a text stream and breaks that stream up into tokens
- which are then fed to the grammar (defined in yacc). Whitespace is ignored
- so the grammar is just fed a steady stream of significant tokens.
- */
-
- /*
- * These are the routines lex calls to get another character as it parses.
- * By default they are macros which read from stdin. We toss the default
- * macro definitions and supply our own versions of these, which will feed
- * lex characters from the expression string we are parsing.
- */
- #undef input
- #undef unput
- #undef output
- static int input();
- static void unput(char c);
- static void output(char c);
-
- #import <stdlib.h>
- #import <string.h>
- #import <math.h>
- #import "exprDefs.h"
- #import "y.tab.h"
-
- /* global which holds the string we are parsing */
- static const char *CurrText;
-
- /* glue to get rid of compiler warnings */
- extern yylook(), yyback();
- static int yywrap();
- %}
-
- DIGIT ([0-9])
- EXP ([Ee][+-]?[0-9]+)
-
- %%
-
-
- [ \t\n]+ { /* whitespace - we ignore it */
- ;
- }
-
- {DIGIT}+ { /* an integer */
- yylval.integer = atoi(yytext);
- return INTEGER;
- }
-
- (({DIGIT}+"."{DIGIT}*{EXP}?)|([+-]?{DIGIT}*"."{DIGIT}+{EXP}?)|({DIGIT}+{EXP})) { /* a float */
- yylval.real = atof(yytext);
- return NUMBER;
- }
-
- {DIGIT}+"#"[a-zA-Z0-9]+ { /* a radix number */
- int radix;
- register int mult = 1;
- register char *c, *stop;
- register unsigned int accum = 0;
- register int charVal;
-
- sscanf( yytext, "%d#", &radix );
- for( stop = yytext; *stop++ != '#'; ); /* skip the pound sign */
- for( c = yytext+yyleng-1; c >= stop; c--, mult *= radix ) {
- if( *c >= '0' && *c <= '9' )
- charVal = *c - '0';
- else if( *c >= 'A' && *c <= 'Z' )
- charVal = *c - 'A' + 10;
- else
- charVal = *c - 'a' + 10;
- accum += mult * charVal;
- }
- yylval.real = accum;
- return NUMBER;
- }
-
- pi { /* the constant pi */
- yylval.real = M_PI;
- return NUMBER;
- }
-
- e { /* the constant e */
- yylval.real = M_E;
- return NUMBER;
- }
-
- [-+*/%^(),] { /* a single char that must be recognized */
- return yytext[0];
- }
-
- [A-Za-z_][A-Za-z_0-9]* { /* an identifier */
- yylval.string = NXZoneMalloc(NXDefaultMallocZone(), yyleng+1);
- bcopy(yytext, yylval.string, yyleng);
- yylval.string[yyleng] = '\0';
- return IDENTIFIER;
- }
-
- . { /* other garbage chars (last rule is the default) */
- yylval.character = yytext[0];
- return BADCHAR;
- }
-
-
- %%
-
- /* inits the global string to the one we will parse */
- void _EXPPrepareToScan(const char *text) {
- CurrText = text;
- }
-
- /* tells lex there's really no more input when we're done */
- static int yywrap() {
- return 1;
- }
-
- /* returns the next char of the string we're parsing */
- static int input() {
- return *CurrText++;
- }
-
- /* lets lex back up one char in the string we're parsing */
- static void unput(char c) {
- --CurrText;
- }
-
- /* called by lex when it wants to output a char. This should never happen. */
- static void output(char c) {
- fprintf(stderr, "lex output function called with char '%c'\n", c);
- }
-