// // The developer of the original code and/or files is Tripwire, Inc. // Portions created by Tripwire, Inc. are copyright (C) 2000-2017 Tripwire, // Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights // reserved. // // This program is free software. The contents of this file are subject // to 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. You may redistribute it and/or modify it // only in compliance with the GNU General Public License. // // This program is distributed in the hope that it will be useful. // However, this program is distributed AS-IS WITHOUT ANY // WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS // FOR A PARTICULAR PURPOSE. Please 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-1307, // USA. // // Nothing in the GNU General Public License or any other license to use // the code or files shall permit you to use Tripwire's trademarks, // service marks, or other intellectual property without Tripwire's // prior written consent. // // If you have any questions, please contact Tripwire, Inc. at either // info@tripwire.org or www.tripwire.org. // /* /////////////////////////////////////////////////////////////////////////////// // tokens.l -- describes all the tokens for the policy language // */ /* increases number of states in DFA to 5000 */ %p 5000 %{ #include "stdtwparser.h" //#ifndef YYNEWLINE # include "twparser/yylex.h" # include "twparser/yyparse.h" //#endif #include #ifdef HAVE_MALLOC_H #include #endif #include #include "core/debug.h" #include "policyparser.h" #include "parserhelper.h" #include "genreparseinfo.h" #include "core/stringutil.h" #include "core/displayencoder.h" /* specify that the lexer exit on EOF */ int yywrap() { return 1; } /* wrapper around cDebug tracing */ void lextrace(const TCHAR*str) { cDebug d("\t\t\t\tlexer"); d.TraceDetail( _T("%s\n"), str); } // since i've replaced this with a non-va_arg yyerror, // call this when you hit a syntax error and then call // the non-va_arg yyerror with the result std::string FormatSyntaxError( char ch, const char* pszAdditionalMsg = NULL ) { // TODO:BAM MKS will call yyerror with narrow-char hard-coded string, so if // we do it here as well, I suppose that's OK. This should be eventually // corrected. std::ostringstream ssErr; ssErr << "Syntax error: \'" << ch << "\'"; if( pszAdditionalMsg ) ssErr << ", " << pszAdditionalMsg; return ssErr.str(); } // saves typing #define TRACE_RETURN(x) lextrace(_T(#x)); return x %} /* Defining a start-condition for parsing a global definitions section */ /* in a special manner: */ %x globals WS [ \t\r] COMMENT #.* BSLASH \\ DBL_QUOTE \" DIRECTIVE @@ EOL \n SEMICOLON ; DOLLAR \$ COMMA \, PIPE \| OROR \|\| EQUALS = LPAREN \( RPAREN \) /* normal strings -- anything but our reserved symbols */ STRING ([^!\{\}>\(\)\n\r\t \,;=$#|\"]+) /* quoted strings can contain escaped characters (including escaped quotes). Can also be empty string. */ QSTRING (\"(([^\\\"\n])|(\\.))*\") SECTION {WS}*{DIRECTIVE}{WS}*section IFHOST {WS}*{DIRECTIVE}{WS}*ifhost ELSE {WS}*{DIRECTIVE}{WS}*else ENDIF {WS}*{DIRECTIVE}{WS}*endif ERROR {WS}*{DIRECTIVE}{WS}*error ECHO {WS}*{DIRECTIVE}{WS}*print END {WS}*{DIRECTIVE}{WS}*end %% /* Lexer state-switching code for implementing a "global definitions" section while enforcing */ /* the limited scope of such a construct. The lexer will catch anything that cannot be */ /* coerced into a variable definition, and output special warnings. */ ^{SECTION}{WS}*((global)|(GLOBAL)) { BEGIN( globals ); } /* Are we done with the definitions section? */ ^{SECTION} { BEGIN(INITIAL); return TWP_SECTION; } ^{ECHO} { TRACE_RETURN(TWP_ECHO); } /* We still need to eat white space, line continuations, and comments... */ {WS}+ { lextrace(_T("eating spaces...")); /* eat spaces */ } {BSLASH}{EOL} { cParserHelper::IncrementLineNumber(); lextrace(_T("eating line continuation...")); /* eat line continuations */ } {COMMENT} { lextrace(_T("eating comment...")); } /* We still need to increment the line #, and pass the two tokens needed to */ /* do variable definitions: */ /* We still need to treat strings the same way, just return a differnt ID. TODO: */ /* Maybe create some helper functions and get rid of all this repeat code? */ {STRING} { // we must make copy of string, otherwise another lexeme will clobber it cDebug d("\t\t\t\tlexer::string"); // convert LPCSTR to TSTRING cParseString *mpstring = new cParseString; ASSERT(mpstring); *mpstring = cStringUtil::StrToTstr( yytext ); d.TraceDetail("--> <%s>\n", mpstring->c_str()); // attach to lval yylval.mpString = mpstring; return TWP_GLOBAL_STRING; } {QSTRING} { // we must make copy of string, otherwise another lexeme will clobber it cDebug d("\t\t\t\tlexer::qstring"); // get rid of beginning and trailing quotes std::string strWithQuotes = yytext; std::string str = strWithQuotes.substr(1, strWithQuotes.size() - 2); // convert any escape characters TSTRING strW; cParserUtil::InterpretEscapedString( str, strW ); d.TraceDetail(_T("read as --> <%s>\n"), strW.c_str()); // convert TSTRING to cParseString cParseString *mpstring = new cParseString; ASSERT(mpstring); *mpstring = strW; d.TraceDetail("interpreted as --> <%s>\n", mpstring->c_str()); // attach to lval yylval.mpString = mpstring; return TWP_GLOBAL_STRING; } {SEMICOLON} { TRACE_RETURN(TWP_SEMICOLON); } {EQUALS} { TRACE_RETURN(TWP_EQUALS); } \n { cParserHelper::IncrementLineNumber(); } . { std::string strError; strError = FormatSyntaxError( yytext[0], "The global section only accepts statements of the form:\n variable = value;\n" ); // MKS defines yyerror with char*, for some stupid reason, // so cast it away yyerror( const_cast( strError.c_str() ) ); } /* catches anything that cannot be deemed a variable definition and exits. */ /* consume spaces */ {WS}+ { lextrace(_T("eating spaces...")); /* eat spaces */ } {BSLASH}{EOL} { cParserHelper::IncrementLineNumber(); lextrace(_T("eating line continuation...")); /* eat line continuations */ } {COMMENT} { lextrace(_T("eating comment...")); } "{" { TRACE_RETURN(TWP_LBRACE); } "}" { TRACE_RETURN(TWP_RBRACE); } "!" { TRACE_RETURN(TWP_BANG); } "->" { TRACE_RETURN(TWP_RARROW); } {EQUALS} { TRACE_RETURN(TWP_EQUALS); } {SEMICOLON} { TRACE_RETURN(TWP_SEMICOLON); } {LPAREN} { TRACE_RETURN(TWP_LPAREN); } {RPAREN} { TRACE_RETURN(TWP_RPAREN); } {COMMA} { TRACE_RETURN(TWP_COMMA); } {PIPE} { TRACE_RETURN(TWP_PIPE); } /* variables */ {DOLLAR} { TRACE_RETURN(TWP_DOLLAR); } {OROR} { TRACE_RETURN(TWP_OROR); } ^{SECTION} { TRACE_RETURN(TWP_SECTION); } ^{IFHOST} { TRACE_RETURN(TWP_IFHOST); } ^{ELSE} { TRACE_RETURN(TWP_ELSE); } ^{ENDIF} { TRACE_RETURN(TWP_ENDIF); } ^{ERROR} { TRACE_RETURN(TWP_ERROR); } ^{ECHO} { TRACE_RETURN(TWP_ECHO); } ^{END} { lextrace( _T( "@@end" ) ); return 0; } /* logical end of file */ {STRING} { // we must make copy of string, otherwise another lexeme will clobber it cDebug d("\t\t\t\tlexer::string"); // convert LPCSTR to TSTRING cParseString *mpstring = new cParseString; ASSERT(mpstring); *mpstring = cStringUtil::StrToTstr( yytext ); d.TraceDetail("--> <%s>\n", mpstring->c_str()); // attach to lval yylval.mpString = mpstring; return TWP_STRING; } {QSTRING} { // we must make copy of string, otherwise another lexeme will clobber it cDebug d("\t\t\t\tlexer::qstring"); // get rid of beginning and trailing quotes std::string strWithQuotes = yytext; std::string str = strWithQuotes.substr(1, strWithQuotes.size() - 2); // convert any escape characters TSTRING strW; cParserUtil::InterpretEscapedString( str, strW ); d.TraceDetail(_T("read as --> <%s>\n"), strW.c_str()); if( cPreprocessor::GetState() == cPreprocessor::STATE_ACCEPT ) { cParserHelper::GetGenreInfo()->DoVarSubstitution( strW ); } // convert TSTRING to cParseString cParseString *mpstring = new cParseString; ASSERT(mpstring); *mpstring = strW; #ifdef DEBUG TSTRING strDisplay = *mpstring; cDisplayEncoder e; e.Encode( strDisplay ); d.TraceDetail("interpreted as --> <%s>\n", strDisplay.c_str()); #endif // DEBUG // attach to lval yylval.mpString = mpstring; return TWP_STRING; } /* not implemented yet ^{DIRECTIVE}{WS}*include{WS}\"[^\"]\" { // get include file name TCHAR szFilename[iFSServices::TW_MAX_PATH]; FILE* fpIncludeFile = _tfopen( szFilename, _T("r") ); if( fpIncludeFile ) { lex_include_file( fpIncludeFile ); fclose( fpIncludeFile ); } } */ \n { cParserHelper::IncrementLineNumber(); } . { std::string strError; strError = FormatSyntaxError( yytext[0] ); // MKS defines yyerror with char*, for some stupid reason, // so cast it away yyerror( const_cast( strError.c_str() ) ); } /* catches anything else that's not in here and quits */ %%