summaryrefslogtreecommitdiffstats
path: root/src/build/ifcompiler/initCompiler.lex
diff options
context:
space:
mode:
authorAndrew Geissler <andrewg@us.ibm.com>2011-09-26 10:27:13 -0500
committerAndrew J. Geissler <andrewg@us.ibm.com>2011-09-26 16:33:30 -0500
commitd034089348a197fa870bada40ac9f62523088d09 (patch)
treec8833301fde3c7d1cc553049abff60d71fb9a51e /src/build/ifcompiler/initCompiler.lex
parenta6425adc2dff068d6ce06e1e62e0aee6f2c46d3e (diff)
downloadtalos-hostboot-d034089348a197fa870bada40ac9f62523088d09.tar.gz
talos-hostboot-d034089348a197fa870bada40ac9f62523088d09.zip
Initial SCOM initfile compiler support.
Change-Id: Ia5be2c8443ee466127305f5771a19d763c3fb08d Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/362 Tested-by: Jenkins Server Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'src/build/ifcompiler/initCompiler.lex')
-rwxr-xr-xsrc/build/ifcompiler/initCompiler.lex361
1 files changed, 361 insertions, 0 deletions
diff --git a/src/build/ifcompiler/initCompiler.lex b/src/build/ifcompiler/initCompiler.lex
new file mode 100755
index 000000000..54e2b5646
--- /dev/null
+++ b/src/build/ifcompiler/initCompiler.lex
@@ -0,0 +1,361 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* fips740 src/engd/initfiles/ifcompiler/initCompiler.lex 1.2 */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* OBJECT CODE ONLY SOURCE MATERIALS */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2010 */
+/* All Rights Reserved */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/* Change Log *************************************************************************************
+//
+// Flag Track Userid Date Description
+// ---- -------- -------- -------- -------------------------------------------------------------
+// D754106 dgilbert 06/14/10 Create
+// dg01 D766229 dgilbert 08/03/10 add check for hex/bin data > 64 bits
+// dg02 SW058986 dgilbert 02/28/11 More noticeable fail for missing col headers
+// andrewg 09/19/11 Updates based on review
+// End Change Log *********************************************************************************/
+/**
+ * @file initCompiler.lex
+ * @brief Contains the rules for the lex/flex lexical scanner for scanning initfiles
+ *
+ * This code runs as part of the build process to generate a
+ * byte-coded representation of an initfile
+ */
+%{
+#include <stdint.h>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <initRpn.H>
+#include <y.tab.h>
+
+uint64_t bits2int( const char * bitString);
+uint64_t hexs2int(const char * hexString, int32_t size);
+void pushBackSpyBody();
+void push_col(const char *s);
+void lex_err(const char *s );
+
+std::ostringstream oss;
+std::ostringstream t_oss;
+
+typedef std::vector<std::ostringstream *> OSS_LIST;
+OSS_LIST g_colstream;
+
+inline void clear_colstream()
+{ for( OSS_LIST::iterator i = g_colstream.begin(); i != g_colstream.end(); ++i) delete *i;
+ g_colstream.clear();
+}
+uint32_t g_spycol;
+uint32_t g_coltype = 0;
+uint32_t g_spytype = 0;
+uint32_t g_paren_level = 0;
+bool g_equation = false; // equation inside spyv col
+std::string g_spyname; // dg02
+
+extern int yyline;
+
+%}
+
+
+
+
+NEWLINE \n
+FILENAME [A-Za-z][A-Za-z0-9_\.]*
+ID [A-Za-z][A-Za-z0-9_]*
+ID2 [A-Za-z][A-Za-z0-9_]*
+ID3 [0-9]+[A-Za-z_]+[0-9]*
+DIGIT [0-9]
+COMMENT #.*\n
+OP "="|"+"|"-"|"|"|"<"|">"|"*"|"/"|"%"
+FLOAT [0-9]+"."[0-9]*
+BINARY 0[bB][0-1]+
+SCOM_DATA [ ]*[scom_data][ ]+
+HEX 0[xX][A-Fa-f0-9]+
+SINGLE_HEX [A-Fa-f0-9]
+ATTRIBUTE [\[[A-Fa-f0-9]\]]
+
+%x scomop
+%x scomop_array
+%x scomop_suffix
+%x scomdata
+%x when_kw
+%x when_expr
+%x scomcolname
+%x scomrow
+%x list
+%x enumcol
+%x fnames
+%x hier
+%x target
+%x attribute
+%x array
+
+
+%%
+
+{COMMENT} ++yyline; /* toss comments - need first line */
+\$Id:.*\n ++yyline; /* toss this - read by initCompiler.C */
+
+ /* Special end-of-file character. */
+<<EOF>> { return 0; }
+
+SyntaxVersion return INIT_VERSION;
+
+ /* The list of initfile versions is just copied into the *.if file
+ * so just make it one chunk of string data */
+Versions BEGIN(fnames);
+<fnames>[=] oss.str("");
+<fnames>{FLOAT} oss << yytext;
+<fnames>[:] oss << yytext;
+<fnames>[,] oss << ", ";
+<fnames>{FILENAME} oss << yytext;
+<fnames>{NEWLINE} { ++yyline;
+ yylval.str_ptr = new std::string(oss.str());
+ BEGIN(INITIAL);
+ return INIT_VERSIONS;
+ }
+
+define { return INIT_DEFINE;}
+
+
+scom { BEGIN(scomop); oss.str(""); return INIT_SCOM; }
+
+<scomop>{HEX} {
+ yylval.str_ptr = new std::string(yytext);
+ oss.str("");
+ return INIT_SCOM_ADDR;
+ }
+
+<scomop>[\(] {BEGIN(scomop_array); return yytext[0];}
+
+<scomop_array>{SINGLE_HEX}+ {
+ yylval.str_ptr = new std::string(yytext);
+ oss.str("");
+ return INIT_INT64_STR;
+ }
+
+<scomop_array>[\)] {BEGIN(scomop_suffix); return(yytext[0]);}
+
+<scomop_suffix>{SINGLE_HEX}+ {
+ yylval.str_ptr = new std::string(yytext);
+ oss.str("");
+ BEGIN(scomop);
+ return INIT_SCOM_SUFFIX;
+ }
+
+
+<scomop>[:;\[] { BEGIN(INITIAL); g_coltype = 0; return yytext[0]; }
+<scomop>{NEWLINE} { BEGIN(INITIAL); ++yyline; }
+
+
+when { BEGIN(when_expr); return INIT_WHEN; }
+<when_expr>[\{] { oss.str("");
+ BEGIN(scomcolname);
+ return yytext[0];
+ }
+
+ /* The column & row format is really hard to handle in the parser,
+ especially since each column can have different parsing rules.
+ So fix it here in the scanner by converting the format to
+ coltitle1 , row1, row2, ..., row n ;
+ coltitle2 , row1, row2, ..., row n ;
+ then push it all back into the input stream and scan the new format
+ */
+
+<scomcolname>{COMMENT} ++yyline;
+<scomcolname>\n ++yyline;
+<scomcolname>{ID} {
+ g_colstream.push_back(new std::ostringstream());
+ *(g_colstream.back()) << yytext;
+ }
+<scomcolname>, {}
+<scomcolname>; { BEGIN(scomrow); g_spycol = 0; }
+
+<scomrow>{COMMENT} ++yyline;
+<scomrow>{NEWLINE} ++yyline;
+<scomrow>[^,;\n#\{\}]+ push_col(yytext);
+<scomrow>[,] ++g_spycol;
+<scomrow>[;] g_spycol = 0;
+<scomrow>[\}] {
+ pushBackSpyBody(); // create new format and put it back on yyin
+ BEGIN(INITIAL); // spybody);
+ }
+
+
+
+ /* The spybody is the modified format - don't track yyline as it's already
+ * accounted for. Any errors in here will point back to the last line in the
+ * 'real' spybody */
+
+arrayv { g_coltype = INIT_SPYV; return INIT_SPYV;}
+bits { g_coltype = INIT_BITS; return INIT_BITS;}
+expr { g_coltype = INIT_EXPR; return INIT_EXPR;}
+scom_data { g_coltype = INIT_SCOMD; return INIT_SCOMD;}
+
+ /*HEX and Binary nubers in the spybody can be up to 64bit,
+ * decimal numbers will always fit in 32bit int */
+
+{BINARY} { yylval.uint64 = bits2int(yytext); return INIT_INT64; }
+
+
+<*>; { g_coltype = 0; return ';'; }
+
+END_INITFILE return INIT_ENDINITFILE;
+
+<*>{ID} {
+ yylval.str_ptr = new std::string(yytext); return INIT_ID;
+ }
+
+<*>{DIGIT}+ {
+ sscanf(yytext, "%d", &yylval.integer); return INIT_INTEGER;
+ }
+
+<*>{HEX} {
+ // normal right-justified 64 bit hex integer
+ yylval.uint64 = hexs2int(yytext,yyleng);
+ return INIT_INT64;
+ }
+
+<*>"&&" return INIT_LOGIC_AND;
+<*>"||" return INIT_LOGIC_OR;
+<*>"==" return INIT_EQ;
+<*>"!=" return INIT_NE;
+<*>"<=" return INIT_LE;
+<*>">=" return INIT_GE;
+<*>">>" return INIT_SHIFT_RIGHT;
+<*>"<<" return INIT_SHIFT_LEFT;
+
+<*>{OP} { g_equation = true; return yytext[0]; }
+<*>[\(] { ++g_paren_level; return yytext[0]; }
+<*>[\)] { --g_paren_level; return yytext[0]; }
+
+<*>\[{SINGLE_HEX}\] { yylval.str_ptr = new std::string(yytext); return ATTRIBUTE_INDEX; }
+
+<*>[\[\]\{\},:] { g_equation = false; return yytext[0]; }
+
+<*>[ \t\r]+ /* Eat up whitespace */
+[\n] { BEGIN(INITIAL);++yyline;}
+
+<*>. lex_err(yytext);
+
+%%
+
+int yywrap() { return 1; }
+
+void lex_err(const char *s )
+{
+ std::cerr << "\nERROR: " << s << " -line " << yyline << std::endl;
+}
+
+// Convert left justified bitstring to 64 bit integer
+uint64_t bits2int( const char * bitString)
+{
+ uint32_t idx = 0;
+ uint64_t mask = 0x8000000000000000ull;
+ uint64_t val = 0;
+ do
+ {
+ if( (bitString[0] != '0') ||
+ ((bitString[1] != 'b') && (bitString[1] != 'B')))
+ {
+ lex_err("Invalid bit string");
+ break;
+ }
+ idx = 2;
+
+ while( bitString[idx] != 0 )
+ {
+ char c = bitString[idx];
+ if( c == '1') val |= mask;
+ else if(c != '0')
+ {
+ lex_err("Invalid bit string");
+ break;
+ }
+ ++idx;
+ mask >>= 1;
+ }
+ if(idx > 66) //dg01a 64bits + "0B" prefix
+ lex_err("Bit string greater than 64 bits!");
+
+ } while (0);
+ return val;
+}
+
+// Convert left justified hex string to 64 bit integer
+uint64_t hexs2int(const char * hexString, int32_t size)
+{
+ uint64_t val = 0;
+ std::string s(hexString);
+ if(size > 18) //dg01a
+ {
+ lex_err("HEX literal greater than 64 bits");
+ size = 18;
+ }
+ s.append(18-size,'0'); // 0x + 16 digits
+ val = strtoull(s.c_str(),NULL,16);
+ return val;
+}
+
+void pushBackSpyBody()
+{
+ std::ostringstream ost;
+ for(OSS_LIST::iterator i = g_colstream.begin(); i != g_colstream.end(); ++i)
+ {
+ ost << (*i)->str() << ';';
+ }
+ ost << '}';
+ std::string t = ost.str(); // Was causing weird stuff if I didn't copy the string out first
+ //std::cout << "<lex comment> Pushing:" << t << std::endl;
+ //std::cout << "<lex comment> " << std::endl;
+
+ for(std::string::reverse_iterator r = t.rbegin();
+ r != t.rend();
+ ++r)
+ {
+ //std::cout << *r;
+ unput(*r);
+ }
+ //std::cout << std::endl;
+ clear_colstream();
+}
+
+
+/// help collect column data
+void push_col(const char * s)
+{
+ //dg02a begin
+ while(g_spycol >= g_colstream.size()) // more data cols than headers cols
+ {
+ // This will force an error in the parser where it can stop the compile.
+ g_colstream.push_back(new std::ostringstream());
+ *(g_colstream.back()) << "MISSING_COLUMN_HEADER";
+ lex_err(g_spyname.c_str());
+ lex_err("Invalid number of spy cols");
+ }
+ //dgxxa end
+ //dgxxd remove if(g_colstream < g_colstream.size()
+
+ std::ostringstream & o = *(g_colstream[g_spycol]);
+ std::ostringstream token;
+ std::istringstream iss(s);
+ std::string t;
+ //std::cout << "Pushing ";
+ while(iss >> t) token << t; // get rid of white space
+ if(token.str().size()) // don't add blank tokens
+ {
+ //std::cout << "Pushing ," << token.str() << std::endl;
+ o << ',' << token.str();
+ }
+}
OpenPOWER on IntegriCloud