diff options
Diffstat (limited to 'src/build.l')
| -rw-r--r-- | src/build.l | 216 | 
1 files changed, 216 insertions, 0 deletions
| diff --git a/src/build.l b/src/build.l new file mode 100644 index 0000000..dc4ddda --- /dev/null +++ b/src/build.l | |||
| @@ -0,0 +1,216 @@ | |||
| 1 | %{ | ||
| 2 | #include "buildparser.h" | ||
| 3 | #include "bu/fstring.h" | ||
| 4 | |||
| 5 | char *fstrdup( const Bu::FString &s ) | ||
| 6 | { | ||
| 7 | char *sRet = new char[s.getSize()+1]; | ||
| 8 | memcpy( sRet, s.getStr(), s.getSize()+1 ); | ||
| 9 | return sRet; | ||
| 10 | } | ||
| 11 | |||
| 12 | char *rstrdup( const char *sIn ) | ||
| 13 | { | ||
| 14 | char *sRet = new char[strlen(sIn)+1]; | ||
| 15 | strcpy( sRet, sIn ); | ||
| 16 | return sRet; | ||
| 17 | } | ||
| 18 | void build_error( YYLTYPE *locp, yyscan_t yyscanner, BuildParser &bld, const char *msg ); | ||
| 19 | |||
| 20 | Bu::FString sBuf; | ||
| 21 | int iStrDepth = 0; | ||
| 22 | %} | ||
| 23 | |||
| 24 | %{ | ||
| 25 | #define YY_USER_ACTION yylloc->last_column += yyleng; | ||
| 26 | %} | ||
| 27 | |||
| 28 | %x strdq | ||
| 29 | %x BlockComment | ||
| 30 | %option noyywrap nounput batch debug bison-bridge bison-locations reentrant | ||
| 31 | %option prefix="build_" | ||
| 32 | %option outfile="src/build.yy.c" | ||
| 33 | %option header-file="src/build.yy.h" | ||
| 34 | %% | ||
| 35 | \n+ { | ||
| 36 | yylloc->last_line += yyleng; | ||
| 37 | yylloc->first_line = yylloc->last_line; | ||
| 38 | yylloc->first_column = yylloc->last_column = 0; | ||
| 39 | } | ||
| 40 | [ \t\r]+ { | ||
| 41 | yylloc->first_line = yylloc->last_line; | ||
| 42 | yylloc->first_column = yylloc->last_column+1; | ||
| 43 | } | ||
| 44 | "#".* /* eol comment */ | ||
| 45 | "//".* /* eol comment */ | ||
| 46 | |||
| 47 | "/*" { | ||
| 48 | BEGIN( BlockComment ); | ||
| 49 | } | ||
| 50 | |||
| 51 | <BlockComment>"*/" { | ||
| 52 | BEGIN( INITIAL ); | ||
| 53 | } | ||
| 54 | |||
| 55 | <BlockComment>\n+ { | ||
| 56 | yylloc->last_column = -yyleng; | ||
| 57 | yylloc->last_line += yyleng; | ||
| 58 | } | ||
| 59 | <BlockComment>. { } | ||
| 60 | /* | ||
| 61 | <BlockComment>[^*\n/]+ { } | ||
| 62 | <BlockComment>"*"[^/\n]+ { } | ||
| 63 | <BlockComment>"*"|"/" { } | ||
| 64 | */ | ||
| 65 | |||
| 66 | [(){}[\],.;=<>!+*/-] return yytext[0]; | ||
| 67 | "+=" return OP_ADDSETP; | ||
| 68 | "<<" return OP_ADDSETR; | ||
| 69 | "==" return OP_CMPEQUAL; | ||
| 70 | "!=" return OP_INEQUAL; | ||
| 71 | "<=" return OP_LTEQUAL; | ||
| 72 | ">=" return OP_GTEQUAL; | ||
| 73 | "target" return TOK_TARGET; | ||
| 74 | "input" return TOK_INPUT; | ||
| 75 | "output" return TOK_OUTPUT; | ||
| 76 | "unset" return TOK_UNSET; | ||
| 77 | "set" return TOK_SET; | ||
| 78 | "condition" return TOK_CONDITION; | ||
| 79 | "requires" return TOK_REQUIRES; | ||
| 80 | "auto" return TOK_AUTO; | ||
| 81 | "config" return TOK_CONFIG; | ||
| 82 | "display" return TOK_DISPLAY; | ||
| 83 | "type" return TOK_TYPE; | ||
| 84 | "int" return TOK_INT; | ||
| 85 | "float" return TOK_FLOAT; | ||
| 86 | "bool" return TOK_BOOL; | ||
| 87 | "version" return TOK_VERSION; | ||
| 88 | "string" return TOK_STRING; | ||
| 89 | "default" return TOK_DEFAULT; | ||
| 90 | "allow" return TOK_ALLOW; | ||
| 91 | "rule" return TOK_RULE; | ||
| 92 | "action" return TOK_ACTION; | ||
| 93 | "profile" return TOK_PROFILE; | ||
| 94 | "if" return TOK_IF; | ||
| 95 | "then" return TOK_THEN; | ||
| 96 | "else" return TOK_ELSE; | ||
| 97 | "include" return TOK_INCLUDE; | ||
| 98 | "warning" return TOK_WARNING; | ||
| 99 | "error" return TOK_ERROR; | ||
| 100 | "notice" return TOK_NOTICE; | ||
| 101 | "cache" return TOK_CACHE; | ||
| 102 | "always" return TOK_ALWAYS; | ||
| 103 | "never" return TOK_NEVER; | ||
| 104 | "global" return TOK_GLOBAL; | ||
| 105 | "local" return TOK_LOCAL; | ||
| 106 | "for" return TOK_FOR; | ||
| 107 | "in" return TOK_IN; | ||
| 108 | "do" return TOK_DO; | ||
| 109 | "return" return TOK_RETURN; | ||
| 110 | "function" return TOK_FUNCTION; | ||
| 111 | "continue" return TOK_CONTINUE; | ||
| 112 | "break" return TOK_BREAK; | ||
| 113 | "value" return TOK_VALUE; | ||
| 114 | "all" return TOK_ALL; | ||
| 115 | "export" return TOK_EXPORT; | ||
| 116 | "tag" return TOK_TAG; | ||
| 117 | "null" return TOK_NULL; | ||
| 118 | |||
| 119 | "true" { | ||
| 120 | yylval->bVal = true; | ||
| 121 | return BOOL; | ||
| 122 | } | ||
| 123 | "false" { | ||
| 124 | yylval->bVal = false; | ||
| 125 | return BOOL; | ||
| 126 | } | ||
| 127 | |||
| 128 | [a-zA-Z_][a-zA-Z0-9_]*: { | ||
| 129 | yytext[yyleng-1] = '\0'; | ||
| 130 | yylval->sVal = rstrdup( yytext ); | ||
| 131 | return PROFILE; | ||
| 132 | } | ||
| 133 | |||
| 134 | [a-zA-Z_][a-zA-Z0-9_]* { | ||
| 135 | yylval->sVal = rstrdup( yytext ); | ||
| 136 | if( b.isKeyword( yylval->sVal ) ) | ||
| 137 | return KEYWORD; | ||
| 138 | else if( b.isCond( yylval->sVal ) ) | ||
| 139 | return CONDITION; | ||
| 140 | return UNDEF; | ||
| 141 | } | ||
| 142 | |||
| 143 | -?([1-9][0-9]*)|(0) { | ||
| 144 | yylval->iVal = strtol( yytext, NULL, 10 ); | ||
| 145 | return INT; | ||
| 146 | } | ||
| 147 | |||
| 148 | (0\.0+)|(-?(([1-9][0-9]*)|(0))\.[0-9]*) { | ||
| 149 | yylval->fVal = strtof( yytext, NULL ); | ||
| 150 | return FLOAT; | ||
| 151 | } | ||
| 152 | |||
| 153 | \" { | ||
| 154 | BEGIN( strdq ); | ||
| 155 | sBuf.clear(); | ||
| 156 | iStrDepth = 0; | ||
| 157 | } | ||
| 158 | <strdq>[^\\\n\"$()]+ { | ||
| 159 | sBuf += yytext; | ||
| 160 | } | ||
| 161 | <strdq>\$\$ { | ||
| 162 | sBuf += "$$"; | ||
| 163 | } | ||
| 164 | <strdq>\$\( { | ||
| 165 | iStrDepth++; // TODO: Should this really count depth? I dunno... | ||
| 166 | sBuf += "$("; | ||
| 167 | } | ||
| 168 | <strdq>\\\) sBuf += "\\)"; | ||
| 169 | <strdq>\) { | ||
| 170 | if( iStrDepth > 0 ) | ||
| 171 | iStrDepth--; | ||
| 172 | sBuf += ")"; | ||
| 173 | } | ||
| 174 | <strdq>[$(] { | ||
| 175 | sBuf += yytext; | ||
| 176 | } | ||
| 177 | <strdq>\n { | ||
| 178 | build_error( yylloc, yyscanner, b, "newline encountered in string"); | ||
| 179 | } | ||
| 180 | <strdq>\\n sBuf += "\n"; | ||
| 181 | <strdq>\\t sBuf += "\t"; | ||
| 182 | <strdq>\\r sBuf += "\r"; | ||
| 183 | <strdq>\\b sBuf += "\b"; | ||
| 184 | <strdq>\\f sBuf += "\f"; | ||
| 185 | <strdq>\\\\ sBuf += "\\"; | ||
| 186 | <strdq>\\\" sBuf += "\""; | ||
| 187 | <strdq>\\\' sBuf += "\'"; | ||
| 188 | <strdq>\\\( sBuf += "("; | ||
| 189 | <strdq>\\\` sBuf += "`"; | ||
| 190 | <strdq>\\. printf("Invalid escape sequence.\n"); | ||
| 191 | <strdq>\"[ \t\r\n]*\" {/* Ignore spaces between strings. */} | ||
| 192 | <strdq>\" { | ||
| 193 | if( iStrDepth > 0 ) | ||
| 194 | { | ||
| 195 | sBuf += "\""; | ||
| 196 | } | ||
| 197 | else | ||
| 198 | { | ||
| 199 | BEGIN( INITIAL ); | ||
| 200 | yylval->sVal = fstrdup( sBuf ); | ||
| 201 | return STRING; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | <<EOF>> { | ||
| 206 | build_pop_buffer_state( yyscanner ); | ||
| 207 | if( !YY_CURRENT_BUFFER ) | ||
| 208 | yyterminate(); | ||
| 209 | else | ||
| 210 | b.endInclude( yylloc ); | ||
| 211 | } | ||
| 212 | |||
| 213 | . { | ||
| 214 | build_error( yylloc, yyscanner, b, "invalid character"); | ||
| 215 | } | ||
| 216 | %% | ||
