static fz_css_condition *parse_condition_list(struct lexbuf *buf) { fz_css_condition *head, *tail; head = tail = parse_condition(buf); while (iscond(buf->lookahead)) { tail = tail->next = parse_condition(buf); } return head; }
/* * Edit/update/replace an attribute list */ static int parse_attribute_block(policy_lex_file_t *lexer, policy_item_t **tail, policy_reserved_word_t where) { policy_lex_t token; policy_attributes_t *this; char buffer[32]; this = rad_malloc(sizeof(*this)); if (!this) { return 0; } memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_ATTRIBUTE_LIST; this->item.lineno = lexer->lineno; this->where = where; token = policy_lex_file(lexer, 0, buffer, sizeof(buffer)); this->how = token; switch (token) { case POLICY_LEX_BEFORE_WHERE_EQUALS: case POLICY_LEX_AFTER_WHERE_EQUALS: case POLICY_LEX_BEFORE_WHERE_ASSIGN: case POLICY_LEX_AFTER_WHERE_ASSIGN: if (!parse_condition(lexer, &(this->where_loc))) { rlm_policy_free_item((policy_item_t *)this); return 0; } break; case POLICY_LEX_BEFORE_HEAD_EQUALS: case POLICY_LEX_AFTER_TAIL_EQUALS: case POLICY_LEX_BEFORE_HEAD_ASSIGN: case POLICY_LEX_AFTER_TAIL_ASSIGN: case POLICY_LEX_ASSIGN: case POLICY_LEX_SET_EQUALS: case POLICY_LEX_CONCAT_EQUALS: break; default: fprintf(stderr, "%s[%d]: Unexpected token %s\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *)this); return 0; /* unknown */ } if (!parse_block(lexer, &(this->attributes))) { rlm_policy_free_item((policy_item_t *) this); return 0; } *tail = (policy_item_t *) this; return 1; }
Status ComplexQuery::parse_segment(const string& seg) { VLOG(1) << "Parse Seg: " << seg; if (seg.empty()) { return Status(-1, "Segment is empty."); } Status status; if (seg.find_first_of("<>=!") != string::npos) { // conditional expression status = parse_condition(seg); } return status; }
instruction_ptr Parser::parse_while_block() { int start_line = current_lexeme().line(); if (!match_current_lexeme(kWhileKeyword)) return instruction_ptr(); next_lexeme(); instruction_ptr condition = parse_condition(); if(!condition) { report_current_syntax_error(); return instruction_ptr(); } if(!match_current_lexeme(kColon)) { report_current_syntax_error(); return instruction_ptr(); } next_lexeme(); next_line(); instructions block; while (!match_current_lexeme(kEndKeyword)) { instruction_ptr instruction = parse_instruction(); if (!instruction) { report_current_syntax_error(); return instruction_ptr(); } block.push_back(instruction); } next_lexeme(); return instruction_ptr(new WhileBlock(start_line, block, condition)); }
Result run( const char* source, unsigned char* stack_memory, unsigned stack_size, Intrinsic* intrinsics, unsigned num_intrinsics, HashFunction hash, void* user_data) { unsigned char op_stack[64]; // 64 nested operators Stack execution_stack = {stack_memory, stack_memory, stack_memory + stack_size}; Stack operator_stack = {op_stack, op_stack, op_stack + sizeof(op_stack)}; Context context = {execution_stack, operator_stack, intrinsics, num_intrinsics, hash, user_data}; Status s = parse_condition(source, context); if (s != SUCCESS) return Result(s, context.error.intrinsic, context.error.length); return Result(POP(context.stack)); }
struct rule_list* parse_rules (unichar* entry,struct utags UTAG,vector_ptr* rules) { // parses dictionary entry to extract rules for derivation and composition struct rule_list* rule_list = new_rule_list(rules); struct rule_list* actual_list_pos = rule_list; unichar cleaned_entry[MAX_DICT_LINE_LENGTH]; // rules will be stripped off unichar beforcond[MAX_COMPOSITION_RULE_LENGTH]; unichar aftercond[MAX_COMPOSITION_RULE_LENGTH]; unichar then_code[MAX_COMPOSITION_RULE_LENGTH]; int bcpos, acpos, tpos; bcpos = acpos = tpos = 0; enum { BEGIN, BEFORE_COND, AFTER_COND, THEN }; int state = 0; int k = 0; for (int i = 0; entry[i] != '\0'; i++) { if ( state != BEGIN ) { // inside a rule if (entry[i] == '\\') i++; // unescaping escaped chars in rule if (entry[i] == ')') { // end of rule struct composition_rule* rule = new_composition_rule(); beforcond[bcpos] = '\0'; aftercond[acpos] = '\0'; then_code[tpos] = '\0'; parse_condition(beforcond, rule->before); parse_condition(aftercond, rule->after); parse_then_code(then_code, &rule->then); bcpos = acpos = tpos = 0; if (actual_list_pos->rule != 0) { // not first rule struct rule_list* tmp = new_rule_list(rules); actual_list_pos->next = tmp; actual_list_pos = tmp; } actual_list_pos->rule = rule; state = BEGIN; } else if (state == BEFORE_COND) { // condition before if (entry[i] == '#') state = AFTER_COND; else beforcond[bcpos++] = entry[i]; } else if (state == AFTER_COND) { // condition after if (entry[i] == '=') state = THEN; else aftercond[acpos++] = entry[i]; } else if (state == THEN) // then-code then_code[tpos++] = entry[i]; } else { // not inside a rule if (entry[i] == '+') { unichar tmp[MAX_DICT_LINE_LENGTH]; int j; for (j = i+1; ((entry[j] != '+') && (entry[j] != ':') && (entry[j] != '(') && (entry[j] != '\0')); j++) tmp[j-(i+1)] = entry[j]; tmp[j-(i+1)] = '\0'; if ((!u_strcmp(tmp, UTAG.PREFIX)) || (!u_strcmp(tmp, UTAG.SUFFIX))) { i = j-1; } else if (!u_strcmp(tmp, UTAG.RULE)) { i = j; // including '(' state = BEFORE_COND; } else { cleaned_entry[k++] = entry[i]; } } else { cleaned_entry[k++] = entry[i]; } } } cleaned_entry[k] = '\0'; u_strcpy(entry, cleaned_entry); if (rule_list->rule == 0) rule_list->rule = new_composition_rule(); return rule_list; }
/* * if (...) {...} * if (...) {...} else {...} * if (...) {...} else if ... */ static int parse_if(policy_lex_file_t *lexer, policy_item_t **tail) { int rcode; policy_lex_t token; char mystring[256]; policy_if_t *this; debug_tokens("[IF] "); this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_IF; this->item.lineno = lexer->lineno; rcode = parse_condition(lexer, &(this->condition)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } rcode = parse_block(lexer, &(this->if_true)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_ELSE)) { debug_tokens("[ELSE] "); token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); rad_assert(token == POLICY_LEX_BARE_WORD); token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_IF)) { token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); rad_assert(token == POLICY_LEX_BARE_WORD); rcode = parse_if(lexer, &(this->if_false)); } else { rcode = parse_block(lexer, &(this->if_false)); } if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } } debug_tokens("\n"); /* * Empty "if" condition, don't even bother remembering * it. */ if (!this->if_true && !this->if_false) { debug_tokens("Discarding empty \"if\" statement at line %d\n", this->item.lineno); rlm_policy_free_item((policy_item_t *) this); return 1; } *tail = (policy_item_t *) this; return 1; }
/* * (foo == bar), with nested conditionals. */ static int parse_condition(policy_lex_file_t *lexer, policy_item_t **tail) { int rcode, seen_not = FALSE; policy_lex_t token, compare; char lhs[256], rhs[256]; policy_condition_t *this; token = policy_lex_file(lexer, 0, lhs, sizeof(lhs)); if (token != POLICY_LEX_L_BRACKET) { fprintf(stderr, "%s[%d]: Expected '(', got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, lhs)); return 0; } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_CONDITIONAL; this->item.lineno = lexer->lineno; redo: token = policy_lex_file(lexer, 0, lhs, sizeof(lhs)); switch (token) { case POLICY_LEX_L_BRACKET: if (!policy_lex_push_token(lexer, token)) { rlm_policy_free_item((policy_item_t *) this); return 0; } this->compare = POLICY_LEX_L_BRACKET; this->child_condition = POLICY_LEX_L_BRACKET; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } break; case POLICY_LEX_L_NOT: if (seen_not) { fprintf(stderr, "%s[%d]: Syntax error at \"!!\"\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } debug_tokens("[NOT] "); token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token != POLICY_LEX_L_BRACKET) { seen_not = this->sense = 1; goto redo; } this->compare = POLICY_LEX_L_NOT; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } break; case POLICY_LEX_BARE_WORD: this->lhs_type = token; token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token == POLICY_LEX_L_BRACKET) { debug_tokens("[IF-CALL %s] ", lhs); /* * Function call. */ if (rlm_policy_find(lexer->policies, lhs) == NULL) { fprintf(stderr, "%s[%d]: Undefined function \"%s\"\n", lexer->filename, lexer->lineno, lhs); rlm_policy_free_item((policy_item_t *) this); return 0; } /* * this->lhs set up below, after "check" */ this->lhs_type = POLICY_LEX_FUNCTION; /* * Copied from parse_call */ token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_L_BRACKET) { fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_R_BRACKET) { fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } } /* else it's a comparison? */ goto check; case POLICY_LEX_DOUBLE_QUOTED_STRING: this->lhs_type = token; /* * Got word. May just be test for existence. */ check: token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token == POLICY_LEX_R_BRACKET) { debug_tokens("[TEST %s] ", lhs); this->lhs = strdup(lhs); this->compare = POLICY_LEX_CMP_TRUE; break; } compare = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); switch (compare) { case POLICY_LEX_CMP_EQUALS: case POLICY_LEX_CMP_NOT_EQUALS: case POLICY_LEX_RX_EQUALS: case POLICY_LEX_RX_NOT_EQUALS: case POLICY_LEX_CMP_TRUE: case POLICY_LEX_CMP_FALSE: case POLICY_LEX_LT: case POLICY_LEX_GT: case POLICY_LEX_LE: case POLICY_LEX_GE: break; default: fprintf(stderr, "%s[%d]: Invalid operator \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, compare, rhs)); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); if ((token != POLICY_LEX_BARE_WORD) && (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) { fprintf(stderr, "%s[%d]: Unexpected rhs token\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } debug_tokens("[COMPARE (%s %s %s)] ", lhs, fr_int2str(rlm_policy_tokens, compare, "?"), rhs); this->lhs = strdup(lhs); this->compare = compare; this->rhs_type = token; this->rhs = strdup(rhs); break; default: fprintf(stderr, "%s[%d]: Unexpected lhs token\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_R_BRACKET) { fprintf(stderr, "%s[%d]: Expected ')', got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } /* * After the end of condition, we MAY have && or || */ token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if ((token == POLICY_LEX_L_AND) || (token == POLICY_LEX_L_OR)) { token = policy_lex_file(lexer, 0, NULL, 0); /* skip over it */ debug_tokens("[%s] ", fr_int2str(rlm_policy_tokens, token, "?")); this->child_condition = token; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return 0; } } *tail = (policy_item_t *) this; return 1; }
static Node * parse_list (TextgenTemplate *tpl, GList *tokens, CheckEndFunc check_end, GList **end, GError **error) { gboolean success = TRUE; GList *list = NULL; GList *l; l = tokens; while (l && !(check_end && check_end (l))) { Token *token = l->data; if (token->type == TOKEN_TEXT) { Node *node; node = g_slice_new (Node); node->type = NODE_TEXT; node->value.text.text = token->content; node->value.text.length = token->content_length; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_VARIABLE) { Node *node; node = g_slice_new (Node); node->type = NODE_VARIABLE; node->value.variable.name = token->content; node->value.variable.line = token->line; node->value.variable.column = token->column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_EXPRESSION || token->type == TOKEN_SCRIPT) { Node *node; node = g_slice_new (Node); node->type = token->type == TOKEN_EXPRESSION ? NODE_EXPRESSION : NODE_SCRIPT; node->value.script.code = token->content; node->value.script.length = token->content_length; node->value.script.code_line = token->line; node->value.script.code_column = token->content_column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_COMMAND) { if (g_ascii_strcasecmp (token->command, "IF") == 0) { Node *node; GList *end; GError *tmp_error = NULL; node = parse_condition (tpl, l, &end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } list = g_list_prepend (list, node); l = end->next; } else if (g_ascii_strcasecmp (token->command, "INCLUDE") == 0) { Node *node; node = g_slice_new (Node); node->type = NODE_INCLUDE; node->value.script.code = token->content; node->value.script.length = token->content_length; node->value.script.code_line = token->line; node->value.script.code_column = token->content_column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, token->line, token->column, _("Unknown command %s"), token->command); set_parse_error (error); success = FALSE; goto finish; } } } if (end) *end = l; finish: if (success) { Node *node = g_slice_new (Node); node->type = NODE_LIST; node->value.list = g_list_reverse (list); return node; } else { g_list_free_full (list, free_node); return NULL; } }
static Node * parse_condition (TextgenTemplate *tpl, GList *tokens, GList **end, GError **error) { Token *start_token = tokens->data; Token *end_token; gboolean success = TRUE; Node *if_true = NULL; Node *if_false = NULL; GList *tmp_end = NULL; GError *tmp_error = NULL; if_true = parse_list (tpl, tokens->next, check_condition_if_true_end, &tmp_end, &tmp_error); if (tmp_error != NULL) { success = FALSE; g_propagate_error (error, tmp_error); goto finish; } if (tmp_end == NULL) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_token->line, start_token->column, _("Could not find ENDIF of the condition")); set_parse_error (error); success = FALSE; goto finish; } end_token = tmp_end->data; if (g_ascii_strcasecmp (end_token->command, "ELSEIF") == 0) { if_false = parse_condition (tpl, tmp_end, &tmp_end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } } else if (g_ascii_strcasecmp (end_token->command, "ELSE") == 0) { if_false = parse_list (tpl, tmp_end->next, check_condition_if_false_end, &tmp_end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } if (tmp_end == NULL) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_token->line, start_token->column, _("Could not find ENDIF of the condition")); set_parse_error (error); success = FALSE; goto finish; } } finish: if (success) { Node *node; node = g_slice_new (Node); node->type = NODE_CONDITION; node->value.cond.code = start_token->content; node->value.cond.length = start_token->content_length; node->value.cond.if_true = if_true; node->value.cond.if_false = if_false; node->value.cond.code_line = start_token->line; node->value.cond.code_column = start_token->column; start_token->owns_content = FALSE; *end = tmp_end; return node; } else { if (if_true) free_node (if_true); if (if_false) free_node (if_false); return FALSE; } }