/* * 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 "vp.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 *, ...); static void *xmalloc(size_t); static void *xrealloc(void *, size_t); 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); } procedure { pos_num += 9; return (PROCEDURE); } function { pos_num += 8; return (FUNCTION); } 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); } repeat { pos_num += 6; return (REPEAT); } until { pos_num += 5; return (UNTIL); } for { pos_num += 3; return (FOR); } to { pos_num += 2; return (TO); } downto { pos_num += 5; return (DOWNTO); } 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); } case { pos_num += 4; return (CASE); } of { pos_num += 2; return (OF); } with { pos_num += 4; return (WITH); } 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 += 2; return (DOTDOT); } [:;\<\>\+\*\/=\.,()-] { 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 */ } %% /* safe malloc */ static void *xmalloc(size_t x) { void *r; if((r = malloc(x))) { memset(r, 0, x); return r; } fprintf(stderr, "out of memory.\n"); exit(-1); /* NOTREACHED */ return NULL; } /* safe realloc */ static void *xrealloc(void *p, size_t x) { void *r; if((r = realloc(p, x))) return r; fprintf(stderr, "out of memory.\n"); exit(-1); /* NOTREACHED */ return NULL; } /* 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: */