From: Charlie Brej Date: Fri, 10 Jul 2009 14:23:54 +0000 (+0100) Subject: [script] Merge all Left-To-Right parsing into a single function X-Git-Tag: 0.7.0~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65ef7eb7e1db80ff200ef5cf533f0f39993ba028;p=thirdparty%2Fplymouth.git [script] Merge all Left-To-Right parsing into a single function --- diff --git a/src/plugins/splash/script/script-parse.c b/src/plugins/splash/script/script-parse.c index de20aa9e..1e1036b8 100644 --- a/src/plugins/splash/script/script-parse.c +++ b/src/plugins/splash/script/script-parse.c @@ -38,6 +38,24 @@ #define WITH_SEMIES + +typedef enum +{ + OP_ASSOC_INFIX_RTL, + OP_ASSOC_INFIX_LTR, + OP_ASSOC_PREFIX, + OP_ASSOC_POSTFIX, + OP_ASSOC_PREPOSTFIX, +} script_parse_operator_associativity_t; + + +typedef struct +{ + const char* symbol; + script_exp_type_t exp_type; + int presedence; +}script_parse_operator_table_entry_t; + static script_op_t *script_parse_op (ply_scan_t *scan); static script_exp_t *script_parse_exp (ply_scan_t *scan); static ply_list_t *script_parse_op_list (ply_scan_t *scan); @@ -371,203 +389,62 @@ static script_exp_t *script_parse_exp_po (ply_scan_t *scan) return exp; } -static script_exp_t *script_parse_exp_md (ply_scan_t *scan) -{ - script_exp_t *sub_a = script_parse_exp_po (scan); - - if (!sub_a) return NULL; - ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); - ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); - while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL - && (curtoken->data.symbol == '*' - || curtoken->data.symbol == '/' - || curtoken->data.symbol == '%') - && !(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL - && peektoken->data.symbol == '=')) - { - script_exp_t *exp = malloc (sizeof (script_exp_t)); - if (curtoken->data.symbol == '*') exp->type = SCRIPT_EXP_TYPE_MUL; - else if (curtoken->data.symbol == '/') exp->type = SCRIPT_EXP_TYPE_DIV; - else exp->type = SCRIPT_EXP_TYPE_MOD; - exp->data.dual.sub_a = sub_a; - ply_scan_get_next_token (scan); - sub_a = exp; - exp->data.dual.sub_b = script_parse_exp_po (scan); - curtoken = ply_scan_get_current_token (scan); - peektoken = ply_scan_peek_next_token (scan); - if (!exp->data.dual.sub_b) - { - script_parse_error (curtoken, "An invalid RHS of an expression"); - return NULL; - } - } - - return sub_a; -} - -static script_exp_t *script_parse_exp_pm (ply_scan_t *scan) -{ - script_exp_t *sub_a = script_parse_exp_md (scan); - - if (!sub_a) return NULL; - ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); - ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); - while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL - && (curtoken->data.symbol == '+' - || curtoken->data.symbol == '-') - && !(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL - && peektoken->data.symbol == '=')) - { - script_exp_t *exp = malloc (sizeof (script_exp_t)); - if (curtoken->data.symbol == '+') exp->type = SCRIPT_EXP_TYPE_PLUS; - else exp->type = SCRIPT_EXP_TYPE_MINUS; - exp->data.dual.sub_a = sub_a; - ply_scan_get_next_token (scan); - exp->data.dual.sub_b = script_parse_exp_md (scan); - sub_a = exp; - curtoken = ply_scan_get_current_token (scan); - peektoken = ply_scan_peek_next_token (scan); - if (!exp->data.dual.sub_b) - { - script_parse_error (curtoken, "An invalid RHS of an expression"); - return NULL; - } - } - - return sub_a; -} - -static script_exp_t *script_parse_exp_gt (ply_scan_t *scan) -{ - script_exp_t *sub_a = script_parse_exp_pm (scan); - - if (!sub_a) return NULL; - ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); - ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); - while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL - && (curtoken->data.symbol == '<' - || curtoken->data.symbol == '>')) /* FIXME make sure we dont consume <<= or >>= */ - { - int gt = (curtoken->data.symbol == '>'); - int eq = 0; - curtoken = ply_scan_get_next_token (scan); - if ((curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL) - && (curtoken->data.symbol == '=') - && !curtoken->whitespace) - { - eq = 1; - curtoken = ply_scan_get_next_token (scan); - } - script_exp_t *exp = malloc (sizeof (script_exp_t)); - if (gt && eq) exp->type = SCRIPT_EXP_TYPE_GE; - else if (gt && !eq) exp->type = SCRIPT_EXP_TYPE_GT; - else if (!gt && eq) exp->type = SCRIPT_EXP_TYPE_LE; - else exp->type = SCRIPT_EXP_TYPE_LT; - exp->data.dual.sub_a = sub_a; - exp->data.dual.sub_b = script_parse_exp_pm (scan); - sub_a = exp; - curtoken = ply_scan_get_current_token (scan); - peektoken = ply_scan_peek_next_token (scan); - if (!exp->data.dual.sub_b) - { - script_parse_error (curtoken, "An invalid RHS of an expression"); - return NULL; - } - } - - return sub_a; -} - -static script_exp_t *script_parse_exp_eq (ply_scan_t *scan) +static script_exp_t *script_parse_exp_ltr (ply_scan_t *scan, int presedence) { - script_exp_t *sub_a = script_parse_exp_gt (scan); - - if (!sub_a) return NULL; - while (1) + static const script_parse_operator_table_entry_t operator_table[] = { - ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); - ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); - if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (peektoken->data.symbol != '=') break; - if (peektoken->whitespace) break; - if ((curtoken->data.symbol != '=') - && (curtoken->data.symbol != '!')) break; - int ne = (curtoken->data.symbol == '!'); - ply_scan_get_next_token (scan); - ply_scan_get_next_token (scan); - - script_exp_t *exp = malloc (sizeof (script_exp_t)); - if (ne) exp->type = SCRIPT_EXP_TYPE_NE; - else exp->type = SCRIPT_EXP_TYPE_EQ; - exp->data.dual.sub_a = sub_a; - exp->data.dual.sub_b = script_parse_exp_gt (scan); - sub_a = exp; - if (!exp->data.dual.sub_b) - { - script_parse_error (ply_scan_get_current_token (scan), - "An invalid RHS of an expression"); - return NULL; - } - } - - return sub_a; -} - -static script_exp_t *script_parse_exp_an (ply_scan_t *scan) -{ - script_exp_t *sub_a = script_parse_exp_eq (scan); - + {"||", SCRIPT_EXP_TYPE_OR, 0}, /* FIXME Does const imply static? */ + {"&&", SCRIPT_EXP_TYPE_AND, 1}, + {"==", SCRIPT_EXP_TYPE_EQ, 2}, + {"!=", SCRIPT_EXP_TYPE_NE, 2}, + {">=", SCRIPT_EXP_TYPE_GE, 3}, + {"<=", SCRIPT_EXP_TYPE_LE, 3}, + {"+=", SCRIPT_EXP_TYPE_TERM_NULL, -1}, /* A few things it shouldn't consume */ + {"-=", SCRIPT_EXP_TYPE_TERM_NULL, -1}, + {"*=", SCRIPT_EXP_TYPE_TERM_NULL, -1}, + {"/=", SCRIPT_EXP_TYPE_TERM_NULL, -1}, + {"%=", SCRIPT_EXP_TYPE_TERM_NULL, -1}, + {">", SCRIPT_EXP_TYPE_GT, 3}, + {"<", SCRIPT_EXP_TYPE_LT, 3}, + {"+", SCRIPT_EXP_TYPE_PLUS, 4}, + {"-", SCRIPT_EXP_TYPE_MINUS, 4}, + {"*", SCRIPT_EXP_TYPE_MUL, 5}, + {"/", SCRIPT_EXP_TYPE_DIV, 5}, + {"%", SCRIPT_EXP_TYPE_MOD, 5}, + {NULL, SCRIPT_EXP_TYPE_TERM_NULL, -1}, + }; + + if (presedence > 5) return script_parse_exp_po (scan); + script_exp_t *sub_a = script_parse_exp_ltr (scan, presedence + 1); if (!sub_a) return NULL; + while (1) { + const char* symbol = ""; + int entry_index; ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (curtoken->data.symbol != '&') break; - if (peektoken->data.symbol != '&') break; - if (peektoken->whitespace) break; - ply_scan_get_next_token (scan); - ply_scan_get_next_token (scan); - - script_exp_t *exp = malloc (sizeof (script_exp_t)); - exp->type = SCRIPT_EXP_TYPE_AND; - exp->data.dual.sub_a = sub_a; - exp->data.dual.sub_b = script_parse_exp_eq (scan); - sub_a = exp; - if (!exp->data.dual.sub_b) + for (entry_index = 0; operator_table[entry_index].symbol; entry_index++) { - script_parse_error (ply_scan_get_current_token (scan), - "An invalid RHS of an expression"); - return NULL; + symbol = operator_table[entry_index].symbol; + if (curtoken->data.symbol != symbol[0]) continue; + if (symbol[1]) + { + if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) continue; + if (peektoken->data.symbol != symbol[1]) continue; + if (peektoken->whitespace) continue; + } + break; } - } - - return sub_a; -} - -static script_exp_t *script_parse_exp_or (ply_scan_t *scan) -{ - script_exp_t *sub_a = script_parse_exp_an (scan); - - if (!sub_a) return NULL; - while (1) - { - ply_scan_token_t *curtoken = ply_scan_get_current_token (scan); - ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan); - if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; - if (peektoken->data.symbol != '|') break; - if (curtoken->data.symbol != '|') break; - if (peektoken->whitespace) break; - ply_scan_get_next_token (scan); + if (operator_table[entry_index].presedence != presedence) break; ply_scan_get_next_token (scan); - + if (symbol[1]) ply_scan_get_next_token (scan); + script_exp_t *exp = malloc (sizeof (script_exp_t)); - exp->type = SCRIPT_EXP_TYPE_OR; + exp->type = operator_table[entry_index].exp_type; exp->data.dual.sub_a = sub_a; - exp->data.dual.sub_b = script_parse_exp_an (scan); + exp->data.dual.sub_b = script_parse_exp_ltr (scan, presedence + 1); sub_a = exp; if (!exp->data.dual.sub_b) { @@ -576,13 +453,12 @@ static script_exp_t *script_parse_exp_or (ply_scan_t *scan) return NULL; } } - return sub_a; } static script_exp_t *script_parse_exp_as (ply_scan_t *scan) { - script_exp_t *lhs = script_parse_exp_or (scan); + script_exp_t *lhs = script_parse_exp_ltr (scan, 0); if (!lhs) return NULL; ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);