├── fips.cmd ├── .gitattributes ├── sdlang.sh ├── .gitignore ├── fips.yml ├── samples ├── parser.sdl └── parser.c ├── fips ├── meson.build ├── LICENSE ├── CMakeLists.txt ├── README.md ├── sdlang.rl ├── sdlang.c ├── sdlang.h └── sdlang.inl /fips.cmd: -------------------------------------------------------------------------------- 1 | @python fips %* 2 | 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf 2 | *.inl linguist-language=C 3 | -------------------------------------------------------------------------------- /sdlang.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ragel -L -G2 -o sdlang.inl sdlang.rl 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #>fips 2 | # this area is managed by fips, do not edit 3 | .fips-* 4 | *.pyc 5 | .vscode/ 6 | # Note: while implementing the grammar is almost done, I just started working on the library API - so it may change, and be extended and documented (, and become awesome) in the future. 12 | 13 | ### Source code 14 | 15 | It's simple. Add `sdlang.c`, `sdlang.inl` and `sdlang.h` to your project. 16 | 17 | The provided `CMakeLists.txt` is written to be used with [fips](http://floooh.github.io/fips/index.html), *the friendly CMake wrapper*. It won't work with regular CMake. 18 | 19 | There's a Meson build script too, by courtesy of [handicraftsman](https://github.com/handicraftsman). 20 | 21 | ### Token API 22 | 23 | Have a look at `samples/parser.c`. In summary, `sdlang_parse()` takes a stream function as a parameter, and produces a series of callbacks which can be captured with `sdlang_set_emit_token()` or `sdlang_set_emit_functions()`. 24 | 25 | You can capture error output `sdlang_set_report_error()`. 26 | 27 | ### Threading 28 | 29 | The parser is thread-safe. 30 | 31 | ## The nasty details 32 | 33 | ### Grammar 34 | 35 | The SDLang grammar isn't documented particularly well, which opens *some* room for interpretation. Also, this is the first time I've written a [Ragel](http://www.colm.net/open-source/ragel/) state machine, so there might be loopholes in my implementation. 36 | 37 | Additionally, I've made some minor adjustments to the SDLang grammar for convenience (or laziness, or my inability to do it right - feel free to chose one): 38 | 39 | - For delimiting single-quoted strings, `'` is supported in addition to backticks. For real, who enjoys typing backticks? 40 | - Integers and floats optionally start with a `+` sign. Also, neither the SDLang page nor the VS Code plugin for syntax highlighting care about the existence of negative numbers, so I took the liberty to allow prefixing numbers with the `-` sign, too. 41 | - Integer and float suffixes can be lower case, so both `1.23F` and `1.23f` are supported. 42 | - Floats can also be written in e-notation, for example `-2.34e-5f`. 43 | - 32/64-bit hexadecimal numbers, like `0x1234abcd` or `0xABCD1234FF`, are supported. 44 | 45 | Known bugs: 46 | 47 | - The end of a node is evaluated rather lazily. Closing brackets and semicolons generate an "end node" token. Non-wrapping newlines do too, but all of them, even for empty lines, which means that there can be multiple "end node" tokens in a row. 48 | - Semicolons to end a node are recognised but not enforced by the parser, which means these two lines are treated the same - basically, a new node name does end the previous node implicitly: 49 | - `title "some title"; author "John Smith"` 50 | - `title "some title" author "John Smith"` 51 | 52 | Some value formats are not implemented yet: 53 | 54 | - date/time formats 55 | 56 | ### Implementation 57 | 58 | `libsdlang` uses the [Ragel State Machine Compiler](http://www.colm.net/open-source/ragel/) to create its parser FSM. 59 | 60 | With less than 1.000 lines of code, the generated code is very compact, and has no external dependencies. 61 | 62 | The library doesn't allocate *any* memory. By default, it only uses a few hundred bytes of stack memory to store state and buffer input. You can predefine `SDLANG_PARSE_BUFFERSIZE` to increase the buffer size, which is probably only required when using large literals or string values. 63 | 64 | The parser uses a small stack frame for parsing nested SDLang blocks. Stack size can be changed by predefining `SDLANG_PARSE_STACKSIZE`. The stack frame **does not grow** - the parser will stop with a `SDLANG_PARSE_ERROR_STACK_OVERFLOW` when it's full. 65 | -------------------------------------------------------------------------------- /sdlang.rl: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * This file is generated by Ragel. Do not edit! 3 | * $ ragel -L -G2 -o sdlang.inl sdlang.rl 4 | ******************************************************************************/ 5 | 6 | %%{ 7 | 8 | machine sdlang; 9 | 10 | prepush { 11 | check_stack_size(&p, pe, top, curline); 12 | } 13 | 14 | # line breaks, with line counter 15 | 16 | newline = '\r'? '\n' @{curline += 1;}; 17 | newline_wrap = '\\' newline; 18 | any_count_line = any | newline; 19 | 20 | # quoted strings 21 | # + optionally use ' to delimit single-quoted strings 22 | 23 | single_quote_char = [^'`\\] | newline | ( '\\' . any_count_line ); 24 | single_quote_string = ['`]{1} . single_quote_char* . ['`]{1}; 25 | 26 | double_quote_char = [^"\\] | newline | ( '\\' any_count_line ); 27 | double_quote_string = '"' . double_quote_char* . '"'; 28 | 29 | any_string = single_quote_string | double_quote_string; 30 | 31 | # boolean and null values 32 | 33 | kw_true = 'true' | 'on'; 34 | kw_false = 'false' | 'off'; 35 | kw_null = 'null'; 36 | keywords = kw_true | kw_false | kw_null; 37 | 38 | # literals (node names) 39 | 40 | alnum_literal = alnum | [\.\:\-_$]; 41 | literal = '_'? . alpha . alnum_literal* - keywords; 42 | 43 | # comments 44 | 45 | one_line_comment = ('//' | '--' | '#') [^\n]* newline; 46 | c_comment := any_count_line* :>> '*/' @{fgoto block;}; 47 | 48 | # numeric values 49 | # + supports floating point e-notation 50 | # + explicitely captures trailing '+'/'-' 51 | # + 32/64 bit hexadecimal numbers 52 | 53 | float_fract = digit* '.' digit+ | digit+ '.'; 54 | float_exp = [eE] [+\-]? digit+; 55 | 56 | float64 = [+\-]? (float_fract float_exp? | digit+ float_exp); 57 | float32 = float64 [fF]; 58 | 59 | int32 = [+\-]? ('0' | [1-9] [0-9]*); 60 | int64 = int32 [lL]; 61 | int128 = int32 [bB] [dD]; 62 | 63 | hex32 = '0' [xX] [0-9a-fA-F]{1,8}; 64 | hex64 = '0' [xX] [0-9a-fA-F]{9,16}; 65 | 66 | # base64 67 | 68 | base64_char = alnum | [+/=]; 69 | base64_string = '[' . base64_char* . ']'; 70 | 71 | # attributes 72 | 73 | attribute = literal '='; 74 | 75 | block := |* 76 | 77 | attribute {emit(SDLANG_TOKEN_ATTRIBUTE, ts, te, curline, user);}; 78 | 79 | literal {emit(SDLANG_TOKEN_NODE, ts, te, curline, user);}; 80 | 81 | any_string {emit(SDLANG_TOKEN_STRING, ts, te, curline, user);}; 82 | 83 | float32 {emit(SDLANG_TOKEN_FLOAT32, ts, te, curline, user);}; 84 | float64 {emit(SDLANG_TOKEN_FLOAT64, ts, te, curline, user);}; 85 | 86 | int64 {emit(SDLANG_TOKEN_INT64, ts, te, curline, user);}; 87 | int128 {emit(SDLANG_TOKEN_INT128, ts, te, curline, user);}; 88 | int32 {emit(SDLANG_TOKEN_INT32, ts, te, curline, user);}; 89 | 90 | hex64 {emit(SDLANG_TOKEN_UINT64, ts, te, curline, user);}; 91 | hex32 {emit(SDLANG_TOKEN_UINT32, ts, te, curline, user);}; 92 | 93 | kw_true {emit(SDLANG_TOKEN_TRUE, ts, te, curline, user);}; 94 | kw_false {emit(SDLANG_TOKEN_FALSE, ts, te, curline, user);}; 95 | 96 | kw_null {emit(SDLANG_TOKEN_NULL, ts, te, curline, user);}; 97 | 98 | base64_string {emit(SDLANG_TOKEN_BASE64, ts, te, curline, user);}; 99 | # data/time formats 100 | # skip empty lines 101 | # lazy token_end 102 | 103 | ';' {emit(SDLANG_TOKEN_NODE_END, ts, te, curline, user);}; 104 | 105 | '{' { 106 | emit(SDLANG_TOKEN_BLOCK, ts, te, curline, user); 107 | fcall block; 108 | }; 109 | 110 | '}' { 111 | emit(SDLANG_TOKEN_BLOCK_END, ts, te, curline, user); 112 | fret; 113 | }; 114 | 115 | one_line_comment {emit(SDLANG_TOKEN_NODE_END, NULL, NULL, curline, user);}; 116 | '/*' {fgoto c_comment;}; 117 | 118 | newline_wrap; # wrapping lines do not end node 119 | newline {emit(SDLANG_TOKEN_NODE_END, NULL, NULL, curline, user);}; 120 | 121 | [ \t]; 122 | 123 | *|; 124 | 125 | main := |* 126 | # Just enter the top-level block. 127 | any {fhold; fcall block;}; 128 | *|; 129 | 130 | }%% 131 | 132 | %% write data nofinal; 133 | 134 | int sdlang_parse(size_t (*stream)(void* ptr, size_t size, void* user), void* user) 135 | { 136 | char buf[SDLANG_PARSE_BUFFERSIZE]; 137 | int cs, act, have = 0, curline = 1; 138 | int stack[SDLANG_PARSE_STACKSIZE], top = 0; 139 | char *ts, *te = 0; 140 | int done = 0, err = SDLANG_PARSE_OK; 141 | 142 | %% write init; 143 | 144 | while (!done) 145 | { 146 | char *p = buf + have, *pe, *eof = 0; 147 | int len, space = SDLANG_PARSE_BUFFERSIZE - have; 148 | 149 | if (space == 0) 150 | { 151 | err = SDLANG_PARSE_ERROR_BUFFER_TOO_SMALL; 152 | break; 153 | } 154 | 155 | len = (int)stream(p, space, user); 156 | pe = p + len; 157 | 158 | if (len < space) 159 | { 160 | eof = pe; 161 | done = 1; 162 | } 163 | 164 | %% write exec; 165 | 166 | if (cs == sdlang_error) 167 | { 168 | err = SDLANG_PARSE_ERROR; 169 | break; 170 | } 171 | 172 | if (top == SDLANG_PARSE_STACKSIZE) 173 | { 174 | err = SDLANG_PARSE_ERROR_STACK_OVERFLOW; 175 | break; 176 | } 177 | 178 | if (ts == 0) 179 | { 180 | have = 0; 181 | } 182 | else 183 | { 184 | have = (int)(pe - ts); 185 | SDLANG_MEMMOVE(buf, ts, have); 186 | te = buf + (te - ts); 187 | ts = buf; 188 | } 189 | } 190 | 191 | if (err != SDLANG_PARSE_OK) 192 | { 193 | (*sdlang_user_report_error)(err, curline); 194 | } 195 | 196 | return err; 197 | } 198 | -------------------------------------------------------------------------------- /sdlang.c: -------------------------------------------------------------------------------- 1 | #include "sdlang.h" 2 | 3 | #include 4 | 5 | static struct sdlang_functions_t* sdlang_user_emit_functions = NULL; 6 | 7 | void sdlang_set_emit_functions(struct sdlang_functions_t* emit_functions) 8 | { 9 | if (emit_functions != NULL) 10 | { 11 | emit_functions->node_name[0] = '\0'; 12 | emit_functions->attr_name[0] = '\0'; 13 | } 14 | 15 | sdlang_user_emit_functions = emit_functions; 16 | } 17 | 18 | void sdlang_emit_token(const struct sdlang_token_t* token, void* user) 19 | { 20 | struct sdlang_functions_t* vtbl = sdlang_user_emit_functions; 21 | 22 | if (vtbl == NULL) 23 | { 24 | return; 25 | } 26 | 27 | const char* value = token->string.from; 28 | const int len = (const int)(token->string.to - value); 29 | 30 | #define size_minus_one(dst) \ 31 | ((int)sizeof(vtbl->dst) - 1) 32 | 33 | #define safe_copy_value(dst) \ 34 | strncpy(vtbl->dst, value, len < size_minus_one(dst) ? len : size_minus_one(dst)); \ 35 | vtbl->dst[len < size_minus_one(dst) ? len : size_minus_one(dst)] = '\0' 36 | 37 | #define safe_call(fn, params) \ 38 | if (vtbl->fn != NULL) vtbl->fn params 39 | 40 | #define safe_emit_value(fn, ...) \ 41 | if (vtbl->value_##fn != NULL) vtbl->value_##fn(vtbl->node_name, vtbl->attr_name, __VA_ARGS__); \ 42 | vtbl->attr_name[0] = '\0'; 43 | 44 | switch (token->type) 45 | { 46 | case SDLANG_TOKEN_NODE: 47 | { 48 | safe_copy_value(node_name); 49 | } 50 | break; 51 | 52 | case SDLANG_TOKEN_NODE_END: 53 | { 54 | vtbl->node_name[0] = '\0'; 55 | } 56 | break; 57 | 58 | case SDLANG_TOKEN_BLOCK: 59 | { 60 | safe_call(block_begin, (vtbl->node_name, user)); 61 | } 62 | break; 63 | 64 | case SDLANG_TOKEN_BLOCK_END: 65 | { 66 | safe_call(block_end, (user)); 67 | } 68 | break; 69 | 70 | case SDLANG_TOKEN_ATTRIBUTE: 71 | { 72 | /* store attribute name */ 73 | safe_copy_value(attr_name); 74 | } 75 | break; 76 | 77 | case SDLANG_TOKEN_INT32: 78 | { 79 | const long l = strtol(value, NULL, 10); 80 | safe_emit_value(i32, l, user); 81 | } 82 | break; 83 | 84 | case SDLANG_TOKEN_INT64: 85 | { 86 | const long long ll = strtoll(value, NULL, 10); 87 | safe_emit_value(i64, ll, user); 88 | } 89 | break; 90 | 91 | case SDLANG_TOKEN_INT128: 92 | { 93 | int64_t hi = 0; 94 | uint64_t lo = 0; 95 | 96 | const char *s = value, *e = &value[len]; 97 | int64_t sign = 1; 98 | 99 | if (*s == '-') 100 | { 101 | sign = -sign; 102 | ++s; 103 | } 104 | 105 | while (s != e) 106 | { 107 | const uint64_t digit = *s - '0'; 108 | 109 | if (lo * 10 + digit < lo) 110 | { 111 | hi = (hi << 4) | (lo >> 48); 112 | lo >>= 4; 113 | } 114 | 115 | lo = lo * 10 + digit; 116 | 117 | ++s; 118 | } 119 | 120 | hi = sign * hi; 121 | 122 | safe_emit_value(i128, hi, lo, user); 123 | } 124 | break; 125 | 126 | case SDLANG_TOKEN_FLOAT32: 127 | { 128 | const float f = strtof(value, NULL); 129 | safe_emit_value(f32, f, user); 130 | } 131 | break; 132 | 133 | case SDLANG_TOKEN_FLOAT64: 134 | { 135 | const double d = strtod(value, NULL); 136 | safe_emit_value(f64, d, user); 137 | } 138 | break; 139 | 140 | case SDLANG_TOKEN_STRING: 141 | { 142 | safe_emit_value(string, value, len, user); 143 | } 144 | break; 145 | 146 | case SDLANG_TOKEN_BASE64: 147 | { 148 | safe_emit_value(base64, value, len, user); 149 | } 150 | break; 151 | 152 | case SDLANG_TOKEN_UINT32: 153 | { 154 | const unsigned long ul = strtoul(value, NULL, 16); 155 | safe_emit_value(u32, ul, user); 156 | } 157 | break; 158 | 159 | case SDLANG_TOKEN_UINT64: 160 | { 161 | const unsigned long long ull = strtoull(value, NULL, 16); 162 | safe_emit_value(u64, ull, user); 163 | } 164 | break; 165 | 166 | case SDLANG_TOKEN_TRUE: 167 | { 168 | safe_emit_value(bool, true, user); 169 | } 170 | break; 171 | 172 | case SDLANG_TOKEN_FALSE: 173 | { 174 | safe_emit_value(bool, false, user); 175 | } 176 | break; 177 | 178 | case SDLANG_TOKEN_NULL: 179 | { 180 | safe_emit_value(null, user); 181 | } 182 | break; 183 | 184 | default: 185 | break; 186 | } 187 | } 188 | 189 | static void (*sdlang_user_emit_token)(const struct sdlang_token_t*, void*) = sdlang_emit_token; 190 | 191 | void sdlang_set_emit_token(void (*emit_token)(const struct sdlang_token_t* token, void* user)) 192 | { 193 | sdlang_user_emit_token = emit_token != NULL ? emit_token : sdlang_emit_token; 194 | } 195 | 196 | static void emit(enum sdlang_token_type_t type, const char* ts, 197 | const char* te, int line, void* user) 198 | { 199 | switch (type) 200 | { 201 | case SDLANG_TOKEN_ATTRIBUTE: 202 | /* strip trailing '=' */ 203 | --te; 204 | break; 205 | 206 | case SDLANG_TOKEN_INT32: 207 | case SDLANG_TOKEN_INT64: 208 | case SDLANG_TOKEN_FLOAT32: 209 | case SDLANG_TOKEN_FLOAT64: 210 | /* strip leading '+' */ 211 | if (*ts == '+') 212 | { 213 | ++ts; 214 | } 215 | break; 216 | 217 | case SDLANG_TOKEN_INT128: 218 | /* strip leading '+' and suffix */ 219 | if (*ts == '+') 220 | { 221 | ++ts; 222 | } 223 | te -= 2; 224 | break; 225 | 226 | case SDLANG_TOKEN_STRING: 227 | case SDLANG_TOKEN_BASE64: 228 | /* strip delimiters */ 229 | ++ts; 230 | --te; 231 | break; 232 | 233 | default: 234 | break; 235 | } 236 | 237 | const struct sdlang_token_t token = { 238 | .type = type, 239 | .string = { 240 | .from = ts, 241 | .to = te 242 | }, 243 | .line = line 244 | }; 245 | 246 | (*sdlang_user_emit_token)(&token, user); 247 | } 248 | 249 | static void sdlang_report_error(enum sdlang_error_t error, int line) 250 | { 251 | (void)error; 252 | (void)line; 253 | } 254 | 255 | static void (*sdlang_user_report_error)(enum sdlang_error_t error, int line) = sdlang_report_error; 256 | 257 | void sdlang_set_report_error(void (*report_error)(enum sdlang_error_t error, int line)) 258 | { 259 | sdlang_user_report_error = report_error != NULL ? report_error : sdlang_report_error; 260 | } 261 | 262 | static void check_stack_size(char** p, char* pe, int top, int line) 263 | { 264 | if (top == SDLANG_PARSE_STACKSIZE - 1) 265 | { 266 | /* 267 | trick the FSM into completing the current iteration, 268 | then the main loop checks for the stack pointer 269 | */ 270 | *p = pe - 1; 271 | } 272 | } 273 | 274 | #include "sdlang.inl" 275 | -------------------------------------------------------------------------------- /samples/parser.c: -------------------------------------------------------------------------------- 1 | #include "sdlang.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static bool is_node = false; 8 | static bool is_attribute = false; 9 | static int depth = 0; 10 | 11 | static size_t read(void* ptr, size_t size, void* user) 12 | { 13 | FILE* file = user; 14 | return fread(ptr, 1, size, file); 15 | } 16 | 17 | static void emit_token(const struct sdlang_token_t* token, void* user) 18 | { 19 | if (token->type == SDLANG_TOKEN_NODE_END) 20 | { 21 | is_node = false; 22 | is_attribute = false; 23 | return; 24 | } 25 | 26 | if (token->type == SDLANG_TOKEN_BLOCK) 27 | { 28 | ++depth; 29 | return; 30 | } 31 | else if (token->type == SDLANG_TOKEN_BLOCK_END) 32 | { 33 | --depth; 34 | return; 35 | } 36 | 37 | for (int d = 0; d < depth; d++) 38 | { 39 | fprintf(stdout, " "); 40 | } 41 | 42 | const char* text = token->string.from; 43 | const int len = (const int)(token->string.to - token->string.from); 44 | 45 | switch (token->type) 46 | { 47 | case SDLANG_TOKEN_NODE: 48 | fprintf(stdout, "%.*s", len, text); 49 | is_node = true; 50 | break; 51 | case SDLANG_TOKEN_BLOCK: 52 | ++depth; 53 | break; 54 | case SDLANG_TOKEN_BLOCK_END: 55 | --depth; 56 | break; 57 | case SDLANG_TOKEN_ATTRIBUTE: 58 | fprintf(stdout, "- attr: %.*s", len, text); 59 | is_attribute = true; 60 | break; 61 | case SDLANG_TOKEN_INT32: 62 | fprintf(stdout, "- value(i32): %.*s", len, text); 63 | is_attribute = false; 64 | break; 65 | case SDLANG_TOKEN_INT64: 66 | fprintf(stdout, "- value(i64): %.*s", len, text); 67 | is_attribute = false; 68 | break; 69 | case SDLANG_TOKEN_INT128: 70 | fprintf(stdout, "- value(i128): %.*s", len, text); 71 | is_attribute = false; 72 | break; 73 | case SDLANG_TOKEN_FLOAT32: 74 | fprintf(stdout, "- value(f32): %.*s", len, text); 75 | is_attribute = false; 76 | break; 77 | case SDLANG_TOKEN_FLOAT64: 78 | fprintf(stdout, "- value(f64): %.*s", len, text); 79 | is_attribute = false; 80 | break; 81 | case SDLANG_TOKEN_STRING: 82 | fprintf(stdout, "- value(str): %.*s", len, text); 83 | is_attribute = false; 84 | break; 85 | case SDLANG_TOKEN_BASE64: 86 | fprintf(stdout, "- value(base64): %.*s", len, text); 87 | is_attribute = false; 88 | break; 89 | case SDLANG_TOKEN_UINT32: 90 | fprintf(stdout, "- value(hex32): %.*s", len, text); 91 | is_attribute = false; 92 | break; 93 | case SDLANG_TOKEN_UINT64: 94 | fprintf(stdout, "- value(hex64): %.*s", len, text); 95 | is_attribute = false; 96 | break; 97 | case SDLANG_TOKEN_TRUE: 98 | fprintf(stdout, "- value: true"); 99 | is_attribute = false; 100 | break; 101 | case SDLANG_TOKEN_FALSE: 102 | fprintf(stdout, "- value: false"); 103 | is_attribute = false; 104 | break; 105 | case SDLANG_TOKEN_NULL: 106 | fprintf(stdout, "- value: null"); 107 | is_attribute = false; 108 | break; 109 | 110 | case SDLANG_TOKEN_NODE_END: 111 | default: 112 | break; 113 | } 114 | 115 | fprintf(stdout, "\n"); 116 | } 117 | 118 | static void begin_block(const char* node, void* user) 119 | { 120 | fprintf(stdout, "node '%s', {\n", node); 121 | } 122 | 123 | static void end_block(void* user) 124 | { 125 | fprintf(stdout, "}\n"); 126 | } 127 | 128 | static void emit_value_i32(const char* node, const char* attr, int32_t value, void* user) 129 | { 130 | fprintf(stdout, "node '%s', attr '%s', i32=%d\n", node, attr, value); 131 | } 132 | 133 | static void emit_value_i64(const char* node, const char* attr, int64_t value, void* user) 134 | { 135 | fprintf(stdout, "node '%s', attr '%s', i64=%"PRId64"\n", node, attr, value); 136 | } 137 | 138 | static void emit_value_i128(const char* node, const char* attr, int64_t hi, uint64_t lo, void* user) 139 | { 140 | fprintf(stdout, "node '%s', attr '%s', i128=[hi %"PRId64", lo=%"PRIu64"]\n", node, attr, hi, lo); 141 | } 142 | 143 | static void emit_value_f32(const char* node, const char* attr, float value, void* user) 144 | { 145 | fprintf(stdout, "node '%s', attr '%s', i32=%f\n", node, attr, value); 146 | } 147 | 148 | static void emit_value_f64(const char* node, const char* attr, double value, void* user) 149 | { 150 | fprintf(stdout, "node '%s', attr '%s', f64=%f\n", node, attr, value); 151 | } 152 | 153 | static void emit_value_string(const char* node, const char* attr, const char* value, int len, void* user) 154 | { 155 | fprintf(stdout, "node '%s', attr '%s', string '%.*s'\n", node, attr, len, value); 156 | } 157 | 158 | static void emit_value_base64(const char* node, const char* attr, const char* value, int len, void* user) 159 | { 160 | fprintf(stdout, "node '%s', attr '%s', base64 [%.*s]\n", node, attr, len, value); 161 | } 162 | 163 | static void emit_value_u32(const char* node, const char* attr, uint32_t value, void* user) 164 | { 165 | fprintf(stdout, "node '%s', attr '%s', u32=%u\n", node, attr, value); 166 | } 167 | 168 | static void emit_value_u64(const char* node, const char* attr, uint64_t value, void* user) 169 | { 170 | fprintf(stdout, "node '%s', attr '%s', u64=%"PRIu64"\n", node, attr, value); 171 | } 172 | 173 | static void emit_value_bool(const char* node, const char* attr, bool value, void* user) 174 | { 175 | fprintf(stdout, "node '%s', attr '%s', bool=%s\n", node, attr, value ? "true" : "false"); 176 | } 177 | 178 | static void emit_value_null(const char* node, const char* attr, void* user) 179 | { 180 | fprintf(stdout, "node '%s', attr '%s', null\n", node, attr); 181 | } 182 | 183 | static void report_error(enum sdlang_error_t error, int line) 184 | { 185 | switch (error) 186 | { 187 | case SDLANG_PARSE_ERROR: 188 | fprintf(stderr, "parse error at line %d\n", line); 189 | break; 190 | case SDLANG_PARSE_ERROR_STACK_OVERFLOW: 191 | fprintf(stderr, "parse stack overflow at line %d\n", line); 192 | break; 193 | case SDLANG_PARSE_ERROR_BUFFER_TOO_SMALL: 194 | fprintf(stderr, "out of buffer memory at line %d\n", line); 195 | break; 196 | default: 197 | fprintf(stderr, "unknown error [%d] at line %d\n", error, line); 198 | break; 199 | } 200 | } 201 | 202 | int main(int argc, char* argv[]) 203 | { 204 | FILE* file = stdout; 205 | int mode = 0; 206 | 207 | if (argc > 1) 208 | { 209 | if (argc > 2) 210 | { 211 | if (strcmp(argv[1], "-t") == 0) 212 | { 213 | mode = 1; 214 | } 215 | } 216 | 217 | file = fopen(argv[argc - 1], "rb"); 218 | 219 | if (file == NULL) 220 | { 221 | fprintf(stderr, "failed to open: %s\n", argv[argc - 1]); 222 | return 1; 223 | } 224 | } 225 | 226 | if (mode == 0) 227 | { 228 | sdlang_set_emit_functions(&(struct sdlang_functions_t) { 229 | .block_begin = begin_block, 230 | .block_end = end_block, 231 | .value_i32 = emit_value_i32, 232 | .value_i64 = emit_value_i64, 233 | .value_i128 = emit_value_i128, 234 | .value_f32 = emit_value_f32, 235 | .value_f64 = emit_value_f64, 236 | .value_string = emit_value_string, 237 | .value_base64 = emit_value_base64, 238 | .value_u32 = emit_value_u32, 239 | .value_u64 = emit_value_u64, 240 | .value_bool = emit_value_bool, 241 | .value_null = emit_value_null 242 | }); 243 | } 244 | else 245 | { 246 | sdlang_set_emit_token(emit_token); 247 | } 248 | 249 | sdlang_set_report_error(report_error); 250 | 251 | const int result = sdlang_parse(read, file); 252 | 253 | if (file != NULL) 254 | { 255 | fclose(file); 256 | } 257 | 258 | return result; 259 | } 260 | -------------------------------------------------------------------------------- /sdlang.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifndef SDLANG_PARSE_BUFFERSIZE 7 | # define SDLANG_PARSE_BUFFERSIZE 1024 8 | #endif 9 | 10 | #ifndef SDLANG_PARSE_STACKSIZE 11 | # define SDLANG_PARSE_STACKSIZE 32 12 | #endif 13 | 14 | #ifndef SDLANG_MEMMOVE 15 | # include 16 | # define SDLANG_MEMMOVE(d, s, n) memmove(d, s, n) 17 | #endif 18 | 19 | #define SDLANG_NODE_MAXNAMELEN 48 20 | #define SDLANG_ATTR_MAXNAMELEN 48 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /*# 27 | ## types 28 | #*/ 29 | 30 | /*# 31 | ### sdlang_token_type_t 32 | #*/ 33 | enum sdlang_token_type_t 34 | { 35 | SDLANG_TOKEN_NODE, 36 | SDLANG_TOKEN_NODE_END, 37 | SDLANG_TOKEN_BLOCK, 38 | SDLANG_TOKEN_BLOCK_END, 39 | SDLANG_TOKEN_ATTRIBUTE, 40 | 41 | SDLANG_TOKEN_INT32, 42 | SDLANG_TOKEN_INT64, 43 | SDLANG_TOKEN_INT128, 44 | SDLANG_TOKEN_FLOAT32, 45 | SDLANG_TOKEN_FLOAT64, 46 | SDLANG_TOKEN_STRING, 47 | SDLANG_TOKEN_BASE64, 48 | SDLANG_TOKEN_UINT32, 49 | SDLANG_TOKEN_UINT64, 50 | 51 | SDLANG_TOKEN_TRUE, 52 | SDLANG_TOKEN_FALSE, 53 | SDLANG_TOKEN_NULL 54 | }; 55 | 56 | /*# 57 | ### sdlang_error_t 58 | #*/ 59 | enum sdlang_error_t 60 | { 61 | SDLANG_PARSE_OK = 0, 62 | SDLANG_PARSE_ERROR, 63 | SDLANG_PARSE_ERROR_STACK_OVERFLOW, 64 | SDLANG_PARSE_ERROR_BUFFER_TOO_SMALL 65 | }; 66 | 67 | /*# 68 | ### sdlang_token_t 69 | 70 | Token description as identified by the parser. 71 | 72 | The `string` variable points at the first and after the last `char` of 73 | the character sequence in relation to the token type. For a node or 74 | attribute, it's the node/attribute name. For value types, it's the actual 75 | value. 76 | 77 | For some token types, like `SDLANG_TOKEN_NODE_END`, `string` pointers may 78 | be set to `NULL`. 79 | 80 | !!! WARNING 81 | `string.from` and `string.to` point to buffer content which may not be 82 | valid anymore after subsequent parsing operations. You'll need to copy 83 | the string content if you want to access it later. 84 | #*/ 85 | struct sdlang_token_t 86 | { 87 | enum sdlang_token_type_t type; 88 | 89 | struct 90 | { 91 | const char* from; 92 | const char* to; 93 | } string; 94 | 95 | int line; 96 | }; 97 | 98 | /*# 99 | ### sdlang_functions_t 100 | 101 | User function table. 102 | 103 | Node and attribute names are null-terminated. Any other string values are 104 | not - the caller needs to ensure to not read past `len` characters. 105 | 106 | Any node names, attribute names and character buffers addressed by `ptr` 107 | are only valid during callbacks, and can/will be overwritten by the parser 108 | afterwards. 109 | 110 | If a function pointer is set to `NULL`, any corresponding callback will be 111 | discarded. 112 | 113 | !!! WARNING 114 | `node_name` and `attr_name` are used internally as a temporary storage 115 | for node and attribute names. Consider their content read-only during, 116 | and undefined after execution of the parser. 117 | #*/ 118 | struct sdlang_functions_t 119 | { 120 | void (*block_begin)(const char* node, void* user); 121 | void (*block_end)(void* user); 122 | void (*value_i32)(const char* node, const char* attr, int32_t value, void* user); 123 | void (*value_i64)(const char* node, const char* attr, int64_t value, void* user); 124 | void (*value_i128)(const char* node, const char* attr, int64_t hi, uint64_t lo, void* user); 125 | void (*value_f32)(const char* node, const char* attr, float value, void* user); 126 | void (*value_f64)(const char* node, const char* attr, double value, void* user); 127 | void (*value_string)(const char* node, const char* attr, const char* ptr, int len, void* user); 128 | void (*value_base64)(const char* node, const char* attr, const char* ptr, int len, void* user); 129 | void (*value_u32)(const char* node, const char* attr, uint32_t value, void* user); 130 | void (*value_u64)(const char* node, const char* attr, uint64_t value, void* user); 131 | void (*value_bool)(const char* node, const char* attr, bool value, void* user); 132 | void (*value_null)(const char* node, const char* attr, void* user); 133 | 134 | /* local node/attribute name buffers */ 135 | char node_name[SDLANG_NODE_MAXNAMELEN]; 136 | char attr_name[SDLANG_ATTR_MAXNAMELEN]; 137 | }; 138 | 139 | /*# 140 | ## functions 141 | #*/ 142 | 143 | /*# 144 | ### sdlang_emit_token 145 | 146 | ~~~ C 147 | void sdlang_emit_token(const struct sdlang_token_t* token, void* user); 148 | ~~~ 149 | 150 | Injects a token into the emitter stream. 151 | 152 | Under normal conditions, calling this function isn't required. The main 153 | reason to have it exposed is to allow pass-through calls for custom 154 | callbacks: 155 | 156 | ~~~ C 157 | void emit_token(const struct sdlang_token_t* token, void* user) 158 | { 159 | if (context_wants_capture_token(user)) 160 | { 161 | // process token 162 | } 163 | 164 | sdlang_emit_token(token, user); 165 | } 166 | 167 | // ... 168 | 169 | sdlang_set_emit_token(emit_token, user); 170 | ~~~ 171 | #*/ 172 | extern void sdlang_emit_token(const struct sdlang_token_t* token, void* user); 173 | 174 | /*# 175 | ### sdlang_set_emit_token 176 | 177 | ~~~ C 178 | void sdlang_set_emit_token(void (*emit_token)(const struct sdlang_token_t* token, void* user)); 179 | ~~~ 180 | 181 | Captures the token function. Pass NULL to set the default function. 182 | 183 | This is the callback used by the parser at the lowest level. By capturing 184 | this function, any APIs at a higher level are effectively cut off. You can 185 | forward the call to `sdlang_emit_token()` to prevent this. 186 | #*/ 187 | extern void sdlang_set_emit_token(void (*emit_token)(const struct sdlang_token_t* token, void* user)); 188 | 189 | /*# 190 | ### sdlang_set_emit_functions 191 | 192 | ~~~ C 193 | void sdlang_set_emit_functions(struct sdlang_functions_t* emit_functions); 194 | ~~~ 195 | 196 | Populates the user-callback function table. Pass NULL to clear and not 197 | generate any more callbacks. 198 | 199 | This is the higher level user interface. The parser translates low level 200 | tokens to calls into this function table. 201 | 202 | Most functions take a `node` and `attribute` parameter. For anonymous 203 | nodes, the `node` parameter is empty. For node values, the `attributes` 204 | parameter is empty. 205 | 206 | There are no explicit callbacks to begin or end a node. These events can 207 | be implied by a change to the `node` parameter from one callback to the 208 | next. 209 | #*/ 210 | extern void sdlang_set_emit_functions(struct sdlang_functions_t* emit_functions); 211 | 212 | /*# 213 | ### sdlang_set_report_error 214 | 215 | ~~~ C 216 | void sdlang_set_report_error(void (*report_error)(enum sdlang_error_t error, int line)); 217 | ~~~ 218 | 219 | Sets the error report function. Pass NULL to set the default function, 220 | which is an empty implementation. 221 | 222 | See __samples/parser.c__ for an example. 223 | #*/ 224 | extern void sdlang_set_report_error(void (*report_error)(enum sdlang_error_t error, int line)); 225 | 226 | /*# 227 | ### sdlang_parse 228 | 229 | ~~~ C 230 | int sdlang_parse(size_t (*stream)(void* ptr, size_t size, void* user), void* user); 231 | ~~~ 232 | 233 | Parses a SDLang document from an input stream. 234 | 235 | The first argument is a stream function which writes up to `size` bytes to 236 | memory at `ptr`, and returns the number of bytes effectively written. 237 | 238 | The `user` parameter is a user-defined context pointer forwarded to most 239 | callbacks, and can be `NULL`. 240 | 241 | ~~~ C 242 | size_t stream_function(void* ptr, size_t size, void* user) 243 | { 244 | FILE* file = get_file_handle_from_user_context(user); 245 | return fread(ptr, 1, size, file); 246 | } 247 | ~~~ 248 | 249 | Returns 0 on success. If an error occured, a positive number is returned, 250 | which can be mapped to `sdlang_error_t`. 251 | #*/ 252 | extern int sdlang_parse(size_t (*stream)(void* ptr, size_t size, void* user), void* user); 253 | 254 | #ifdef __cplusplus 255 | } 256 | #endif 257 | -------------------------------------------------------------------------------- /sdlang.inl: -------------------------------------------------------------------------------- 1 | 2 | /* #line 1 "sdlang.rl" */ 3 | /******************************************************************************* 4 | * This file is generated by Ragel. Do not edit! 5 | * $ ragel -L -G2 -o sdlang.inl sdlang.rl 6 | ******************************************************************************/ 7 | 8 | 9 | /* #line 130 "sdlang.rl" */ 10 | 11 | 12 | 13 | /* #line 14 "sdlang.inl" */ 14 | static const int sdlang_start = 22; 15 | static const int sdlang_error = 0; 16 | 17 | static const int sdlang_en_c_comment = 1; 18 | static const int sdlang_en_block = 24; 19 | static const int sdlang_en_main = 22; 20 | 21 | 22 | /* #line 133 "sdlang.rl" */ 23 | 24 | int sdlang_parse(size_t (*stream)(void* ptr, size_t size, void* user), void* user) 25 | { 26 | char buf[SDLANG_PARSE_BUFFERSIZE]; 27 | int cs, act, have = 0, curline = 1; 28 | int stack[SDLANG_PARSE_STACKSIZE], top = 0; 29 | char *ts, *te = 0; 30 | int done = 0, err = SDLANG_PARSE_OK; 31 | 32 | 33 | /* #line 34 "sdlang.inl" */ 34 | { 35 | cs = sdlang_start; 36 | top = 0; 37 | ts = 0; 38 | te = 0; 39 | act = 0; 40 | } 41 | 42 | /* #line 143 "sdlang.rl" */ 43 | 44 | while (!done) 45 | { 46 | char *p = buf + have, *pe, *eof = 0; 47 | int len, space = SDLANG_PARSE_BUFFERSIZE - have; 48 | 49 | if (space == 0) 50 | { 51 | err = SDLANG_PARSE_ERROR_BUFFER_TOO_SMALL; 52 | break; 53 | } 54 | 55 | len = (int)stream(p, space, user); 56 | pe = p + len; 57 | 58 | if (len < space) 59 | { 60 | eof = pe; 61 | done = 1; 62 | } 63 | 64 | 65 | /* #line 66 "sdlang.inl" */ 66 | { 67 | if ( p == pe ) 68 | goto _test_eof; 69 | goto _resume; 70 | 71 | _again: 72 | switch ( cs ) { 73 | case 22: goto st22; 74 | case 1: goto st1; 75 | case 2: goto st2; 76 | case 23: goto st23; 77 | case 0: goto st0; 78 | case 24: goto st24; 79 | case 3: goto st3; 80 | case 4: goto st4; 81 | case 5: goto st5; 82 | case 6: goto st6; 83 | case 7: goto st7; 84 | case 8: goto st8; 85 | case 9: goto st9; 86 | case 10: goto st10; 87 | case 25: goto st25; 88 | case 11: goto st11; 89 | case 12: goto st12; 90 | case 26: goto st26; 91 | case 27: goto st27; 92 | case 13: goto st13; 93 | case 14: goto st14; 94 | case 28: goto st28; 95 | case 15: goto st15; 96 | case 16: goto st16; 97 | case 29: goto st29; 98 | case 17: goto st17; 99 | case 30: goto st30; 100 | case 31: goto st31; 101 | case 32: goto st32; 102 | case 33: goto st33; 103 | case 34: goto st34; 104 | case 35: goto st35; 105 | case 36: goto st36; 106 | case 37: goto st37; 107 | case 38: goto st38; 108 | case 39: goto st39; 109 | case 40: goto st40; 110 | case 41: goto st41; 111 | case 42: goto st42; 112 | case 43: goto st43; 113 | case 44: goto st44; 114 | case 45: goto st45; 115 | case 18: goto st18; 116 | case 19: goto st19; 117 | case 20: goto st20; 118 | case 21: goto st21; 119 | case 46: goto st46; 120 | case 47: goto st47; 121 | case 48: goto st48; 122 | case 49: goto st49; 123 | case 50: goto st50; 124 | case 51: goto st51; 125 | case 52: goto st52; 126 | case 53: goto st53; 127 | case 54: goto st54; 128 | case 55: goto st55; 129 | case 56: goto st56; 130 | case 57: goto st57; 131 | case 58: goto st58; 132 | default: break; 133 | } 134 | 135 | if ( ++p == pe ) 136 | goto _test_eof; 137 | _resume: 138 | switch ( cs ) 139 | { 140 | tr33: 141 | /* #line 127 "sdlang.rl" */ 142 | {te = p+1;{p--; { 143 | check_stack_size(&p, pe, top, curline); 144 | {stack[top++] = 22;goto st24;}}}} 145 | goto st22; 146 | st22: 147 | /* #line 1 "NONE" */ 148 | {ts = 0;} 149 | if ( ++p == pe ) 150 | goto _test_eof22; 151 | case 22: 152 | /* #line 1 "NONE" */ 153 | {ts = p;} 154 | /* #line 155 "sdlang.inl" */ 155 | goto tr33; 156 | tr1: 157 | /* #line 16 "sdlang.rl" */ 158 | {curline += 1;} 159 | goto st1; 160 | st1: 161 | /* #line 1 "NONE" */ 162 | {ts = 0;} 163 | if ( ++p == pe ) 164 | goto _test_eof1; 165 | case 1: 166 | /* #line 167 "sdlang.inl" */ 167 | switch( (*p) ) { 168 | case 10: goto tr1; 169 | case 42: goto st2; 170 | } 171 | goto st1; 172 | st2: 173 | if ( ++p == pe ) 174 | goto _test_eof2; 175 | case 2: 176 | switch( (*p) ) { 177 | case 10: goto tr1; 178 | case 42: goto st2; 179 | case 47: goto tr3; 180 | } 181 | goto st1; 182 | tr3: 183 | /* #line 46 "sdlang.rl" */ 184 | {{goto st24;}} 185 | goto st23; 186 | st23: 187 | if ( ++p == pe ) 188 | goto _test_eof23; 189 | case 23: 190 | /* #line 191 "sdlang.inl" */ 191 | goto st0; 192 | st0: 193 | cs = 0; 194 | goto _out; 195 | tr4: 196 | /* #line 16 "sdlang.rl" */ 197 | {curline += 1;} 198 | /* #line 119 "sdlang.rl" */ 199 | {te = p+1;{emit(SDLANG_TOKEN_NODE_END, NULL, NULL, curline, user);}} 200 | goto st24; 201 | tr8: 202 | /* #line 81 "sdlang.rl" */ 203 | {te = p+1;{emit(SDLANG_TOKEN_STRING, ts, te, curline, user);}} 204 | goto st24; 205 | tr11: 206 | /* #line 16 "sdlang.rl" */ 207 | {curline += 1;} 208 | /* #line 115 "sdlang.rl" */ 209 | {te = p+1;{emit(SDLANG_TOKEN_NODE_END, NULL, NULL, curline, user);}} 210 | goto st24; 211 | tr19: 212 | /* #line 1 "NONE" */ 213 | { switch( act ) { 214 | case 5: 215 | {{p = ((te))-1;}emit(SDLANG_TOKEN_FLOAT64, ts, te, curline, user);} 216 | break; 217 | case 8: 218 | {{p = ((te))-1;}emit(SDLANG_TOKEN_INT32, ts, te, curline, user);} 219 | break; 220 | case 11: 221 | {{p = ((te))-1;}emit(SDLANG_TOKEN_TRUE, ts, te, curline, user);} 222 | break; 223 | case 12: 224 | {{p = ((te))-1;}emit(SDLANG_TOKEN_FALSE, ts, te, curline, user);} 225 | break; 226 | case 13: 227 | {{p = ((te))-1;}emit(SDLANG_TOKEN_NULL, ts, te, curline, user);} 228 | break; 229 | } 230 | } 231 | goto st24; 232 | tr22: 233 | /* #line 88 "sdlang.rl" */ 234 | {{p = ((te))-1;}{emit(SDLANG_TOKEN_INT32, ts, te, curline, user);}} 235 | goto st24; 236 | tr25: 237 | /* #line 87 "sdlang.rl" */ 238 | {te = p+1;{emit(SDLANG_TOKEN_INT128, ts, te, curline, user);}} 239 | goto st24; 240 | tr26: 241 | /* #line 116 "sdlang.rl" */ 242 | {te = p+1;{{goto st1;}}} 243 | goto st24; 244 | tr29: 245 | /* #line 98 "sdlang.rl" */ 246 | {te = p+1;{emit(SDLANG_TOKEN_BASE64, ts, te, curline, user);}} 247 | goto st24; 248 | tr30: 249 | /* #line 16 "sdlang.rl" */ 250 | {curline += 1;} 251 | /* #line 118 "sdlang.rl" */ 252 | {te = p+1;} 253 | goto st24; 254 | tr34: 255 | /* #line 121 "sdlang.rl" */ 256 | {te = p+1;} 257 | goto st24; 258 | tr40: 259 | /* #line 103 "sdlang.rl" */ 260 | {te = p+1;{emit(SDLANG_TOKEN_NODE_END, ts, te, curline, user);}} 261 | goto st24; 262 | tr47: 263 | /* #line 105 "sdlang.rl" */ 264 | {te = p+1;{ 265 | emit(SDLANG_TOKEN_BLOCK, ts, te, curline, user); 266 | { 267 | check_stack_size(&p, pe, top, curline); 268 | {stack[top++] = 24;goto st24;}} 269 | }} 270 | goto st24; 271 | tr48: 272 | /* #line 110 "sdlang.rl" */ 273 | {te = p+1;{ 274 | emit(SDLANG_TOKEN_BLOCK_END, ts, te, curline, user); 275 | {cs = stack[--top];goto _again;} 276 | }} 277 | goto st24; 278 | tr49: 279 | /* #line 84 "sdlang.rl" */ 280 | {te = p;p--;{emit(SDLANG_TOKEN_FLOAT64, ts, te, curline, user);}} 281 | goto st24; 282 | tr50: 283 | /* #line 83 "sdlang.rl" */ 284 | {te = p+1;{emit(SDLANG_TOKEN_FLOAT32, ts, te, curline, user);}} 285 | goto st24; 286 | tr51: 287 | /* #line 88 "sdlang.rl" */ 288 | {te = p;p--;{emit(SDLANG_TOKEN_INT32, ts, te, curline, user);}} 289 | goto st24; 290 | tr53: 291 | /* #line 86 "sdlang.rl" */ 292 | {te = p+1;{emit(SDLANG_TOKEN_INT64, ts, te, curline, user);}} 293 | goto st24; 294 | tr55: 295 | /* #line 91 "sdlang.rl" */ 296 | {te = p;p--;{emit(SDLANG_TOKEN_UINT32, ts, te, curline, user);}} 297 | goto st24; 298 | tr64: 299 | /* #line 90 "sdlang.rl" */ 300 | {te = p;p--;{emit(SDLANG_TOKEN_UINT64, ts, te, curline, user);}} 301 | goto st24; 302 | tr71: 303 | /* #line 90 "sdlang.rl" */ 304 | {te = p+1;{emit(SDLANG_TOKEN_UINT64, ts, te, curline, user);}} 305 | goto st24; 306 | tr72: 307 | /* #line 79 "sdlang.rl" */ 308 | {te = p;p--;{emit(SDLANG_TOKEN_NODE, ts, te, curline, user);}} 309 | goto st24; 310 | tr73: 311 | /* #line 77 "sdlang.rl" */ 312 | {te = p+1;{emit(SDLANG_TOKEN_ATTRIBUTE, ts, te, curline, user);}} 313 | goto st24; 314 | st24: 315 | /* #line 1 "NONE" */ 316 | {ts = 0;} 317 | if ( ++p == pe ) 318 | goto _test_eof24; 319 | case 24: 320 | /* #line 1 "NONE" */ 321 | {ts = p;} 322 | /* #line 323 "sdlang.inl" */ 323 | switch( (*p) ) { 324 | case 9: goto tr34; 325 | case 10: goto tr4; 326 | case 13: goto st3; 327 | case 32: goto tr34; 328 | case 34: goto st4; 329 | case 35: goto st6; 330 | case 39: goto st7; 331 | case 43: goto st9; 332 | case 45: goto st15; 333 | case 46: goto st10; 334 | case 47: goto st16; 335 | case 48: goto tr39; 336 | case 59: goto tr40; 337 | case 91: goto st18; 338 | case 92: goto st19; 339 | case 95: goto st21; 340 | case 96: goto st7; 341 | case 102: goto st46; 342 | case 110: goto st51; 343 | case 111: goto st54; 344 | case 116: goto st56; 345 | case 123: goto tr47; 346 | case 125: goto tr48; 347 | } 348 | if ( (*p) < 65 ) { 349 | if ( 49 <= (*p) && (*p) <= 57 ) 350 | goto tr17; 351 | } else if ( (*p) > 90 ) { 352 | if ( 97 <= (*p) && (*p) <= 122 ) 353 | goto st45; 354 | } else 355 | goto st45; 356 | goto st0; 357 | st3: 358 | if ( ++p == pe ) 359 | goto _test_eof3; 360 | case 3: 361 | if ( (*p) == 10 ) 362 | goto tr4; 363 | goto st0; 364 | tr7: 365 | /* #line 16 "sdlang.rl" */ 366 | {curline += 1;} 367 | goto st4; 368 | st4: 369 | if ( ++p == pe ) 370 | goto _test_eof4; 371 | case 4: 372 | /* #line 373 "sdlang.inl" */ 373 | switch( (*p) ) { 374 | case 10: goto tr7; 375 | case 34: goto tr8; 376 | case 92: goto st5; 377 | } 378 | goto st4; 379 | st5: 380 | if ( ++p == pe ) 381 | goto _test_eof5; 382 | case 5: 383 | if ( (*p) == 10 ) 384 | goto tr7; 385 | goto st4; 386 | st6: 387 | if ( ++p == pe ) 388 | goto _test_eof6; 389 | case 6: 390 | if ( (*p) == 10 ) 391 | goto tr11; 392 | goto st6; 393 | tr13: 394 | /* #line 16 "sdlang.rl" */ 395 | {curline += 1;} 396 | goto st7; 397 | st7: 398 | if ( ++p == pe ) 399 | goto _test_eof7; 400 | case 7: 401 | /* #line 402 "sdlang.inl" */ 402 | switch( (*p) ) { 403 | case 10: goto tr13; 404 | case 39: goto tr8; 405 | case 92: goto st8; 406 | case 96: goto tr8; 407 | } 408 | goto st7; 409 | st8: 410 | if ( ++p == pe ) 411 | goto _test_eof8; 412 | case 8: 413 | if ( (*p) == 10 ) 414 | goto tr13; 415 | goto st7; 416 | st9: 417 | if ( ++p == pe ) 418 | goto _test_eof9; 419 | case 9: 420 | switch( (*p) ) { 421 | case 46: goto st10; 422 | case 48: goto tr16; 423 | } 424 | if ( 49 <= (*p) && (*p) <= 57 ) 425 | goto tr17; 426 | goto st0; 427 | st10: 428 | if ( ++p == pe ) 429 | goto _test_eof10; 430 | case 10: 431 | if ( 48 <= (*p) && (*p) <= 57 ) 432 | goto tr18; 433 | goto st0; 434 | tr18: 435 | /* #line 1 "NONE" */ 436 | {te = p+1;} 437 | /* #line 84 "sdlang.rl" */ 438 | {act = 5;} 439 | goto st25; 440 | st25: 441 | if ( ++p == pe ) 442 | goto _test_eof25; 443 | case 25: 444 | /* #line 445 "sdlang.inl" */ 445 | switch( (*p) ) { 446 | case 69: goto st11; 447 | case 70: goto tr50; 448 | case 101: goto st11; 449 | case 102: goto tr50; 450 | } 451 | if ( 48 <= (*p) && (*p) <= 57 ) 452 | goto tr18; 453 | goto tr49; 454 | st11: 455 | if ( ++p == pe ) 456 | goto _test_eof11; 457 | case 11: 458 | switch( (*p) ) { 459 | case 43: goto st12; 460 | case 45: goto st12; 461 | } 462 | if ( 48 <= (*p) && (*p) <= 57 ) 463 | goto st26; 464 | goto tr19; 465 | st12: 466 | if ( ++p == pe ) 467 | goto _test_eof12; 468 | case 12: 469 | if ( 48 <= (*p) && (*p) <= 57 ) 470 | goto st26; 471 | goto tr19; 472 | st26: 473 | if ( ++p == pe ) 474 | goto _test_eof26; 475 | case 26: 476 | switch( (*p) ) { 477 | case 70: goto tr50; 478 | case 102: goto tr50; 479 | } 480 | if ( 48 <= (*p) && (*p) <= 57 ) 481 | goto st26; 482 | goto tr49; 483 | tr16: 484 | /* #line 1 "NONE" */ 485 | {te = p+1;} 486 | /* #line 88 "sdlang.rl" */ 487 | {act = 8;} 488 | goto st27; 489 | st27: 490 | if ( ++p == pe ) 491 | goto _test_eof27; 492 | case 27: 493 | /* #line 494 "sdlang.inl" */ 494 | switch( (*p) ) { 495 | case 46: goto tr18; 496 | case 66: goto st14; 497 | case 69: goto st11; 498 | case 76: goto tr53; 499 | case 98: goto st14; 500 | case 101: goto st11; 501 | case 108: goto tr53; 502 | } 503 | if ( 48 <= (*p) && (*p) <= 57 ) 504 | goto st13; 505 | goto tr51; 506 | st13: 507 | if ( ++p == pe ) 508 | goto _test_eof13; 509 | case 13: 510 | switch( (*p) ) { 511 | case 46: goto tr18; 512 | case 69: goto st11; 513 | case 101: goto st11; 514 | } 515 | if ( 48 <= (*p) && (*p) <= 57 ) 516 | goto st13; 517 | goto tr22; 518 | st14: 519 | if ( ++p == pe ) 520 | goto _test_eof14; 521 | case 14: 522 | switch( (*p) ) { 523 | case 68: goto tr25; 524 | case 100: goto tr25; 525 | } 526 | goto tr22; 527 | tr17: 528 | /* #line 1 "NONE" */ 529 | {te = p+1;} 530 | /* #line 88 "sdlang.rl" */ 531 | {act = 8;} 532 | goto st28; 533 | st28: 534 | if ( ++p == pe ) 535 | goto _test_eof28; 536 | case 28: 537 | /* #line 538 "sdlang.inl" */ 538 | switch( (*p) ) { 539 | case 46: goto tr18; 540 | case 66: goto st14; 541 | case 69: goto st11; 542 | case 76: goto tr53; 543 | case 98: goto st14; 544 | case 101: goto st11; 545 | case 108: goto tr53; 546 | } 547 | if ( 48 <= (*p) && (*p) <= 57 ) 548 | goto tr17; 549 | goto tr51; 550 | st15: 551 | if ( ++p == pe ) 552 | goto _test_eof15; 553 | case 15: 554 | switch( (*p) ) { 555 | case 45: goto st6; 556 | case 46: goto st10; 557 | case 48: goto tr16; 558 | } 559 | if ( 49 <= (*p) && (*p) <= 57 ) 560 | goto tr17; 561 | goto st0; 562 | st16: 563 | if ( ++p == pe ) 564 | goto _test_eof16; 565 | case 16: 566 | switch( (*p) ) { 567 | case 42: goto tr26; 568 | case 47: goto st6; 569 | } 570 | goto st0; 571 | tr39: 572 | /* #line 1 "NONE" */ 573 | {te = p+1;} 574 | /* #line 88 "sdlang.rl" */ 575 | {act = 8;} 576 | goto st29; 577 | st29: 578 | if ( ++p == pe ) 579 | goto _test_eof29; 580 | case 29: 581 | /* #line 582 "sdlang.inl" */ 582 | switch( (*p) ) { 583 | case 46: goto tr18; 584 | case 66: goto st14; 585 | case 69: goto st11; 586 | case 76: goto tr53; 587 | case 88: goto st17; 588 | case 98: goto st14; 589 | case 101: goto st11; 590 | case 108: goto tr53; 591 | case 120: goto st17; 592 | } 593 | if ( 48 <= (*p) && (*p) <= 57 ) 594 | goto st13; 595 | goto tr51; 596 | st17: 597 | if ( ++p == pe ) 598 | goto _test_eof17; 599 | case 17: 600 | if ( (*p) < 65 ) { 601 | if ( 48 <= (*p) && (*p) <= 57 ) 602 | goto st30; 603 | } else if ( (*p) > 70 ) { 604 | if ( 97 <= (*p) && (*p) <= 102 ) 605 | goto st30; 606 | } else 607 | goto st30; 608 | goto tr22; 609 | st30: 610 | if ( ++p == pe ) 611 | goto _test_eof30; 612 | case 30: 613 | if ( (*p) < 65 ) { 614 | if ( 48 <= (*p) && (*p) <= 57 ) 615 | goto st31; 616 | } else if ( (*p) > 70 ) { 617 | if ( 97 <= (*p) && (*p) <= 102 ) 618 | goto st31; 619 | } else 620 | goto st31; 621 | goto tr55; 622 | st31: 623 | if ( ++p == pe ) 624 | goto _test_eof31; 625 | case 31: 626 | if ( (*p) < 65 ) { 627 | if ( 48 <= (*p) && (*p) <= 57 ) 628 | goto st32; 629 | } else if ( (*p) > 70 ) { 630 | if ( 97 <= (*p) && (*p) <= 102 ) 631 | goto st32; 632 | } else 633 | goto st32; 634 | goto tr55; 635 | st32: 636 | if ( ++p == pe ) 637 | goto _test_eof32; 638 | case 32: 639 | if ( (*p) < 65 ) { 640 | if ( 48 <= (*p) && (*p) <= 57 ) 641 | goto st33; 642 | } else if ( (*p) > 70 ) { 643 | if ( 97 <= (*p) && (*p) <= 102 ) 644 | goto st33; 645 | } else 646 | goto st33; 647 | goto tr55; 648 | st33: 649 | if ( ++p == pe ) 650 | goto _test_eof33; 651 | case 33: 652 | if ( (*p) < 65 ) { 653 | if ( 48 <= (*p) && (*p) <= 57 ) 654 | goto st34; 655 | } else if ( (*p) > 70 ) { 656 | if ( 97 <= (*p) && (*p) <= 102 ) 657 | goto st34; 658 | } else 659 | goto st34; 660 | goto tr55; 661 | st34: 662 | if ( ++p == pe ) 663 | goto _test_eof34; 664 | case 34: 665 | if ( (*p) < 65 ) { 666 | if ( 48 <= (*p) && (*p) <= 57 ) 667 | goto st35; 668 | } else if ( (*p) > 70 ) { 669 | if ( 97 <= (*p) && (*p) <= 102 ) 670 | goto st35; 671 | } else 672 | goto st35; 673 | goto tr55; 674 | st35: 675 | if ( ++p == pe ) 676 | goto _test_eof35; 677 | case 35: 678 | if ( (*p) < 65 ) { 679 | if ( 48 <= (*p) && (*p) <= 57 ) 680 | goto st36; 681 | } else if ( (*p) > 70 ) { 682 | if ( 97 <= (*p) && (*p) <= 102 ) 683 | goto st36; 684 | } else 685 | goto st36; 686 | goto tr55; 687 | st36: 688 | if ( ++p == pe ) 689 | goto _test_eof36; 690 | case 36: 691 | if ( (*p) < 65 ) { 692 | if ( 48 <= (*p) && (*p) <= 57 ) 693 | goto st37; 694 | } else if ( (*p) > 70 ) { 695 | if ( 97 <= (*p) && (*p) <= 102 ) 696 | goto st37; 697 | } else 698 | goto st37; 699 | goto tr55; 700 | st37: 701 | if ( ++p == pe ) 702 | goto _test_eof37; 703 | case 37: 704 | if ( (*p) < 65 ) { 705 | if ( 48 <= (*p) && (*p) <= 57 ) 706 | goto st38; 707 | } else if ( (*p) > 70 ) { 708 | if ( 97 <= (*p) && (*p) <= 102 ) 709 | goto st38; 710 | } else 711 | goto st38; 712 | goto tr55; 713 | st38: 714 | if ( ++p == pe ) 715 | goto _test_eof38; 716 | case 38: 717 | if ( (*p) < 65 ) { 718 | if ( 48 <= (*p) && (*p) <= 57 ) 719 | goto st39; 720 | } else if ( (*p) > 70 ) { 721 | if ( 97 <= (*p) && (*p) <= 102 ) 722 | goto st39; 723 | } else 724 | goto st39; 725 | goto tr64; 726 | st39: 727 | if ( ++p == pe ) 728 | goto _test_eof39; 729 | case 39: 730 | if ( (*p) < 65 ) { 731 | if ( 48 <= (*p) && (*p) <= 57 ) 732 | goto st40; 733 | } else if ( (*p) > 70 ) { 734 | if ( 97 <= (*p) && (*p) <= 102 ) 735 | goto st40; 736 | } else 737 | goto st40; 738 | goto tr64; 739 | st40: 740 | if ( ++p == pe ) 741 | goto _test_eof40; 742 | case 40: 743 | if ( (*p) < 65 ) { 744 | if ( 48 <= (*p) && (*p) <= 57 ) 745 | goto st41; 746 | } else if ( (*p) > 70 ) { 747 | if ( 97 <= (*p) && (*p) <= 102 ) 748 | goto st41; 749 | } else 750 | goto st41; 751 | goto tr64; 752 | st41: 753 | if ( ++p == pe ) 754 | goto _test_eof41; 755 | case 41: 756 | if ( (*p) < 65 ) { 757 | if ( 48 <= (*p) && (*p) <= 57 ) 758 | goto st42; 759 | } else if ( (*p) > 70 ) { 760 | if ( 97 <= (*p) && (*p) <= 102 ) 761 | goto st42; 762 | } else 763 | goto st42; 764 | goto tr64; 765 | st42: 766 | if ( ++p == pe ) 767 | goto _test_eof42; 768 | case 42: 769 | if ( (*p) < 65 ) { 770 | if ( 48 <= (*p) && (*p) <= 57 ) 771 | goto st43; 772 | } else if ( (*p) > 70 ) { 773 | if ( 97 <= (*p) && (*p) <= 102 ) 774 | goto st43; 775 | } else 776 | goto st43; 777 | goto tr64; 778 | st43: 779 | if ( ++p == pe ) 780 | goto _test_eof43; 781 | case 43: 782 | if ( (*p) < 65 ) { 783 | if ( 48 <= (*p) && (*p) <= 57 ) 784 | goto st44; 785 | } else if ( (*p) > 70 ) { 786 | if ( 97 <= (*p) && (*p) <= 102 ) 787 | goto st44; 788 | } else 789 | goto st44; 790 | goto tr64; 791 | st44: 792 | if ( ++p == pe ) 793 | goto _test_eof44; 794 | case 44: 795 | if ( (*p) < 65 ) { 796 | if ( 48 <= (*p) && (*p) <= 57 ) 797 | goto tr71; 798 | } else if ( (*p) > 70 ) { 799 | if ( 97 <= (*p) && (*p) <= 102 ) 800 | goto tr71; 801 | } else 802 | goto tr71; 803 | goto tr64; 804 | st45: 805 | if ( ++p == pe ) 806 | goto _test_eof45; 807 | case 45: 808 | switch( (*p) ) { 809 | case 36: goto st45; 810 | case 61: goto tr73; 811 | case 95: goto st45; 812 | } 813 | if ( (*p) < 48 ) { 814 | if ( 45 <= (*p) && (*p) <= 46 ) 815 | goto st45; 816 | } else if ( (*p) > 58 ) { 817 | if ( (*p) > 90 ) { 818 | if ( 97 <= (*p) && (*p) <= 122 ) 819 | goto st45; 820 | } else if ( (*p) >= 65 ) 821 | goto st45; 822 | } else 823 | goto st45; 824 | goto tr72; 825 | st18: 826 | if ( ++p == pe ) 827 | goto _test_eof18; 828 | case 18: 829 | switch( (*p) ) { 830 | case 43: goto st18; 831 | case 61: goto st18; 832 | case 93: goto tr29; 833 | } 834 | if ( (*p) < 65 ) { 835 | if ( 47 <= (*p) && (*p) <= 57 ) 836 | goto st18; 837 | } else if ( (*p) > 90 ) { 838 | if ( 97 <= (*p) && (*p) <= 122 ) 839 | goto st18; 840 | } else 841 | goto st18; 842 | goto st0; 843 | st19: 844 | if ( ++p == pe ) 845 | goto _test_eof19; 846 | case 19: 847 | switch( (*p) ) { 848 | case 10: goto tr30; 849 | case 13: goto st20; 850 | } 851 | goto st0; 852 | st20: 853 | if ( ++p == pe ) 854 | goto _test_eof20; 855 | case 20: 856 | if ( (*p) == 10 ) 857 | goto tr30; 858 | goto st0; 859 | st21: 860 | if ( ++p == pe ) 861 | goto _test_eof21; 862 | case 21: 863 | if ( (*p) > 90 ) { 864 | if ( 97 <= (*p) && (*p) <= 122 ) 865 | goto st45; 866 | } else if ( (*p) >= 65 ) 867 | goto st45; 868 | goto st0; 869 | st46: 870 | if ( ++p == pe ) 871 | goto _test_eof46; 872 | case 46: 873 | switch( (*p) ) { 874 | case 36: goto st45; 875 | case 61: goto tr73; 876 | case 95: goto st45; 877 | case 97: goto st47; 878 | } 879 | if ( (*p) < 48 ) { 880 | if ( 45 <= (*p) && (*p) <= 46 ) 881 | goto st45; 882 | } else if ( (*p) > 58 ) { 883 | if ( (*p) > 90 ) { 884 | if ( 98 <= (*p) && (*p) <= 122 ) 885 | goto st45; 886 | } else if ( (*p) >= 65 ) 887 | goto st45; 888 | } else 889 | goto st45; 890 | goto tr72; 891 | st47: 892 | if ( ++p == pe ) 893 | goto _test_eof47; 894 | case 47: 895 | switch( (*p) ) { 896 | case 36: goto st45; 897 | case 61: goto tr73; 898 | case 95: goto st45; 899 | case 108: goto st48; 900 | } 901 | if ( (*p) < 48 ) { 902 | if ( 45 <= (*p) && (*p) <= 46 ) 903 | goto st45; 904 | } else if ( (*p) > 58 ) { 905 | if ( (*p) > 90 ) { 906 | if ( 97 <= (*p) && (*p) <= 122 ) 907 | goto st45; 908 | } else if ( (*p) >= 65 ) 909 | goto st45; 910 | } else 911 | goto st45; 912 | goto tr72; 913 | st48: 914 | if ( ++p == pe ) 915 | goto _test_eof48; 916 | case 48: 917 | switch( (*p) ) { 918 | case 36: goto st45; 919 | case 61: goto tr73; 920 | case 95: goto st45; 921 | case 115: goto st49; 922 | } 923 | if ( (*p) < 48 ) { 924 | if ( 45 <= (*p) && (*p) <= 46 ) 925 | goto st45; 926 | } else if ( (*p) > 58 ) { 927 | if ( (*p) > 90 ) { 928 | if ( 97 <= (*p) && (*p) <= 122 ) 929 | goto st45; 930 | } else if ( (*p) >= 65 ) 931 | goto st45; 932 | } else 933 | goto st45; 934 | goto tr72; 935 | st49: 936 | if ( ++p == pe ) 937 | goto _test_eof49; 938 | case 49: 939 | switch( (*p) ) { 940 | case 36: goto st45; 941 | case 61: goto tr73; 942 | case 95: goto st45; 943 | case 101: goto tr77; 944 | } 945 | if ( (*p) < 48 ) { 946 | if ( 45 <= (*p) && (*p) <= 46 ) 947 | goto st45; 948 | } else if ( (*p) > 58 ) { 949 | if ( (*p) > 90 ) { 950 | if ( 97 <= (*p) && (*p) <= 122 ) 951 | goto st45; 952 | } else if ( (*p) >= 65 ) 953 | goto st45; 954 | } else 955 | goto st45; 956 | goto tr72; 957 | tr77: 958 | /* #line 1 "NONE" */ 959 | {te = p+1;} 960 | /* #line 94 "sdlang.rl" */ 961 | {act = 12;} 962 | goto st50; 963 | tr80: 964 | /* #line 1 "NONE" */ 965 | {te = p+1;} 966 | /* #line 96 "sdlang.rl" */ 967 | {act = 13;} 968 | goto st50; 969 | tr82: 970 | /* #line 1 "NONE" */ 971 | {te = p+1;} 972 | /* #line 93 "sdlang.rl" */ 973 | {act = 11;} 974 | goto st50; 975 | st50: 976 | if ( ++p == pe ) 977 | goto _test_eof50; 978 | case 50: 979 | /* #line 980 "sdlang.inl" */ 980 | switch( (*p) ) { 981 | case 36: goto st45; 982 | case 95: goto st45; 983 | } 984 | if ( (*p) < 48 ) { 985 | if ( 45 <= (*p) && (*p) <= 46 ) 986 | goto st45; 987 | } else if ( (*p) > 58 ) { 988 | if ( (*p) > 90 ) { 989 | if ( 97 <= (*p) && (*p) <= 122 ) 990 | goto st45; 991 | } else if ( (*p) >= 65 ) 992 | goto st45; 993 | } else 994 | goto st45; 995 | goto tr19; 996 | st51: 997 | if ( ++p == pe ) 998 | goto _test_eof51; 999 | case 51: 1000 | switch( (*p) ) { 1001 | case 36: goto st45; 1002 | case 61: goto tr73; 1003 | case 95: goto st45; 1004 | case 117: goto st52; 1005 | } 1006 | if ( (*p) < 48 ) { 1007 | if ( 45 <= (*p) && (*p) <= 46 ) 1008 | goto st45; 1009 | } else if ( (*p) > 58 ) { 1010 | if ( (*p) > 90 ) { 1011 | if ( 97 <= (*p) && (*p) <= 122 ) 1012 | goto st45; 1013 | } else if ( (*p) >= 65 ) 1014 | goto st45; 1015 | } else 1016 | goto st45; 1017 | goto tr72; 1018 | st52: 1019 | if ( ++p == pe ) 1020 | goto _test_eof52; 1021 | case 52: 1022 | switch( (*p) ) { 1023 | case 36: goto st45; 1024 | case 61: goto tr73; 1025 | case 95: goto st45; 1026 | case 108: goto st53; 1027 | } 1028 | if ( (*p) < 48 ) { 1029 | if ( 45 <= (*p) && (*p) <= 46 ) 1030 | goto st45; 1031 | } else if ( (*p) > 58 ) { 1032 | if ( (*p) > 90 ) { 1033 | if ( 97 <= (*p) && (*p) <= 122 ) 1034 | goto st45; 1035 | } else if ( (*p) >= 65 ) 1036 | goto st45; 1037 | } else 1038 | goto st45; 1039 | goto tr72; 1040 | st53: 1041 | if ( ++p == pe ) 1042 | goto _test_eof53; 1043 | case 53: 1044 | switch( (*p) ) { 1045 | case 36: goto st45; 1046 | case 61: goto tr73; 1047 | case 95: goto st45; 1048 | case 108: goto tr80; 1049 | } 1050 | if ( (*p) < 48 ) { 1051 | if ( 45 <= (*p) && (*p) <= 46 ) 1052 | goto st45; 1053 | } else if ( (*p) > 58 ) { 1054 | if ( (*p) > 90 ) { 1055 | if ( 97 <= (*p) && (*p) <= 122 ) 1056 | goto st45; 1057 | } else if ( (*p) >= 65 ) 1058 | goto st45; 1059 | } else 1060 | goto st45; 1061 | goto tr72; 1062 | st54: 1063 | if ( ++p == pe ) 1064 | goto _test_eof54; 1065 | case 54: 1066 | switch( (*p) ) { 1067 | case 36: goto st45; 1068 | case 61: goto tr73; 1069 | case 95: goto st45; 1070 | case 102: goto st55; 1071 | case 110: goto tr82; 1072 | } 1073 | if ( (*p) < 48 ) { 1074 | if ( 45 <= (*p) && (*p) <= 46 ) 1075 | goto st45; 1076 | } else if ( (*p) > 58 ) { 1077 | if ( (*p) > 90 ) { 1078 | if ( 97 <= (*p) && (*p) <= 122 ) 1079 | goto st45; 1080 | } else if ( (*p) >= 65 ) 1081 | goto st45; 1082 | } else 1083 | goto st45; 1084 | goto tr72; 1085 | st55: 1086 | if ( ++p == pe ) 1087 | goto _test_eof55; 1088 | case 55: 1089 | switch( (*p) ) { 1090 | case 36: goto st45; 1091 | case 61: goto tr73; 1092 | case 95: goto st45; 1093 | case 102: goto tr77; 1094 | } 1095 | if ( (*p) < 48 ) { 1096 | if ( 45 <= (*p) && (*p) <= 46 ) 1097 | goto st45; 1098 | } else if ( (*p) > 58 ) { 1099 | if ( (*p) > 90 ) { 1100 | if ( 97 <= (*p) && (*p) <= 122 ) 1101 | goto st45; 1102 | } else if ( (*p) >= 65 ) 1103 | goto st45; 1104 | } else 1105 | goto st45; 1106 | goto tr72; 1107 | st56: 1108 | if ( ++p == pe ) 1109 | goto _test_eof56; 1110 | case 56: 1111 | switch( (*p) ) { 1112 | case 36: goto st45; 1113 | case 61: goto tr73; 1114 | case 95: goto st45; 1115 | case 114: goto st57; 1116 | } 1117 | if ( (*p) < 48 ) { 1118 | if ( 45 <= (*p) && (*p) <= 46 ) 1119 | goto st45; 1120 | } else if ( (*p) > 58 ) { 1121 | if ( (*p) > 90 ) { 1122 | if ( 97 <= (*p) && (*p) <= 122 ) 1123 | goto st45; 1124 | } else if ( (*p) >= 65 ) 1125 | goto st45; 1126 | } else 1127 | goto st45; 1128 | goto tr72; 1129 | st57: 1130 | if ( ++p == pe ) 1131 | goto _test_eof57; 1132 | case 57: 1133 | switch( (*p) ) { 1134 | case 36: goto st45; 1135 | case 61: goto tr73; 1136 | case 95: goto st45; 1137 | case 117: goto st58; 1138 | } 1139 | if ( (*p) < 48 ) { 1140 | if ( 45 <= (*p) && (*p) <= 46 ) 1141 | goto st45; 1142 | } else if ( (*p) > 58 ) { 1143 | if ( (*p) > 90 ) { 1144 | if ( 97 <= (*p) && (*p) <= 122 ) 1145 | goto st45; 1146 | } else if ( (*p) >= 65 ) 1147 | goto st45; 1148 | } else 1149 | goto st45; 1150 | goto tr72; 1151 | st58: 1152 | if ( ++p == pe ) 1153 | goto _test_eof58; 1154 | case 58: 1155 | switch( (*p) ) { 1156 | case 36: goto st45; 1157 | case 61: goto tr73; 1158 | case 95: goto st45; 1159 | case 101: goto tr82; 1160 | } 1161 | if ( (*p) < 48 ) { 1162 | if ( 45 <= (*p) && (*p) <= 46 ) 1163 | goto st45; 1164 | } else if ( (*p) > 58 ) { 1165 | if ( (*p) > 90 ) { 1166 | if ( 97 <= (*p) && (*p) <= 122 ) 1167 | goto st45; 1168 | } else if ( (*p) >= 65 ) 1169 | goto st45; 1170 | } else 1171 | goto st45; 1172 | goto tr72; 1173 | } 1174 | _test_eof22: cs = 22; goto _test_eof; 1175 | _test_eof1: cs = 1; goto _test_eof; 1176 | _test_eof2: cs = 2; goto _test_eof; 1177 | _test_eof23: cs = 23; goto _test_eof; 1178 | _test_eof24: cs = 24; goto _test_eof; 1179 | _test_eof3: cs = 3; goto _test_eof; 1180 | _test_eof4: cs = 4; goto _test_eof; 1181 | _test_eof5: cs = 5; goto _test_eof; 1182 | _test_eof6: cs = 6; goto _test_eof; 1183 | _test_eof7: cs = 7; goto _test_eof; 1184 | _test_eof8: cs = 8; goto _test_eof; 1185 | _test_eof9: cs = 9; goto _test_eof; 1186 | _test_eof10: cs = 10; goto _test_eof; 1187 | _test_eof25: cs = 25; goto _test_eof; 1188 | _test_eof11: cs = 11; goto _test_eof; 1189 | _test_eof12: cs = 12; goto _test_eof; 1190 | _test_eof26: cs = 26; goto _test_eof; 1191 | _test_eof27: cs = 27; goto _test_eof; 1192 | _test_eof13: cs = 13; goto _test_eof; 1193 | _test_eof14: cs = 14; goto _test_eof; 1194 | _test_eof28: cs = 28; goto _test_eof; 1195 | _test_eof15: cs = 15; goto _test_eof; 1196 | _test_eof16: cs = 16; goto _test_eof; 1197 | _test_eof29: cs = 29; goto _test_eof; 1198 | _test_eof17: cs = 17; goto _test_eof; 1199 | _test_eof30: cs = 30; goto _test_eof; 1200 | _test_eof31: cs = 31; goto _test_eof; 1201 | _test_eof32: cs = 32; goto _test_eof; 1202 | _test_eof33: cs = 33; goto _test_eof; 1203 | _test_eof34: cs = 34; goto _test_eof; 1204 | _test_eof35: cs = 35; goto _test_eof; 1205 | _test_eof36: cs = 36; goto _test_eof; 1206 | _test_eof37: cs = 37; goto _test_eof; 1207 | _test_eof38: cs = 38; goto _test_eof; 1208 | _test_eof39: cs = 39; goto _test_eof; 1209 | _test_eof40: cs = 40; goto _test_eof; 1210 | _test_eof41: cs = 41; goto _test_eof; 1211 | _test_eof42: cs = 42; goto _test_eof; 1212 | _test_eof43: cs = 43; goto _test_eof; 1213 | _test_eof44: cs = 44; goto _test_eof; 1214 | _test_eof45: cs = 45; goto _test_eof; 1215 | _test_eof18: cs = 18; goto _test_eof; 1216 | _test_eof19: cs = 19; goto _test_eof; 1217 | _test_eof20: cs = 20; goto _test_eof; 1218 | _test_eof21: cs = 21; goto _test_eof; 1219 | _test_eof46: cs = 46; goto _test_eof; 1220 | _test_eof47: cs = 47; goto _test_eof; 1221 | _test_eof48: cs = 48; goto _test_eof; 1222 | _test_eof49: cs = 49; goto _test_eof; 1223 | _test_eof50: cs = 50; goto _test_eof; 1224 | _test_eof51: cs = 51; goto _test_eof; 1225 | _test_eof52: cs = 52; goto _test_eof; 1226 | _test_eof53: cs = 53; goto _test_eof; 1227 | _test_eof54: cs = 54; goto _test_eof; 1228 | _test_eof55: cs = 55; goto _test_eof; 1229 | _test_eof56: cs = 56; goto _test_eof; 1230 | _test_eof57: cs = 57; goto _test_eof; 1231 | _test_eof58: cs = 58; goto _test_eof; 1232 | 1233 | _test_eof: {} 1234 | if ( p == eof ) 1235 | { 1236 | switch ( cs ) { 1237 | case 25: goto tr49; 1238 | case 11: goto tr19; 1239 | case 12: goto tr19; 1240 | case 26: goto tr49; 1241 | case 27: goto tr51; 1242 | case 13: goto tr22; 1243 | case 14: goto tr22; 1244 | case 28: goto tr51; 1245 | case 29: goto tr51; 1246 | case 17: goto tr22; 1247 | case 30: goto tr55; 1248 | case 31: goto tr55; 1249 | case 32: goto tr55; 1250 | case 33: goto tr55; 1251 | case 34: goto tr55; 1252 | case 35: goto tr55; 1253 | case 36: goto tr55; 1254 | case 37: goto tr55; 1255 | case 38: goto tr64; 1256 | case 39: goto tr64; 1257 | case 40: goto tr64; 1258 | case 41: goto tr64; 1259 | case 42: goto tr64; 1260 | case 43: goto tr64; 1261 | case 44: goto tr64; 1262 | case 45: goto tr72; 1263 | case 46: goto tr72; 1264 | case 47: goto tr72; 1265 | case 48: goto tr72; 1266 | case 49: goto tr72; 1267 | case 50: goto tr19; 1268 | case 51: goto tr72; 1269 | case 52: goto tr72; 1270 | case 53: goto tr72; 1271 | case 54: goto tr72; 1272 | case 55: goto tr72; 1273 | case 56: goto tr72; 1274 | case 57: goto tr72; 1275 | case 58: goto tr72; 1276 | } 1277 | } 1278 | 1279 | _out: {} 1280 | } 1281 | 1282 | /* #line 165 "sdlang.rl" */ 1283 | 1284 | if (cs == sdlang_error) 1285 | { 1286 | err = SDLANG_PARSE_ERROR; 1287 | break; 1288 | } 1289 | 1290 | if (top == SDLANG_PARSE_STACKSIZE) 1291 | { 1292 | err = SDLANG_PARSE_ERROR_STACK_OVERFLOW; 1293 | break; 1294 | } 1295 | 1296 | if (ts == 0) 1297 | { 1298 | have = 0; 1299 | } 1300 | else 1301 | { 1302 | have = (int)(pe - ts); 1303 | SDLANG_MEMMOVE(buf, ts, have); 1304 | te = buf + (te - ts); 1305 | ts = buf; 1306 | } 1307 | } 1308 | 1309 | if (err != SDLANG_PARSE_OK) 1310 | { 1311 | (*sdlang_user_report_error)(err, curline); 1312 | } 1313 | 1314 | return err; 1315 | } 1316 | --------------------------------------------------------------------------------