/* * scanner-sming.l -- * * Lexical rules for scanning the SMIng MIB module language. * * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig. * * See the file "COPYING" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * @(#) $Id: scanner-sming.l 7734 2008-02-15 07:49:14Z schoenw $ */ %option noyywrap %{ #include #ifdef BACKEND_SMING #include #include #include #include #if defined(HAVE_WIN_H) #include "win.h" #endif #include "error.h" #include "util.h" #include "parser-sming.h" #include "parser-sming.tab.h" #include "scanner-sming.h" #ifdef HAVE_DMALLOC_H #include #endif /* we need a reentrant parser, so yylex gets arguments */ #if 0 #define YY_DECL int yylex YY_PROTO((YYSTYPE *lvalp, void *parser)) #else #define YY_DECL int yylex(YYSTYPE *lvalp, void *parser) #endif #define thisParser (*(Parser *) parser) #define MAX_NUMBER "18446744073709551615" /* max Counter64 */ /* * This makes the usual notation when referencing attributes also * work with our pure parser code. */ #define yylval (*lvalp) static YY_BUFFER_STATE yybuffer[MAX_LEX_DEPTH]; static int lexDepth = 0; int smingEnterLexRecursion(file) FILE *file; { if (lexDepth >= MAX_LEX_DEPTH) { return (-1); } yybuffer[lexDepth++] = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(file, YY_BUF_SIZE)); return (lexDepth); } void smingLeaveLexRecursion() { yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(yybuffer[--lexDepth]); } %} /* * Lex pattern definitions. */ delim ([^a-zA-Z0-9-]) lineBreak ("\n"|"\n\015"|"\015\n") WSP (" "|"\t") VCHAR ([\041-\176]) HTAB "\t" SP " " /* * Lex state definitions. */ %s Skipline %% /* * Lex rules for comments. Do you use {lineBreak} here because it * introduces a trailing context which is (a) slow and (b) causes * REJECT to be used. */ "//"({WSP}|{VCHAR})*/"\n" { } "//"({WSP}|{VCHAR})*/"\n\015" { } "//"({WSP}|{VCHAR})*/"\015\n" { } /* * Lex rules for some special tokens. */ [\{\}\(\)\;\,\-\.\|] { return yytext[0]; } ".." { return DOT_DOT; } "."/[^\.] { return DOT; } "::" { return COLON_COLON; } /* * Lex rules for separators. */ {lineBreak} { thisParser.line++; } {WSP} { } /* * Lex rules for known keywords. */ module/{delim} { yylval.id = yytext; return moduleKeyword; } import/{delim} { yylval.id = yytext; return importKeyword; } revision/{delim} { yylval.id = yytext; return revisionKeyword; } date/{delim} { yylval.id = yytext; return dateKeyword; } organization/{delim} { yylval.id = yytext; return organizationKeyword; } contact/{delim} { yylval.id = yytext; return contactKeyword; } description/{delim} { yylval.id = yytext; return descriptionKeyword; } reference/{delim} { yylval.id = yytext; return referenceKeyword; } extension/{delim} { yylval.id = yytext; return extensionKeyword; } typedef/{delim} { yylval.id = yytext; return typedefKeyword; } type/{delim} { yylval.id = yytext; return typeKeyword; } parent/{delim} { yylval.id = yytext; return parentKeyword; } identity/{delim} { yylval.id = yytext; return identityKeyword; } class/{delim} { yylval.id = yytext; return classKeyword; } extends/{delim} { yylval.id = yytext; return extendsKeyword; } attribute/{delim} { yylval.id = yytext; return attributeKeyword; } unique/{delim} { yylval.id = yytext; return uniqueKeyword; } event/{delim} { yylval.id = yytext; return eventKeyword; } format/{delim} { yylval.id = yytext; return formatKeyword; } units/{delim} { yylval.id = yytext; return unitsKeyword; } status/{delim} { yylval.id = yytext; return statusKeyword; } access/{delim} { yylval.id = yytext; return accessKeyword; } default/{delim} { yylval.id = yytext; return defaultKeyword; } abnf/{delim} { yylval.id = yytext; return abnfKeyword; } /* *Base types keywords */ OctetString/{delim} { yylval.id = yytext; return OctetStringKeyword; } Pointer/{delim} { yylval.id = yytext; return PointerKeyword; } ObjectIdentifier/{delim} { yylval.id = yytext; return ObjectIdentifierKeyword; } Integer32/{delim} { yylval.id = yytext; return Integer32Keyword; } Integer64/{delim} { yylval.id = yytext; return Integer64Keyword; } Unsigned32/{delim} { yylval.id = yytext; return Unsigned32Keyword; } Unsigned64/{delim} { yylval.id = yytext; return Unsigned64Keyword; } Float32/{delim} { yylval.id = yytext; return Float32Keyword; } Float64/{delim} { yylval.id = yytext; return Float64Keyword; } Float128/{delim} { yylval.id = yytext; return Float128Keyword; } Bits/{delim} { yylval.id = yytext; return BitsKeyword; } Enumeration/{delim} { yylval.id = yytext; return EnumerationKeyword; } /* *Status keywords */ current/{delim} { yylval.id = yytext; return currentKeyword; } deprecated/{delim} { yylval.id = yytext; return deprecatedKeyword; } obsolete/{delim} { yylval.id = yytext; return obsoleteKeyword; } /* *Access keywords */ eventonly/{delim} { yylval.id = yytext; return eventonlyKeyword; } readonly/{delim} { yylval.id = yytext; return readonlyKeyword; } readwrite/{delim} { yylval.id = yytext; return readwriteKeyword; } /* *Special floating point values' keywords */ neginf/{delim} { yylval.id = yytext; return neginfKeyword; } posinf/{delim} { yylval.id = yytext; return posinfKeyword; } snan/{delim} { yylval.id = yytext; return snanKeyword; } qnan/{delim} { yylval.id = yytext; return qnanKeyword; } /* * Lex rules for identifiers. */ /* e.g. module names: REF: draft,p.12-13 */ [A-Z](-?[a-zA-Z0-9_]+)*-? { if (yytext[yyleng-1] == '-') { smiPrintError(parser, ERR_ID_ENDS_IN_HYPHEN, yytext); } if (yyleng > 64) { smiPrintError(parser, ERR_UCIDENTIFIER_64, yytext); } if (strchr(yytext, '_')) { smiPrintError(parser, ERR_UNDERSCORE_IN_IDENTIFIER, yytext); } yylval.text = smiStrdup(yytext); return ucIdentifier; } /* same for lowercase names */ [a-z](-?[a-zA-Z0-9_]+)*-? { if (yytext[yyleng-1] == '-') { smiPrintError(parser, ERR_ID_ENDS_IN_HYPHEN, yytext); } if (yyleng > 64) { smiPrintError(parser, ERR_LCIDENTIFIER_64, yytext); } if (strchr(yytext, '_')) { smiPrintError(parser, ERR_UNDERSCORE_IN_IDENTIFIER, yytext); } yylval.text = smiStrdup(yytext); return lcIdentifier; } /* * Lex rules for numbers. * * NOTE: `-' is a separate token. Hence, there are no negative numbers. */ 0+/[0-9] { smiPrintError(parser, ERR_LEADING_ZEROS); } ([1-9][0-9]*|0)/[^0-9] { if ((yyleng > sizeof(MAX_NUMBER)-1) || ((yyleng == sizeof(MAX_NUMBER)-1) && (strcmp(yytext, MAX_NUMBER) > 0))) { smiPrintError(parser, ERR_NUMBER_TOO_LARGE, yytext); } yylval.text = yytext; return decimalNumber; } 0x[0-9a-fA-F]+/[^0-9a-fA-F] { if (yyleng % 2) { smiPrintError(parser, ERR_HEX_STRING_MUL2, yytext); } yylval.text = yytext; return hexadecimalNumber; } /* * Lex rules for floating point values. */ ([0-9]*\.[0-9]+([eE][+-]?[0-9]+)?)/[^0-9] { yylval.text = yytext; return floatValue; } /* * Lex rules for OID's. */ ([0-9A-Za-z]-?)+\.([0-9A-Za-z]-?)+\.([0-9A-Za-z]-?)+(\.([0-9A-Za-z]-?)+)*/([^0-9A-Za-z]) { yylval.text = yytext; return OID; } /* * Lex rules for textSegments. */ \"([^\"]|(\\\"))*\" { char *s, *d; /* the source and destination pointer */ int column = 0; /* the current column */ int newlineflag = 0; /* we have just passed a newline */ int cutoffcolumn = 0; /* cut off white space up to this column */ /* (computed by caculating the indentation */ /* of the first column) */ yytext[yyleng-1] = '\0'; for (d = yytext, s = yytext+1; s[0]; s++, d++) { if ((s[0] == '\n' && s[1] == '\r') /* newline sequence */ || (s[0] == '\r' && s[1] == '\n')) { thisParser.line += 1; d[0] = '\n'; s++; newlineflag = 1; column = 0; if (cutoffcolumn < 0) cutoffcolumn = 0; } else if (s[0] == '\n') { /* simple newline */ thisParser.line += 1; d[0] = '\n'; newlineflag = 1; column = 0; if (cutoffcolumn < 0) cutoffcolumn = 0; } else { if (newlineflag && isspace((int)(unsigned char)s[0])) { /* space after newline */ if (cutoffcolumn <= 0) { cutoffcolumn -= (s[0] == '\t') ? (8-((column-1) % 8)) : 1; } column += (s[0] == '\t') ? (8-((column-1) % 8)) : 1; if (cutoffcolumn <= 0 || column <= cutoffcolumn) { d--; } else { d[0] = s[0]; newlineflag = 0; } } else { /* everything else */ if (! isascii(s[0])) { smiPrintError(parser, ERR_ILLEGAL_CHAR_IN_STRING, s[0], (unsigned char) s[0]); } d[0] = s[0]; newlineflag = 0; if (cutoffcolumn < 0) { cutoffcolumn *= -1; } } } } d[0] = '\0'; yylval.text = yytext; return textSegment; } /* * Skip the remainder of the line */ .*{lineBreak} { thisParser.line++; BEGIN(INITIAL); } /* * Everything else... */ . { smiPrintError(parser, ERR_LEX_UNEXPECTED_CHAR); BEGIN(Skipline); } %% #endif