/* * Copyrigth (C) 2002 Marcello Barnaba * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Simple pascal lexer. * Developed on NetBSD. */ %{ #include "rvp.h" #include "memory.h" #include "y.tab.h" #define YY_NO_UNPUT #define STR_CHUNK 128 #define ADD_CHAR_TO_BUF(c) \ if(str_len + 1 > str_allocated) \ { \ str_allocated += STR_CHUNK; \ strbuf = xrealloc(strbuf, str_allocated); \ strptr = strbuf + str_len; \ } \ *strptr++ = (c); \ str_len++ #define TRUE 1 #define FALSE 0 int line_num = 1; int pos_num = 1; char *strbuf; char *strptr; int str_len, str_allocated; static void lexerror(char *, ...); extern int yylval; extern char *yylbuf; %} DGT [0-9] %option noyywrap %option caseless %x bracecomment %x parencomment %x string %% {DGT}+ { pos_num += strlen(yytext); yylval = strtol(yytext, NULL, 0); return (INT_CONST); } {DGT}+"."{DGT}* { pos_num += strlen(yytext); yylval = strtod(yytext, NULL); return (REAL_CONST); } true { pos_num += 4; yylval = TRUE; return (BOOL_CONST); } false { pos_num += 5; yylval = FALSE; return (BOOL_CONST); } program { pos_num += 7; return (PROGRAM); } if { pos_num += 2; return (IF); } then { pos_num += 4; return (THEN); } else { pos_num += 4; return (ELSE); } begin { pos_num += 5; return (BEGIN_); } end { pos_num += 3; return (END); } while { pos_num += 5; return (WHILE); } do { pos_num += 2; return (DO); } integer { pos_num += 7; return (INTEGER); } real { pos_num += 4; return (REAL); } char { pos_num += 4; return (CHAR); } boolean { pos_num += 7; return (BOOLEAN); } var { pos_num += 3; return (VAR); } and { pos_num += 3; return (AND); } or { pos_num += 2; return (OR); } not { pos_num += 3; return (NOT); } div { pos_num += 3; return (DIV); } mod { pos_num += 3; return (MOD); } "<=" { pos_num += 2; return (LE); } ">=" { pos_num += 2; return (GE); } "<>" { pos_num += 2; return (NE); } ":=" { pos_num += 2; return (ASSIGN); } [:;\<\>\+\*\/=\.,()-] { pos_num++; return (*yytext); } [a-z_-][a-z0-9_-]* { pos_num += strlen(yytext); yylbuf = yytext; return (ID); } /* strings stuff. */ ' { BEGIN(string); strbuf = xmalloc(STR_CHUNK); strptr = strbuf; str_allocated = STR_CHUNK; str_len = 0; } { ' { BEGIN(INITIAL); *strptr = '\0'; yylbuf = strbuf; pos_num += str_len; return (STRING); } '' { ADD_CHAR_TO_BUF('\''); } \n { lexerror("unterminated string const.\n"); yyterminate(); } <> { lexerror("unterminated string const.\n"); yyterminate(); } [^\\\n\']+ { char *yptr = yytext; while(*yptr) { ADD_CHAR_TO_BUF(*yptr++); } } } /* parens comments. */ "(*" pos_num += 2; BEGIN(parencomment); { [^*\n] /* eat */ pos_num++; "*"+[^*)\n]* /* eat */ pos_num++; \n ++line_num; pos_num = 1; <> { lexerror("unexpected EOF."); yyterminate(); } "*"+")" pos_num += 2; BEGIN(INITIAL); } /* brace comments. */ "{" pos_num++; BEGIN(bracecomment); { [^}\n] /* eat */ pos_num++; \n ++line_num; pos_num = 1; <> { lexerror("unexpected EOF."); yyterminate(); } "}" pos_num++; BEGIN(INITIAL); } /* gnam gnam. */ [ \t] /* eat blanks */ pos_num++; \n ++line_num; pos_num = 1; . { lexerror("unknown character in input: '%s'\n", yytext); exit(-1); /* XXX to be fixed */ } %% /* dirty error routine . . let`s keep things simple. */ static void lexerror(char *fmt, ...) { va_list ap; fprintf(stderr, "line %d: fatal: ", line_num); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } /* vi:set ts=8 sts=4 sw=4 tw=79: */