void parse_ifClause() { expression_t expr; size_t conv_expr; size_t jc_addr; size_t jmp_addr; size_t stack_frame; bool jmp_used = true; switch(next_token.type) { case TT_KW_IF: match(TT_KW_IF); match(TT_PARENTHESES_OPEN); expr = parse_expr(); match(TT_PARENTHESES_CLOSE); jc_addr = get_code_seg_top(); switch (expr.type) { case DOUBLE_LIT_DT: if(!((int)expr.double_val)) generate_jump(0); //address is unknown yet else jmp_used = false; break; case INT_LIT_DT: if(!expr.int_val) generate_jump(0); //address is unknown yet else jmp_used = false; break; case DOUBLE_DT: conv_expr = generate_double_to_int(expr.addr); generate_neg_cond_jump(0, conv_expr); //address is unknown yet break; case INT_DT: generate_neg_cond_jump(0, expr.addr); //address is unknown yet break; case STRING_LIT_DT: case STRING_DT: error("String value in a if statement", ERROR_TYPE_COMPAT); break; default: ; } stack_frame = store_stack_frame(); parse_block(true); load_stack_frame(stack_frame); generate_data_seg_restore(stack_frame); jmp_addr = get_code_seg_top(); generate_jump(0); //address is unknown yet if (jmp_used) set_jump_addr(jc_addr, get_code_seg_top()); match(TT_KW_ELSE); stack_frame = store_stack_frame(); parse_block(true); load_stack_frame(stack_frame); generate_data_seg_restore(stack_frame); set_jump_addr(jmp_addr, get_code_seg_top()); break; default: error("Syntactic error: Failed to parse the program", ERROR_SYN); } }
Statement *ParserContext::parse_if() { eat_token(tok_if); Expression *cond = parse_paren_expression(); AST *true_block = parse_block(); if (curtok()->type() == tok_else) { AST *false_block = parse_block(); return new IfStatement(cond, true_block, false_block); } return new IfStatement(cond, true_block); }
/* lstatement -> ['ID' ':'] statement */ int parse_lstatement(ast_node* block) { int current_id = stat_count++; /* store ID before parsing a block */ char* label = (char*)NULL; ast_node* expr; ast_node* block1, *block2; if (match(T_ID, T_COLON)) /* statement has a label */ label = strdup(lexeme); if (match(T_ID, T_ASSIGN)) { /* parse assignment statement */ char* name = strdup(lexeme); /* save lexeme before advancing */ expr = parse_expression(); expect(T_SEMI); ast_push_assign_stat(block, label, name, expr, current_id, lineno); return 1; } else if (match(T_SKIP, T_UNDEF)) { /* parse skip statement */ expect(T_SEMI); ast_push_skip_stat(block, label, current_id, lineno); return 1; } else if (match(T_IF, T_UNDEF)) { /* parse if-then-else statement */ expect(T_L_PAREN); expr = parse_expression(); expect(T_R_PAREN); expect(T_THEN); block1 = parse_block(); if (match(T_ELSE, T_UNDEF)) { /* create else node */ block2 = parse_block(); ast_push_if_else_stat(block, label, expr, block1, block2, current_id, lineno); } else ast_push_if_then_stat(block, label, expr, block1, current_id, lineno); return 1; } else if (match(T_WHILE, T_UNDEF)) {/* parse while statement */ expect(T_L_PAREN); expr = parse_expression(); expect(T_R_PAREN); expect(T_DO); block1 = parse_block(); ast_push_while_stat(block, label, expr, block1, current_id, lineno); return 1; } else if (match(T_AWAIT, T_UNDEF)) {/* parse await statement */ expect(T_L_PAREN); expr = parse_expression(); expect(T_R_PAREN); expect(T_SEMI); ast_push_await_stat(block, label, expr, current_id, lineno); return 1; } else { --stat_count; /* backtrack statement counter */ return 0; } }
/** Parse @c switch statement. * * @param parse Parser object. * @return New syntax tree node. */ static stree_switch_t *parse_switch(parse_t *parse) { stree_switch_t *switch_s; stree_when_t *when_c; stree_expr_t *expr; #ifdef DEBUG_PARSE_TRACE printf("Parse 'switch' statement.\n"); #endif lmatch(parse, lc_switch); switch_s = stree_switch_new(); list_init(&switch_s->when_clauses); switch_s->expr = parse_expr(parse); lmatch(parse, lc_is); /* Parse @c when clauses. */ while (lcur_lc(parse) == lc_when) { lskip(parse); when_c = stree_when_new(); list_init(&when_c->exprs); while (b_true) { expr = parse_expr(parse); list_append(&when_c->exprs, expr); if (lcur_lc(parse) != lc_comma) break; lskip(parse); } lmatch(parse, lc_do); when_c->block = parse_block(parse); list_append(&switch_s->when_clauses, when_c); } /* Parse @c else clause. */ if (lcur_lc(parse) == lc_else) { lskip(parse); lmatch(parse, lc_do); switch_s->else_block = parse_block(parse); } else { switch_s->else_block = NULL; } lmatch(parse, lc_end); return switch_s; }
/* parse_while Matches a valid while loop declaration Parameters: none Return: none */ void parse_while(Tree &cst){ cst.add_branch_node("while_stmt"); match("while", cst); parse_bool(cst); parse_block(cst); cst.kill_all_children(); }
struct prog *parse_prog(void) { algolist_t algolist = parse_algolist(); vardecllist_t globvar; typedecllist_t type_decls; constdecllist_t const_decls; if( lookahead[0]->type == CONST) { const_decls = parse_constdecls(); } else const_decls = empty_constdecllist(); if (lookahead[0]->type == VARIABLES) { eat(VARIABLES); eat(EOL); globvar = parse_vardecls(); } else globvar = empty_vardecllist(); if (lookahead[0]->type == TYPES) type_decls = parse_typedecls(); else type_decls = empty_typedecllist(); eat(BEGIN); eat(EOL); instructionlist_t instrs = parse_block(); eat(END); if (lookahead[0]->type == EOL) eat(EOL); eat(ENDOFFILE); struct entry_point *entrypoint = make_entry_point(globvar, instrs, type_decls, const_decls); return make_prog(algolist, entrypoint); }
/* parse_statement Checks the current token to be able to parse the correct statement Parameters: none Return: none */ void parse_statement(Tree &cst){ cst.add_branch_node("statement"); if(!(curr_token -> desc).compare("print")){ parse_print(cst); } else if(!(curr_token -> type).compare("identifier")){ parse_assingment(cst); } else if(types.find(curr_token -> desc) != types.end()){ parse_var_decl(cst); } else if(!(curr_token -> desc).compare("while")){ parse_while(cst); } else if(!(curr_token -> desc).compare("if")){ parse_if(cst); } else if(!(curr_token -> type).compare("open_block")){ parse_block(cst); } else{ std::cout << "Parse Error on line " << curr_token -> line_number << ".\nExpected statement, found " << curr_token -> desc << "\nStatements begin with:\n\tprint\n\tidentifier -- [a-z]\n\t" << "int, string, boolean\n\twhile\n\tif\n\t{" << "\n\nCompilation unsuccessful" << std::endl; exit(EXIT_FAILURE); } cst.kill_all_children(); }
/* parse_blockquote • hanldes parsing of a blockquote fragment */ static size_t parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size) { size_t beg, end = 0, pre, work_size = 0; char *work_data = 0; struct buf *out = new_work_buffer(rndr); beg = 0; while (beg < size) { for (end = beg + 1; end < size && data[end - 1] != '\n'; end += 1); pre = prefix_quote(data + beg, end - beg); if (pre) beg += pre; /* skipping prefix */ else if (is_empty(data + beg, end - beg) && (end >= size || (prefix_quote(data + end, size - end) == 0 && !is_empty(data + end, size - end)))) /* empty line followed by non-quote line */ break; if (beg < end) { /* copy into the in-place working buffer */ /* bufput(work, data + beg, end - beg); */ if (!work_data) work_data = data + beg; else if (data + beg != work_data + work_size) memmove(work_data + work_size, data + beg, end - beg); work_size += end - beg; } beg = end; } parse_block(out, rndr, work_data, work_size); if (rndr->make.blockquote) rndr->make.blockquote(ob, out, rndr->make.opaque); release_work_buffer(rndr, out); return end; }
static ifstatement_t* parse_if(parser_t* p) { ifstatement_t* ifstatement = (ifstatement_t*)malloc(sizeof(ifstatement_t)); match(p, TT_IF); ifstatement->expression = parse_expression(p); ifstatement->block = parse_block(p); token_type_t tok = get_token(p->t); if (TT_ELSE == tok) { ifstatement->else_block = parse_block(p); match(p, TT_END); } else { ifstatement->else_block = 0; expect(p, TT_END); } return ifstatement; }
static int parse_expr(cstate *cs, AConfig *node) { /* last token was T_TEXT */ node = _aconfig_find(node, cs->text, 1); for(;;) { switch(lex(cs, 1)) { case T_DOT: if(lex(cs, 0) != T_TEXT) return -1; node = _aconfig_find(node, cs->text, 1); continue; case T_TEXT: node->value = cs->text; return 0; case T_OBRACE: return parse_block(cs, node); default: return -1; } } }
struct instruction *parse_if(void) { instructionlist_t elseblock; eat(IF); struct expr *cond = parse_expression(); eat(THEN); eat(EOL); instructionlist_t block = parse_block(); if (lookahead[0]->type == ELSE) { eat(ELSE); eat(EOL); elseblock = parse_block(); } else elseblock = empty_instructionlist(); eat(END); eat(IF); eat(EOL); return ifthenelseblock(cond, block, elseblock); }
/* Statatements */ Statement *ParserContext::parse_while() { eat_token(tok_while); Expression *cond = parse_paren_expression(); AST *block = parse_block(); return new WhileStatement(cond, block); }
string str_event(const event_t event) { // Parse event const section_t section = parse_section(event); const auto block = parse_block(event); const uint8_t dimensions = parse_dimensions(event); // Parse kind switch (event&ekind_mask) { case unevent: return "unevent"; case block_ekind: return format("s%s b%d,%d,%d,%d",str(section),block[0],block[1],block[2],block[3]); case line_ekind: { string b[4]; for (int i=0;i<4;i++) b[i] = i==dimensions?"_":str(int(block[i-(i>=dimensions)])); return format("s%s d%d b%s,%s,%s,%s",str(section),dimensions,b[0],b[1],b[2],b[3]); } case block_line_ekind: return format("s%s d%d b%d,%d,%d,%d",str(section),dimensions,block[0],block[1],block[2],block[3]); case block_lines_ekind: return format("s%s ss%d cd%d b%d,%d,%d,%d",str(section),dimensions>>2,dimensions&3,block[0],block[1],block[2],block[3]); default: return "<error>"; } }
static funcdef_t* parse_funcdef(parser_t* p, bool is_inline) { funcdef_t* funcdef = (funcdef_t*)malloc(sizeof(funcdef_t)); funcdef->line_number = p->t->line_number; match(p, TT_DEF); if (!is_inline) { match(p, TT_IDENT); strcpy(funcdef->name, ((char*)(p->t->token_value))); } funcdef->parameters = create_list(); token_type_t tok = get_token(p->t); if (TT_OP_POPEN == tok) { tok = get_token(p->t); if (TT_OP_PCLOSE != tok) { unget_token(p->t); do { list_insert(funcdef->parameters, parse_vardecl(p)); get_token(p->t); } while (TT_OP_COMMA == p->t->token_type); } expect(p, TT_OP_PCLOSE); } else { unget_token(p->t); } funcdef->block = parse_block(p); match(p, TT_END); return funcdef; }
struct caseblock *parse_caseblock(void) { exprlist_t exprlist = parse_expressionlist(); eat(COLON); instructionlist_t block = parse_block(); return caseblock(exprlist, block); }
/** Parse member function. * * @param parse Parser object. * @param outer_csi CSI containing this declaration or @c NULL if global. * @return New syntax tree node. */ static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi) { stree_fun_t *fun; stree_symbol_t *symbol; bool_t body_expected; fun = stree_fun_new(); symbol = stree_symbol_new(sc_fun); symbol->u.fun = fun; symbol->outer_csi = outer_csi; fun->symbol = symbol; lmatch(parse, lc_fun); fun->name = parse_ident(parse); #ifdef DEBUG_PARSE_TRACE printf("Parsing function '%s'.\n", strtab_get_str(fun->name->sid)); #endif fun->sig = parse_fun_sig(parse); /* Parse attributes. */ parse_symbol_attrs(parse, symbol); body_expected = !stree_symbol_has_attr(symbol, sac_builtin) && (outer_csi->cc != csi_interface); fun->proc = stree_proc_new(); fun->proc->outer_symbol = symbol; if (lcur_lc(parse) == lc_scolon) { lskip(parse); /* Body not present */ if (body_expected) { cspan_print(fun->name->cspan); printf(" Error: Function '"); symbol_print_fqn(symbol); printf("' should have a body.\n"); parse_note_error(parse); } fun->proc->body = NULL; } else { lmatch(parse, lc_is); fun->proc->body = parse_block(parse); lmatch(parse, lc_end); /* Body present */ if (!body_expected) { cspan_print(fun->name->cspan); printf(" Error: Function declaration '"); symbol_print_fqn(symbol); printf("' should not have a body.\n"); parse_note_error(parse); } } return fun; }
Statement *ParserContext::parse_def() { eat_token(tok_def); if (curtok()->type() != tok_word) throw SyntaxError("Expected identifier in function definition"); std::string funcname = curtok()->string(); eat_token(tok_word); if (curtok()->type() != tok_paren_start) throw SyntaxError("Expected parenthesis in function definition"); eat_token(tok_paren_start); std::vector<std::string> params; while (curtok()->type() != tok_paren_end) { if (curtok()->type() != tok_word) throw SyntaxError("Parameters must be identifiers in function definitions"); params.push_back(curtok()->string()); eat_token(tok_word); if (curtok()->type() == tok_comma) eat_token(tok_comma); } eat_token(tok_paren_end); return new DefStatement(funcname, params, parse_block()); }
BLOCK *clone_block(FS *fs, BLOCK *block) { BLOCK *clone; if (block->pins == 0 && !(block->flags & F_DIRTY)) { set_flag(block, F_CLONE); remove_block_from_hash(fs, block); return block; } clone = find_free_slot(fs); memcpy(clone->buffer, block->buffer, fs->block_size); set_flag(clone, F_CACHED); set_flag(clone, F_CLONE); clone->type = block->type; clone->location = block->location; if (block->type != B_DATA) { if (!parse_block(fs, clone)) { printf("Error parsing cloned block %ld\n", block->location); return NULL; } } return clone; }
void parse_funcBody(symbol_t* funcRef) { symbol_t* func; switch(next_token.type) { case TT_SEMICOLON: match(TT_SEMICOLON); break; case TT_BLOCK_START: func = func_table_find(func_get_name()); func->def = true; //function is defined func->addr = get_code_seg_top(); var_table_scope_enter(); init_new_stack_frame(param_count); if (funcRef->paramList) { unode_str_t* paramIter = funcRef->paramList->front; while (paramIter) { var_table_add(&(paramIter->item)); paramIter = paramIter->next; } } parse_block(false); generate_no_return_exception(); break; default: error("Syntactic error: Failed to parse the program", ERROR_SYN); } }
/** Parse member property getter. * * @param parse Parser object. * @param prop Property containing this declaration. */ static void parse_prop_get(parse_t *parse, stree_prop_t *prop) { cspan_t *cspan; stree_block_t *block; stree_proc_t *getter; bool_t body_expected; body_expected = (prop->symbol->outer_csi->cc != csi_interface); lskip(parse); cspan = lprev_span(parse); if (prop->getter != NULL) { cspan_print(cspan); printf(" Error: Duplicate getter.\n"); parse_note_error(parse); return; } if (lcur_lc(parse) == lc_scolon) { /* Body not present */ lskip(parse); block = NULL; if (body_expected) { cspan_print(prop->name->cspan); printf(" Error: Property '"); symbol_print_fqn(prop->symbol); printf("' getter should have " "a body.\n"); parse_note_error(parse); } } else { /* Body present */ lmatch(parse, lc_is); block = parse_block(parse); lmatch(parse, lc_end); if (!body_expected) { cspan_print(prop->name->cspan); printf(" Error: Property '"); symbol_print_fqn(prop->symbol); printf("' getter declaration should " "not have a body.\n"); parse_note_error(parse); /* XXX Free block */ block = NULL; } } /* Create getter procedure */ getter = stree_proc_new(); getter->body = block; getter->outer_symbol = prop->symbol; /* Store getter in property. */ prop->getter = getter; }
/* * Parse a named policy "policy foo {...}" */ static int parse_named_policy(policy_lex_file_t *lexer) { int rcode; policy_lex_t token; char mystring[256]; policy_named_t *this; DICT_ATTR *dattr; debug_tokens("[POLICY] "); this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_NAMED_POLICY; this->item.lineno = lexer->lineno; token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); if (token != POLICY_LEX_BARE_WORD) { fprintf(stderr, "%s[%d]: Expected policy name, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } dattr = dict_attrbyname(mystring); if (dattr) { fprintf(stderr, "%s[%d]: Invalid policy name \"%s\": it is already defined as a dictionary attribute\n", lexer->filename, lexer->lineno, mystring); rlm_policy_free_item((policy_item_t *) this); return 0; } this->name = strdup(mystring); rcode = parse_block(lexer, &(this->policy)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } /* * And insert it into the tree of policies. * * For now, policy names aren't scoped, they're global. */ if (!rlm_policy_insert(lexer->policies, this)) { radlog(L_ERR, "Failed to insert policy \"%s\"", this->name); rlm_policy_free_item((policy_item_t *) this); return 0; } if ((lexer->debug & POLICY_DEBUG_PRINT_POLICY) != 0) { rlm_policy_print(this); } return 1; }
static whilestatement_t* parse_while(parser_t* p) { whilestatement_t* whilestmt = (whilestatement_t*)malloc(sizeof(whilestatement_t)); match(p, TT_WHILE); whilestmt->expression = parse_expression(p); whilestmt->block = parse_block(p); match(p, TT_END); return whilestmt; }
static int parse_file(zt_cfg_ty* cfg, FILE* file) { int c; char block[BUFMAX]; struct cfg_bvv_ty bvv; int numents = 0; int line = 1; zt_assert(cfg); memset(&bvv, '\0', sizeof(struct cfg_bvv_ty)); sprintf(block, "Global"); /* default blockname */ bvv.block = strdup(block); while ((c = fgetc(file)) != EOF) { switch (c) { case '\n': break; case '[': /* begin a block */ memset(block, '\0', BUFMAX); if (bvv.block) { free(bvv.block); bvv.block = NULL; } parse_block(file, &bvv); cfg_discard_line(file); break; case ';': /* FALL-THRU */ case '#': /* comment */ while (((c = fgetc(file)) != EOF) && (c != '\n')) { ; } break; case ' ': /* FALL-TRHU */ case '\t': /* whitespace */ cfg_discard_whitespace(file); break; default: ungetc(c, file); if (!(parse_line(file, &bvv))) { zt_log_printf(zt_log_err, "Syntax error in config file at line: %d\n", line); return -1; } cfg_insert_bvv(cfg, &bvv); free(bvv.variable); free(bvv.value); numents++; break; } /* switch */ line++; } free(bvv.block); cfg->numentries = numents; return 0; } /* parse_file */
std::vector<unsigned int> RangeParser::operator()(const std::string &s) { range = s; check_range(); ans.clear(); while (!range.empty()) { find_block(); parse_block(); } return ans; }
/** Parse @c if statement. * * @param parse Parser object. * @return New syntax tree node. */ static stree_if_t *parse_if(parse_t *parse) { stree_if_t *if_s; stree_if_clause_t *if_c; #ifdef DEBUG_PARSE_TRACE printf("Parse 'if' statement.\n"); #endif if_s = stree_if_new(); list_init(&if_s->if_clauses); /* Parse @c if clause. */ lmatch(parse, lc_if); if_c = stree_if_clause_new(); if_c->cond = parse_expr(parse); lmatch(parse, lc_then); if_c->block = parse_block(parse); list_append(&if_s->if_clauses, if_c); /* Parse @c elif clauses. */ while (lcur_lc(parse) == lc_elif) { lskip(parse); if_c = stree_if_clause_new(); if_c->cond = parse_expr(parse); lmatch(parse, lc_then); if_c->block = parse_block(parse); list_append(&if_s->if_clauses, if_c); } /* Parse @c else clause. */ if (lcur_lc(parse) == lc_else) { lskip(parse); if_s->else_block = parse_block(parse); } else { if_s->else_block = NULL; } lmatch(parse, lc_end); return if_s; }
vector<unsigned int> RP::operator()(const string &s){ range=s; check_range(); ans.clear(); while(range.size()!=0){ find_block(); parse_block(); } return ans; }
/* * 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; }
/* Parse @c with-except-finally statement. * * @param parse Parser object. * @return New syntax tree node. */ static stree_wef_t *parse_wef(parse_t *parse) { stree_wef_t *wef_s; stree_except_t *except_c; #ifdef DEBUG_PARSE_TRACE printf("Parse WEF statement.\n"); #endif wef_s = stree_wef_new(); list_init(&wef_s->except_clauses); if (lcur_lc(parse) == lc_with) { lmatch(parse, lc_with); lmatch(parse, lc_ident); lmatch(parse, lc_colon); (void) parse_texpr(parse); lmatch(parse, lc_assign); (void) parse_expr(parse); } lmatch(parse, lc_do); wef_s->with_block = parse_block(parse); while (lcur_lc(parse) == lc_except && !parse_is_error(parse)) { except_c = parse_except(parse); list_append(&wef_s->except_clauses, except_c); } if (lcur_lc(parse) == lc_finally) { lmatch(parse, lc_finally); lmatch(parse, lc_do); wef_s->finally_block = parse_block(parse); } else { wef_s->finally_block = NULL; } lmatch(parse, lc_end); return wef_s; }
struct algo *parse_procedure() { eat(PROCEDURE); eat(IDENTIFIER); char *ident = strdup(tok->val); eat(EOL); struct declarations *decls = parse_decls(); eat(BEGIN); eat(EOL); instructionlist_t block = parse_block(); eat(END); eat(ALGORITHM); eat(PROCEDURE); eat(IDENTIFIER); if (lookahead[0]->type == EOL) eat(EOL); return algo(ident, NULL, decls, block); }
/* parse_program Parses a block and matches end of program Parameters: none Return: none */ void parse_program(Tree &cst){ cst.add_branch_node("program"); parse_block(cst); if(!curr_token -> desc.compare("$")){ match("$", cst); std:: cout << "No Parse Warnings" << std::endl; } else{ std::cout << "\nParse Warning(s):\n\tMissing end_of_program - $ on line " << (--curr_token) -> line_number << std::endl << std::endl; cst.add_leaf_node("$", curr_token -> line_number); curr_token++; } }