/* * Copyright (C) 2006 Bill Cox * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA */ %{ #include #include #include #include #include "dv.h" #include "dvparse.h" #define YY_NEVER_INTERACTIVE 1 #define YY_INPUT(buf,result,max_size) \ if((result = dvRead((char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); static int dvRead(char *buf, int maxSize) { int numChars = 0; int c; static bool lastWasReturn = true; do { if(lastWasReturn) { /* Insert a tab in front of each line to force a character to match */ c = '\t'; lastWasReturn = false; } else { c = getc(dvFile); } if(c != EOF && c != '\r') { *buf++ = c; numChars++; if(c == '\n') { lastWasReturn = true; } } } while(numChars < maxSize && c != EOF); return numChars; } static char *unmunge( char *string) { char *buffer = utMakeString(strlen(string) + 1); char *p = buffer; string++; /* Skip " */ while(*string != '"') { if(*string == '\\') { string++; } *p++ = *string++; } *p = '\0'; return buffer; } static uint16 findIndentDepth(char *string) { uint16 length = 0; while(*string) { if(*string == ' ') { length++; } else if(*string == '\t') { length += 8; } string++; } return length; } int dvlexwrap(void) { return 1; } #ifdef DV_DEBUG #define myDebug utDebug #else #define myDebug noDebug #endif #undef YYLMAX #define YYLMAX 4096 static uint16 dvCommentDepth, dvIndentLevels = 0, dvIndentDepth[DV_MAX_INDENT] = {8}; static void noDebug(char *foo, ...) {} %} %Start comment %% ^[ \t]*"//".*\n { dvLineNum++; myDebug("comment line\n");} /* Single line comment */ [ \t]*"//".*\n { dvLineNum++; myDebug("newline\n"); return '\n';} /* Tail comment */ "/*" { myDebug("Start block comment...\n"); dvCommentDepth = 1; BEGIN comment; } "/*" { dvCommentDepth++; } "*/" { myDebug("End block comment\n"); dvCommentDepth--; if (dvCommentDepth == 0) { BEGIN INITIAL; } } . ; "\n" { dvLineNum++; } ^[ \t]*\n {dvLineNum++; } ^[ \t]+ { uint16 length = findIndentDepth(dvlextext); uint16 oldLevels = dvIndentLevels; if(length > dvIndentDepth[dvIndentLevels]) { dvIndentDepth[++dvIndentLevels] = length; myDebug("KWBEGIN\n"); return KWBEGIN; } else if(length < dvIndentDepth[dvIndentLevels]) { while(dvIndentLevels > 0 && length != dvIndentDepth[dvIndentLevels]) { dvIndentLevels--; } if(length != 8 && dvIndentLevels == 0) { dverror("Mismatched indentation"); } if(dvIndentLevels + 1 != oldLevels) { dvNumEndsRemaining = oldLevels - dvIndentLevels - 1; myDebug("Starting multiple ends...\n"); } myDebug("KWEND\n"); return KWEND; }} [ \t]+ ; "array" {myDebug("KWARRAY\n"); return KWARRAY;} "attributes" {myDebug("KWATTRIBUTES\n"); return KWATTRIBUTES;} "bit" {myDebug("KWBIT\n"); return KWBIT;} "bool" {myDebug("KWBOOL\n"); return KWBOOL;} "cascade" {myDebug("KWCASCADE\n"); return KWCASCADE;} "char" {myDebug("KWCHAR\n"); return KWCHAR;} "child_only" {myDebug("KWCHILD_ONLY\n"); return KWCHILD_ONLY;} "class" {myDebug("KWCLASS\n"); return KWCLASS;} "create_only" {myDebug("KWCREATE_ONLY\n"); return KWCREATE_ONLY;} "double" {myDebug("KWDOUBLE\n"); return KWDOUBLE;} "doubly_linked" {myDebug("KWDOUBLY_LINKED\n"); return KWDOUBLY_LINKED;} "enum" {myDebug("KWENUM\n"); return KWENUM;} "fixed_number" {myDebug("KWFIXED_NUMBER\n"); return KWFIXED_NUMBER;} "float" {myDebug("KWFLOAT\n"); return KWFLOAT;} "free_list" {myDebug("KWFREE_LIST\n"); return KWFREE_LIST;} "hashed" {myDebug("KWHASHED\n"); return KWHASHED;} "heap" {myDebug("KWHEAP\n"); return KWHEAP;} "import" {myDebug("KIMPORT\n"); return KWIMPORT;} "linked_list" {myDebug("KWLINKED_LIST\n"); return KWLINKED_LIST;} "mandatory" {myDebug("KWMANDATORY\n"); return KWMANDATORY;} "module" {myDebug("KWMODULE\n"); return KWMODULE;} "parent_only" {myDebug("KWPARENT_ONLY\n"); return KWPARENT_ONLY;} "persistent" {myDebug("KWPERSISTENT\n"); return KWPERSISTENT;} "reference_size" {myDebug("KWREFERENCE_SIZE\n"); return KWREFERENCE_SIZE;} "relationship" {myDebug("KWRELATIONSHIP\n"); return KWRELATIONSHIP;} "schema" {myDebug("KWSCHEMA\n"); return KWSCHEMA;} "sparse" {myDebug("KWSPARSE\n"); return KWSPARSE;} "sym" {myDebug("KWSYM\n"); return KWSYM;} "tail_linked" {myDebug("KWTAIL_LINKED\n"); return KWTAIL_LINKED;} "typedef" {myDebug("KWTYPEDEF\n"); return KWTYPEDEF;} "undo_redo" {myDebug("KWUNDO_REDO\n"); return KWUNDO_REDO;} "union" {myDebug("KWUNION\n"); return KWUNION;} "volatile" {myDebug("KWVOLATILE\n"); return KWVOLATILE;} "+"\n { myDebug("Line continuation\n"); dvLineNum++; } \n { myDebug("newline\n"); dvLineNum++; return '\n'; } [0-9]+ { dvlval.intVal = atol(dvlextext); myDebug("INTEGER %u\n", dvlval.intVal); return INTEGER; } int[0-9]* { if(strlen(dvlextext) == 3) { dvlval.intVal = 32; } else { dvlval.intVal = atol(dvlextext + 3); } myDebug("INTTYPE %u\n", dvlval.intVal); return INTTYPE; } uint[0-9]* { if(strlen(dvlextext) == 4) { dvlval.intVal = 32; } else { dvlval.intVal = atol(dvlextext + 4); } myDebug("UINTTYPE %u\n", dvlval.intVal); return UINTTYPE; } [a-zA-Z][a-zA-Z0-9_]* { myDebug("IDENT %s\n", dvlextext); dvlval.symVal = utSymCreate(dvlextext); return IDENT; } \"([^"]|\"\"-)*\" { myDebug("STRING %s\n", dvlextext); dvlval.stringVal = utSymCreate(unmunge(dvlextext)); return STRING; } . { myDebug("Char '%c'\n", dvlextext[0]); return dvlextext[0]; }