int argument_expression_list(void) { if( assignment_expression() ) { } else if( argument_expression_list() ) { match(COMMA); assignment_expression(); } else { abort(); } }
static sl_node_base_t* low_precedence_not_expression(sl_parse_state_t* ps) { if(peek_token(ps)->type == SL_TOK_LP_NOT) { return sl_make_unary_node(ps, assignment_expression(ps), SL_NODE_NOT); } else { return assignment_expression(ps); } }
int expression(void) { if( assignment_expression() ) { } else if ( expression() ) { match(COMMA); assignment_expression(); } else { abort(); } }
struct block *expression(struct block *block) { block = assignment_expression(block); while (peek().token == ',') { consume(','); block = assignment_expression(block); } return block; }
static sl_node_base_t* assignment_expression(sl_parse_state_t* ps) { sl_node_base_t* left = range_expression(ps); sl_token_t* tok = peek_token(ps); char* op_method; switch(tok->type) { case SL_TOK_EQUALS: op_method = NULL; break; case SL_TOK_ASSIGN_PLUS: op_method = "+"; break; case SL_TOK_ASSIGN_MINUS: op_method = "-"; break; case SL_TOK_ASSIGN_POW: op_method = "**"; break; case SL_TOK_ASSIGN_TIMES: op_method = "*"; break; case SL_TOK_ASSIGN_DIVIDE: op_method = "/"; break; case SL_TOK_ASSIGN_MOD: op_method = "%"; break; case SL_TOK_ASSIGN_PIPE: op_method = "|"; break; case SL_TOK_ASSIGN_AMP: op_method = "&"; break; case SL_TOK_ASSIGN_CARET: op_method = "^"; break; case SL_TOK_ASSIGN_OR: op_method = "||"; break; case SL_TOK_ASSIGN_AND: op_method = "&&"; break; case SL_TOK_ASSIGN_SHIFT_LEFT: op_method = "<<"; break; case SL_TOK_ASSIGN_SHIFT_RIGHT: op_method = ">>"; break; default: return left; } switch(left->type) { case SL_NODE_VAR: case SL_NODE_IVAR: case SL_NODE_CVAR: next_token(ps); left = sl_make_simple_assign_node(ps, (sl_node_var_t*)left, assignment_expression(ps), op_method); break; case SL_NODE_SEND: next_token(ps); left = sl_make_assign_send_node(ps, (sl_node_send_t*)left, assignment_expression(ps), op_method); break; case SL_NODE_CONST: /* compound assignment makes no sense on constants, so error if the assignment operator is anything except '=': */ expect_token(ps, SL_TOK_EQUALS); left = sl_make_assign_const_node(ps, (sl_node_const_t*)left, assignment_expression(ps)); break; case SL_NODE_ARRAY: /* compound assignment makes no sense on arrays, so error if the assignment operator is anything except '=': */ expect_token(ps, SL_TOK_EQUALS); left = sl_make_assign_array_node(ps, (sl_node_array_t*)left, assignment_expression(ps)); break; default: break; } return left; }
struct block *assignment_expression(struct block *block) { struct var target; block = conditional_expression(block); target = block->expr; switch (peek().token) { case '=': consume('='); block = assignment_expression(block); break; case MUL_ASSIGN: consume(MUL_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_MUL, target, block->expr); break; case DIV_ASSIGN: consume(DIV_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_DIV, target, block->expr); break; case MOD_ASSIGN: consume(MOD_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_MOD, target, block->expr); break; case PLUS_ASSIGN: consume(PLUS_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_ADD, target, block->expr); break; case MINUS_ASSIGN: consume(MINUS_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_SUB, target, block->expr); break; case AND_ASSIGN: consume(AND_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_AND, target, block->expr); break; case OR_ASSIGN: consume(OR_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_OR, target, block->expr); break; case XOR_ASSIGN: consume(XOR_ASSIGN); block = assignment_expression(block); block->expr = eval_expr(block, IR_OP_XOR, target, block->expr); break; default: return block; } block->expr = eval_assign(block, target, block->expr); return block; }
void argument_expression_list(struct ArgumentExpressionList* node, struct SymbolList* symbol) { while (symbol) { push_arg_buf(symbol->symbol); symbol = symbol->next; } push_arg(load_symbol(assignment_expression(node->assignmentExpression))); while (node->type == 1) { node = node->argumentExpressionList; push_arg(load_symbol(assignment_expression(node->assignmentExpression))); } cast_arg(); }
/** 赋值表达式 <assignment_expression>::=<equality_expression>{<TK_ASSIGN><assignment_expression>} */ void assignment_expression(){ equality_expression(); if(TK_ASSIGN == token){ get_token(); assignment_expression(); } }
/* * Production: Iteration Statement * FIRST set: { KW_T (only USING) } */ void iteration_statement(void) { match(KW_T, USING); match(LPR_T, NO_ATTR); assignment_expression(); match(COM_T, NO_ATTR); conditional_expression(); match(COM_T, NO_ATTR); assignment_expression(); match(RPR_T, NO_ATTR); match(KW_T, REPEAT); match(LBR_T, NO_ATTR); opt_statements(); match(RBR_T, NO_ATTR); match(EOS_T, NO_ATTR); gen_incode("PLATY: USING statement parsed"); }
int assignment_expression(void) { if( conditional_expression() ) { } else if( unary_expression() ) { assignment_operator(); assignment_expression(); } }
/* Parse call to builtin symbol __builtin_va_start, which is the result of * calling va_start(arg, s). Return type depends on second input argument. */ static struct block *parse__builtin_va_start(struct block *block) { const struct typetree *type; struct symbol *sym; struct token param; int is_invalid; consume('('); block = assignment_expression(block); consume(','); param = consume(IDENTIFIER); sym = sym_lookup(&ns_ident, param.strval); type = ¤t_func()->symbol->type; is_invalid = !sym || sym->depth != 1 || !is_function(type); is_invalid = is_invalid || !nmembers(type) || strcmp( get_member(type, nmembers(type) - 1)->name, param.strval); if (is_invalid) { error("Second parameter of va_start must be last function argument."); exit(1); } consume(')'); block->expr = eval__builtin_va_start(block, block->expr); return block; }
/* Parse and emit initializer code for target variable in statements such as * int b[] = {0, 1, 2, 3}. Generate a series of assignment operations on * references to target variable. */ static struct block *initializer(struct block *block, struct var target) { assert(target.kind == DIRECT); /* Do not care about cv-qualifiers here. */ target.type = unwrapped(target.type); if (peek().token == '{') { block = object_initializer(block, target); } else { block = assignment_expression(block); if (!target.symbol->depth && block->expr.kind != IMMEDIATE) { error("Initializer must be computable at load time."); exit(1); } if (target.kind == DIRECT && !target.type->size) { assert(!target.offset); assert(is_string(block->expr)); assert(is_array(block->expr.type)); /* Complete type based on string literal. Evaluation does not have * the required context to do this logic. */ ((struct symbol *) target.symbol)->type.size = block->expr.type->size; target.type = block->expr.type; } eval_assign(block, target, block->expr); } return block; }
/** <expression>::=<assignment_expression>{TK_COMMA><assignment_expression>} */ void expression(){ while(1){ assignment_expression(); if(TK_COMMA != token) break; get_token(); } }
/* FIRST(iteration statement)={USING} <iteration statement> -> USING (<assignment expression>, <conditional expression>, <assignment expression>) REPEAT { < opt_statements> }; Author: Kwok Hong Kelvin Chan */ void iteration_statement(void) { if (lookahead_token.code == KW_T && lookahead_token.attribute.get_int == USING) { match(KW_T,USING); match(LPR_T,NO_ATTR); assignment_expression(); match(COM_T, NO_ATTR); conditional_expression(); match(COM_T, NO_ATTR); assignment_expression(); match(RPR_T,NO_ATTR); match(KW_T,REPEAT); match(LBR_T,NO_ATTR); opt_statements(); match(RBR_T,NO_ATTR); match(EOS_T,NO_ATTR); gen_incode("USING statement parsed"); } }
/* FIRST(assignment statement)={AVID ,SVID} <assignment statement> -> <assignment expression>; Author: Kyle Hinskens */ void assignment_statement(void){ switch(lookahead_token.code){ case AVID_T: case SVID_T: assignment_expression(); match(EOS_T, NO_ATTR); gen_incode("Assignment statement parsed"); break; } }
int initializer(void) { if( assignment_expression() ) { } else if( lookaheadT.type == LCURLY ) { match(LCURLY); if( initializer_list() ) {} if( lookaheadT.type == COMMA ) { match(COMMA); } match(RCURLY); } else { abort(); } }
/** 实参表达式 <argument_expression_list>::=<assignment_expression> {<TK_COMMA><assignment_expression>} */ void argument_expression_list(){ get_token(); if(TK_CLOSEPA != token){ while(1){ assignment_expression(); if(TK_CLOSEPA == token) break; skip(TK_COMMA); get_token(); } } skip(TK_CLOSEPA); get_token(); }
/* Parse call to builtin symbol __builtin_va_arg, which is the result of calling * va_arg(arg, T). Return type depends on second input argument. */ static struct block *parse__builtin_va_arg(struct block *block) { struct typetree *type; consume('('); block = assignment_expression(block); consume(','); type = declaration_specifiers(NULL); if (peek().token != ')') { type = declarator(type, NULL); } consume(')'); block->expr = eval__builtin_va_arg(block, block->expr, type); return block; }
struct Symbol* assignment_expression(struct AssignmentExpression* node) { if (node->type == 0) return conditional_expression(node->conditionalExpression); // to do struct Symbol* orig_symbol; struct Symbol* symbol2 = load_symbol(assignment_expression(node->assignmentExpression)); struct Symbol* symbol1 = unary_expression(node->unaryExpression, &orig_symbol); struct Symbol* symbol3 = 0; int specifier = symbol1->specifier; test_changeable(orig_symbol); if (node->assignmentOperator > 1) { switch (node->assignmentOperator) { case 2: symbol3 = multiplicative_symbol(symbol1, symbol2, 1); break; case 3: symbol3 = multiplicative_symbol(symbol1, symbol2, 2); break; case 4: symbol3 = multiplicative_symbol(symbol1, symbol2, 3); break; case 5: symbol3 = additive_symbol(symbol1, symbol2, 1); break; case 6: symbol3 = additive_symbol(symbol1, symbol2, 2); break; case 7: symbol3 = shift_symbol(symbol1, symbol2, 1); break; case 8: symbol3 = shift_symbol(symbol1, symbol2, 2); break; case 9: symbol3 = and_symbol(symbol1, symbol2, 1); break; case 10: symbol3 = exclusive_or_symbol(symbol1, symbol2, 1); break; case 11: symbol3 = inclusive_or_symbol(symbol1, symbol2, 1); break; default: break; } } else symbol3 = symbol2; symbol3 = cast_symbol(symbol3, orig_symbol->specifier, orig_symbol->stars); ADDSTRING(" store "); code_gen_type_specifier(symbol1->specifier,0,symbol1->length,symbol1->stars); ADDSTRING(" "); code_gen_symbol('%', symbol3); ADDSTRING(", "); code_gen_type_specifier(orig_symbol->specifier,0,orig_symbol->length,orig_symbol->stars); ADDSTRING("* "); code_gen_symbol('%',orig_symbol); ADDSTRING(", align "); int l = len_gen_type_specifier(specifier); sprintf(buf, "%d", l); ADDSTRING(buf); ADDSTRING("\n"); return symbol3; }
static struct block *postfix_expression(struct block *block) { struct var root; block = primary_expression(block); root = block->expr; while (1) { const struct member *field; const struct typetree *type; struct var expr, copy, *arg; struct token tok; int i, j; switch ((tok = peek()).token) { case '[': do { /* Evaluate a[b] = *(a + b). The semantics of pointer arithmetic * takes care of multiplying b with the correct width. */ consume('['); block = expression(block); root = eval_expr(block, IR_OP_ADD, root, block->expr); root = eval_deref(block, root); consume(']'); } while (peek().token == '['); break; case '(': type = root.type; if (is_pointer(root.type) && is_function(root.type->next)) type = type_deref(root.type); else if (!is_function(root.type)) { error("Expression must have type pointer to function, was %t.", root.type); exit(1); } consume('('); arg = calloc(nmembers(type), sizeof(*arg)); for (i = 0; i < nmembers(type); ++i) { if (peek().token == ')') { error("Too few arguments, expected %d but got %d.", nmembers(type), i); exit(1); } block = assignment_expression(block); arg[i] = block->expr; /* todo: type check here. */ if (i < nmembers(type) - 1) { consume(','); } } while (is_vararg(type) && peek().token != ')') { consume(','); arg = realloc(arg, (i + 1) * sizeof(*arg)); block = assignment_expression(block); arg[i] = block->expr; i++; } consume(')'); for (j = 0; j < i; ++j) param(block, arg[j]); free(arg); root = eval_call(block, root); break; case '.': consume('.'); tok = consume(IDENTIFIER); field = find_type_member(root.type, tok.strval); if (!field) { error("Invalid field access, no member named '%s'.", tok.strval); exit(1); } root.type = field->type; root.offset += field->offset; break; case ARROW: consume(ARROW); tok = consume(IDENTIFIER); if (is_pointer(root.type) && is_struct_or_union(root.type->next)) { field = find_type_member(type_deref(root.type), tok.strval); if (!field) { error("Invalid field access, no member named '%s'.", tok.strval); exit(1); } /* Make it look like a pointer to the field type, then perform * normal dereferencing. */ root.type = type_init(T_POINTER, field->type); root = eval_deref(block, root); root.offset = field->offset; } else { error("Invalid field access."); exit(1); } break; case INCREMENT: consume(INCREMENT); copy = create_var(root.type); eval_assign(block, copy, root); expr = eval_expr(block, IR_OP_ADD, root, var_int(1)); eval_assign(block, root, expr); root = copy; break; case DECREMENT: consume(DECREMENT); copy = create_var(root.type); eval_assign(block, copy, root); expr = eval_expr(block, IR_OP_SUB, root, var_int(1)); eval_assign(block, root, expr); root = copy; break; default: block->expr = root; return block; } } }
/* * Production: Assignment Statement * FIRST set: { AVID, SVID } */ void assignment_statement(void) { assignment_expression(); match(EOS_T, NO_ATTR); gen_incode("PLATY: Assignment statement parsed"); }
struct Symbol* expression_func(struct Expression* node) { if (node->type == 1) expression_func(node->expression); return assignment_expression(node->assignmentExpression); }
/** 初值符 <initializer>::=<assignment_expreession> */ void initializer(){ assignment_expression(); }
/* $VER: vbcc (parse_expr.c) V0.8 */ #include "vbcc_cpp.h" #include "vbc.h" static char FILE_[]=__FILE__; np expression(void) /* Komma-Ausdruecke */ { np left,right,new; left=assignment_expression(); if(!left->flags) return 0; killsp(); while(ctok->type==COMMA){ #ifdef HAVE_MISRA /* removed */ #endif next_token(); killsp(); right=assignment_expression(); new=mymalloc(NODES); new->left=left; new->right=right; new->ntyp=0; new->flags=KOMMA; left=new; killsp(); }