%{ static char const rcsid[] = "$Id: harmony.lex,v 1.8 1998/07/31 22:45:56 liddl Exp $"; /*======================================================================== * Harmony Core Language Parser * Object-Oriented Systems Modeling Research Group * * Dr. Stephen W. Liddle (liddle@byu.edu) * School of Accountancy and Information Systems * Marriott School of Management * 540 TNRB, P.O. Box 23068-3068 * Brigham Young University * Provo, UT 84602 * * Dr. David W. Embley (embley@cs.byu.edu) and * Dr. Scott N. Woodfield (woodfiel@cs.byu.edu) * Department of Computer Science * 3361 TMCB * Brigham Young University * Provo, UT 84602 * * Copyright (C) 1995-1998, Board of Trustees of Brigham Young University * * Harmony Core Language Parser software, both binary and source * (hereafter, Software) is copyrighted by The Board of Trustees of * Brigham Young University (BYU), and ownership remains with BYU. * * BYU grants you (hereafter, Licensee) a license to use the Software * for academic, research and internal business purposes only, without a * fee. Licensee may distribute the binary and source code (if released) * to third parties provided that the copyright notice and this statement * appears on all copies and that no charge is associated with such * copies. * * Licensee may not make derivative works without first arranging an * additional license agreement with BYU. * * Any Licensee wishing to make commercial use of the Software should * contact BYU to negotiate an appropriate license for such * commercial use. Commercial use includes (1) integration of all or * part of the source code into a product for sale or license by or on * behalf of Licensee to third parties, or (2) distribution of the binary * code or source code to third parties that need it to utilize a * commercial product sold or licensed by or on behalf of Licensee. * * BYU MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED * WARRANTY. BYU SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE * USERS OF THIS SOFTWARE. * * By using or copying this Software, Licensee agrees to abide by the * copyright law and all other applicable laws of the United States * including, but not limited to, export control laws, and the terms * of this license. BYU shall have the right to terminate this license * immediately by written notice upon Licensee's breach of, or * non-compliance with, any of its terms. Licensee may be held legally * responsible for any copyright infringement that is caused or * encouraged by Licensee's failure to abide by the terms of this license. * * Comments and questions are welcome and can be sent to liddle@byu.edu. */ /*======================================================================== * $RCSfile: harmony.lex,v $ * * $Author: liddl (Stephen W. Liddle) $ * $Date: 1998/07/31 22:45:56 $ * $Revision: 1.8 $ * * $Description: * Harmony lexer source, borrowed from Melody lexer. $ * * $Log: harmony.lex,v $ * Revision 1.8 1998/07/31 22:45:56 liddl * Fixed miscellaneous bugs that Scott found. * * Revision 1.7 1998/07/28 22:25:16 liddl * Added <=> (EQUIV) operator. * * Revision 1.6 1998/07/28 19:01:31 liddl * Added MOD/DIV keywords. * * Revision 1.5 1998/07/10 20:51:36 liddl * Added support for non-printing characters (nul, bel, etc.) * and Unicode(expression). * * Revision 1.4 1998/06/24 19:01:23 liddl * Updated for 1.1 core. * */ /*------------------------------------------------------------------------ * INCLUDES */ #include #include #include #include "lex_sym.h" #include "semantic.H" /*------------------------------------------------------------------------ * CONSTANTS */ #define INFORMAL_CHUNK 1000 /*------------------------------------------------------------------------ * MACROS */ #define DEBUG 1 #ifdef DEBUG # if DEBUG # define P(x) Prev_col = Col_num; Col_num += strlen(YYText()); \ if (Debug_lex) \ fprintf(stderr, "line %ld: %-17s %s\n", Line_num, \ x, YYText()) # define Q(x) if (Debug_lex) \ fprintf(stderr, "line %ld: %-17s <<%s>>\n", \ Line_num, x, Informal_text) # else # define P(x) Prev_col = Col_num; Col_num += strlen(YYText()); # define Q(x) # endif #else # define P(x) Prev_col = Col_num; Col_num += strlen(YYText()); # define Q(x) #endif #define KEY(x) if (Case_Is_Key()) { \ P(#x); return (x); \ } else { \ REJECT; \ } /*------------------------------------------------------------------------ * STATIC GLOBAL VARIABLES */ static long Informal_len = 0; static long Comment_level = 0; /*------------------------------------------------------------------------ * GLOBAL VARIABLES */ int Debug_lex = 0; long Col_num = 1, Line_num = 1, Prev_col = 1, Prev_line = 1; char *Informal_ptr, *Informal_text = NULL, *Parse_str = NULL; /*------------------------------------------------------------------------ * GLOBAL VARIABLES */ extern FlexLexer *Harmony_lexer; /*------------------------------------------------------------------------ * STATIC FUNCTION DECLARATIONS */ static void Add_Informal_Letter(void); %} %option reject %e 2000 %a 4000 %p 5000 %o 6000 %x COMMENT INFORML digit ([0-9]) hexdigit ([0-9a-fA-F]) nonneghex (0[xX]{hexdigit}+) nonnegint ({digit}+) exponent ({white}[Ee]{white}[+-]?{white}{nonnegint}) float ({nonnegint}"."{nonnegint}{exponent}?) upper ([A-Z]) lower ([a-z]) special1 ("("|")"|"*"|"+"|","|"-"|"."|"/"|"\\"|";") special2 ("<"|"="|">"|"@"|"["|"]"|"^"|"{"|"|"|"}"|":"|"?") nonsymbol ("!"|"$"|"&"|"`"|"#"|"%") special ({special1}|{special2}|{nonsymbol}|"_"|"~"|["]|[']) symbol ({nonsymbol}|"\\"{special}) upperletter ({upper}|"\\"{upper}|{symbol}|"\\"{digit}) lowerletter ({lower}|"\\"{lower}) any_letter ({upperletter}|{lowerletter}|{digit}) upperword (({upperletter}{any_letter}*)|("~"+{any_letter}+)) lowerword (({lowerletter}{any_letter}*)|("_"+{any_letter}+)) qstring ((['][~']*['])|(["][~"]*["])) white ([ \t\f\r\n]*) thread ([tT][hH][rR][eE][aA][dD]) iswsa ([iI][sS]{white}[aA]) nul ([nN][uU][lL]) bel ([bB][eE][lL]) bs ([bB][sS]) tab ([tT][aA][bB]) lf ([lL][fF]) ff ([fF][fF]) cr ([cC][rR]) esc ([eE][sS][cC]) quote ([qQ][uU][oO][tT][eE]) tic ([tT][iI][cC]) unicode ([uU][nN][iI][cC][oO][dD][eE]) add ([aA][dD][dD]) and ([aA][nN][dD]) ascending ([aA][sS][cC][eE][nN][dD][iI][nN][gG]) boolean ([bB][oO][oO][lL][eE][aA][nN]) by ([bB][yY]) commit ([cC][oO][mM][mM][iI][tT]) constant ([cC][oO][nN][sS][tT][aA][nN][tT]) descending ([dD][eE][sS][cC][eE][nN][dD][iI][nN][gG]) digits ([dD][iI][gG][iI][tT][sS]) div ([dD][iI][vV]) do ([dD][oO]) else ([eE][lL][sS][eE]) elseif ([eE][lL][sS][eE][iI][fF]) end ([eE][nN][dD]) enter ([eE][nN][tT][eE][rR]) entering ({enter}[iI][nN][gG]) exception ([eE][xX][cC][eE][pP][tT][iI][oO][nN]) exists ([eE][xX][iI][sS][tT][sS]) false ([fF][aA][lL][sS][eE]) forall ([fF][oO][rR]{white}[aA][lL][lL]) foreach ([fF][oO][rR]{white}[eE][aA][cC][hH]) from ([fF][rR][oO][mM]) if ([iI][fF]) includes ([iI][nN][cC][lL][uU][dD][eE][sS]) inf ([iI][nN][fF]) integer ([iI][nN][tT][eE][gG][eE][rR]) interaction ([iI][nN][tT][eE][rR][aA][cC][tT][iI][oO][nN]) isa ({iswsa}) isai ({isa}{white}"["{white}[iI][nN][tT][eE][rR][sS][eE][cC][tT][iI][oO][nN]{white}"]") isam ({isa}{white}"["{white}[dD][iI][sS][jJ][oO][iI][nN][tT]{white}"]") isap ({isa}{white}"["{white}[pP][aA][rR][tT][iI][tT][iI][oO][nN]{white}"]") isau ({isa}{white}"["{white}[uU][nN][iI][oO][nN]"]") mergethr ([mM][eE][rR][gG][eE]{white}{thread}) modulo ([mM][oO][dD]) nan ([nN][aA][nN]) newthread ([nN][eE][wW]{white}{thread}) not ([nN][oO][tT]) object ([oO][bB][jJ][eE][cC][tT]) objectset ([oO][bB][jJ][eE][cC][tT]{white}[sS][eE][tT]) oneof ([oO][nN][eE]{white}[oO][fF]) or ([oO][rR]) priority ([pP][rR][iI][oO][rR][iI][tT][yY]) real ([rR][eE][aA][lL]) remove ([rR][eE][mM][oO][vV][eE]) self ([sS][eE][lL][fF]) selfthread ([sS][eE][lL][fF]{white}{thread}) start ([sS][tT][aA][rR][tT]) state ([sS][tT][aA][tT][eE]) string ([sS][tT][rR][iI][nN][gG]) then ([tT][hH][eE][nN]) to ([tT][oO]) toall ([tT][oO]{white}[aA][lL][lL]) true ([tT][rR][uU][eE]) wait ([wW][aA][iI][tT]) when ([wW][hH][eE][nN]) where ([wW][hH][eE][rR][eE]) while ([wW][hH][iI][lL][eE]) %% {nul} { KEY(NUL); } {bel} { KEY(BEL); } {bs} { KEY(BS); } {tab} { KEY(TAB); } {lf} { KEY(LF); } {ff} { KEY(FF); } {cr} { KEY(CR); } {esc} { KEY(ESC); } {quote} { KEY(QUOTE); } {tic} { KEY(TIC); } {unicode} { KEY(UNICODE); } {add} { KEY(ADD); } {and} { KEY(AND); } {ascending} { KEY(ASCENDING); } {boolean} { KEY(BOOLEAN); } {by} { KEY(BY); } {commit} { KEY(COMMIT); } {constant} { KEY(CONSTANT); } {descending} { KEY(DESCENDING); } {digits} { KEY(DIGITS); } {div} { KEY(DIV); } {do} { KEY(DO); } {else} { KEY(ELSE); } {elseif} { KEY(ELSEIF); } {end} { KEY(END); } {enter} { KEY(ENTER); } {entering} { KEY(ENTERING); } {exception} { KEY(EXCEPTION); } {exists} { KEY(EXISTS); } {false} { KEY(FALSEKEY); } {forall} { KEY(FORALL); } {foreach} { KEY(FOREACH); } {from} { KEY(FROM); } {if} { KEY(IF); } {includes} { KEY(INCLUDES); } {inf} { KEY(INF); } {integer} { KEY(INTEGER); } {interaction} { KEY(INTERACTION); } {isa} { KEY(ISA); } {isai} { KEY(ISAI); } {isam} { KEY(ISAM); } {isap} { KEY(ISAP); } {isau} { KEY(ISAU); } {modulo} { KEY(MODULO); } {nan} { KEY(NAN); } {newthread} { KEY(NEWTHREAD); } {not} { KEY(NOT); } {object} { KEY(OBJECTKEY); } {objectset} { KEY(OBJECTSET); } {oneof} { KEY(ONEOF); } {or} { KEY(OR); } {mergethr} { KEY(MERGETHR); } {real} { KEY(REAL); } {remove} { KEY(REMOVE); } {self} { KEY(SELF); } {selfthread} { KEY(SELFTHREAD); } {start} { KEY(START); } {state} { KEY(STATE); } {string} { KEY(STRINGKEY); } {then} { KEY(THEN); } {to} { KEY(TO); } {toall} { KEY(TOALL); } {true} { KEY(TRUEKEY); } {wait} { KEY(WAIT); } {when} { KEY(WHEN); } {where} { KEY(WHERE); } {while} { KEY(WHILE); } "@" { P("AT"); return (AT); } "|" { P("BAR"); return (BAR); } "^" { P("CARET"); return (CARET); } ":" { P("COLON"); return (COLON); } "," { P("COMMA"); return (COMMA); } "->" { P("DETERMINES"); return (DETERMINES); } "=" { P("EQUAL"); return (EQUAL); } "<=>" { P("EQUIV"); return (EQUIV); } ">=" { P("GREATEQ"); return (GREATEQ); } "-" { P("MINUS"); return (MINUS); } "=>" { P("IMPLIES"); return (IMPLIES); } "<" { P("LANGLE"); return (LANGLE); } "{" { P("LBRACE"); return (LBRACE); } "[" { P("LBRACKET"); return (LBRACKET); } "<=" { P("LESSEQ"); return (LESSEQ); } ":-" { P("LOGICSEP"); return (LOGICSEP); } ":=" { P("ASSIGNOP"); return (ASSIGNOP); } "(" { P("LPAREN"); return (LPAREN); } "<>" { P("NOTEQ"); return (NOTEQ); } "." { P("PERIOD"); return (PERIOD); } ".." { P("DOTDOT"); return (DOTDOT); } "+" { P("PLUS"); return (PLUS); } "?" { P("INFORMAL"); return (INFORMAL); } ">" { P("RANGLE"); return (RANGLE); } "}" { P("RBRACE"); return (RBRACE); } "]" { P("RBRACKET"); return (RBRACKET); } ")" { P("RPAREN"); return (RPAREN); } ";" { P("SEMICOLON"); return (SEMICOLON); } "/" { P("SLASH"); return (SLASH); } "*" { P("STAR"); return (STAR); } "(." { P("SUBSETOF"); return (SUBSETOF); } ".)" { P("INCSYM"); return (INCSYM); } "(=" { P("SUBSETEQ"); return (SUBSETEQ); } "=)" { P("INCSYMEQ"); return (INCSYMEQ); } {float} { P("FLOAT"); return (FLOAT); } {nonnegint} { P("NONNEGINT"); return (NONNEGINT); } {nonneghex} { P("NONNEGINT"); return (NONNEGINT); } {qstring} { P("STRING"); return (STRING); } {lowerword} { P("LOWERWORD"); return (LOWERWORD); } {upperword} { P("UPPERWORD"); return (UPPERWORD); } "--".*$ { P("NOTE"); } "/-" { BEGIN(COMMENT); ++Comment_level; Prev_col = Col_num; Prev_line = Line_num; Col_num += 2; } "-/" { Col_num += 2; if (--Comment_level <= 0) { BEGIN(INITIAL); P("NOTE"); } } "/-" { ++Comment_level; Col_num += 2; } \r* { Col_num = 1; } \n { Col_num = 1; ++Line_num; } . { ++Col_num; } "<<" { BEGIN(INFORML); Prev_col = Col_num; Prev_line = Line_num; Col_num += 2; if (Informal_text == NULL) { Informal_text = new char[INFORMAL_CHUNK]; if (Informal_text == NULL) { fprintf(stderr, "Harmony: Out of memory in INFORMAL.\n"); exit (-102); } Informal_len = INFORMAL_CHUNK; Informal_ptr = Informal_text; } } ">>" { Col_num += 2; BEGIN(INITIAL); *Informal_ptr = '\0'; Q("INFORMAL"); return (INFORMAL); } \r* { Col_num = 1; Add_Informal_Letter(); } \n { Col_num = 1; ++Line_num; Add_Informal_Letter(); } . { ++Col_num; Add_Informal_Letter(); } [\t] { Col_num += 8 - (Col_num % 8); Prev_col = Col_num; } [ \f]* { Col_num += strlen(YYText()); Prev_col = Col_num; } \r* { Prev_col = Col_num; Col_num = 1; } \n { Prev_col = Col_num = 1; Prev_line = ++Line_num; } . { Dump_Text(stderr, Parse_str, Col_num, Line_num); fprintf(stderr, "harmony: Line %ld Col %ld: Invalid input (%s)\n", Line_num, Col_num, YYText()); char tmp[10]; yy_flex_strcpy(tmp, "test"); exit (-1); } %% /*========================================================================= * FUNCTIONS */ /*------------------------------------------------------------------------ * FUNCTION yy_flex_strcpy -- needed by Flex */ void yy_flex_strcpy(char *dest, const char *src) { while ((*dest++ = *src++)) ; } /* yy_flex_strcpy */ /*------------------------------------------------------------------------ * FUNCTION Add_Informal_Letter -- add one letter to informal string */ static void Add_Informal_Letter() { *Informal_ptr++ = *(Harmony_lexer->YYText()); if (Informal_ptr >= Informal_text + Informal_len) { char *tmp; long inf_len = Informal_ptr - Informal_text; Informal_len += INFORMAL_CHUNK; tmp = new char[Informal_len]; if (tmp == NULL) { fprintf(stderr, "Harmony: Out of memory in Add_Informal_Letter.\n"); exit (-101); } memcpy(tmp, Informal_text, inf_len); delete Informal_text; Informal_text = tmp; Informal_ptr = Informal_text + inf_len; } } /* Add_Informal_Letter */ /*======================================================================== * END OF FILE $RCSfile: harmony.lex,v $ */