static int lex_read_char( struct lexState *ls ) { char c = lex_next( ls ); char next = lex_next( ls ); if( c != '\'' && next == '\'' ) { ls->token.type = TK_CHAR; ls->token.string = (char*) malloc( sizeof( char ) * 2 ); sprintf( ls->token.string, "%c", c ); } else if( c == '\\' && ( next == 'n' || next == 't' ) && lex_next( ls ) == '\'' ) { ls->token.type = TK_CHAR; ls->token.string = (char*) malloc( sizeof( char ) * 2 ); switch( next ) { case 'n': ls->token.string[0] = (char)10; break; case 't': ls->token.string[0] = (char)9; break; } ls->token.string[1] = 0; } else { lex_settoken( ls, TK_ERROR, 0 ); } return ls->token.type; }
/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ static void lex_newline(LexState *ls) { LexChar old = ls->c; lua_assert(lex_iseol(ls)); lex_next(ls); /* Skip "\n" or "\r". */ if (lex_iseol(ls) && ls->c != old) lex_next(ls); /* Skip "\n\r" or "\r\n". */ if (++ls->linenumber >= LJ_MAX_LINE) lj_lex_error(ls, ls->tok, LJ_ERR_XLINES); }
struct op_s * parsei (int fd) { int op; struct op_s *prog = NULL, *ptr = NULL, *cell; while ((op = lex_next (fd)) != 0) { if (op == LOOP_END) return prog; cell = (struct op_s *)malloc (sizeof (struct op_s)); if (prog == NULL) prog = cell; else ptr->next = cell; ptr = cell; cell->opcode = op; cell->val = 1; cell->next = NULL; cell->loop = (op == LOOP_START) ? parsei (fd) : NULL; } return prog; }
// prepare the linked-list of instruction cells static instruction *parse_iter(void) { command_t op; instruction *prog = NULL, *ptr = NULL, *cell; while ((op = lex_next()) != 0) { if (op == LOOP_END) return prog; cell = (instruction *) malloc(sizeof(instruction)); if (prog == NULL) prog = cell; else ptr->next = cell; ptr = cell; cell->opcode = op; cell->value = 1; cell->next = NULL; // recursively parse loops cell->loop = (op == LOOP_START) ? parse_iter() : NULL; } return prog; }
/** Parse module. * * Parse a program module. * * The input is read using the lexer associated with @a parse. The resulting * declarations are added to existing declarations in the program associated * with @a parse. * * If any parse error occurs, parse->error will @c b_true when this function * returns. parse->error_bailout will be @c b_true if the error has not * been recovered yet. Similar holds for other parsing functions in this * module. * * @param parse Parser object. */ void parse_module(parse_t *parse) { stree_csi_t *csi; stree_enum_t *enum_d; stree_modm_t *modm; while (lcur_lc(parse) != lc_eof && !parse_is_error(parse)) { switch (lcur_lc(parse)) { case lc_class: case lc_struct: case lc_interface: csi = parse_csi(parse, lcur_lc(parse), NULL); modm = stree_modm_new(mc_csi); modm->u.csi = csi; list_append(&parse->cur_mod->members, modm); break; case lc_enum: enum_d = parse_enum(parse, NULL); modm = stree_modm_new(mc_enum); modm->u.enum_d = enum_d; list_append(&parse->cur_mod->members, modm); break; default: lunexpected_error(parse); lex_next(parse->lex); break; } } }
/** Skip to next lem. * * @param parse Parser object. */ void lskip(parse_t *parse) { #ifdef DEBUG_LPARSE_TRACE printf("lskip()\n"); #endif lex_next(parse->lex); }
/** * Determines the extent of a block. This function looks for matching braces, * ignoring braces inside quotes, comments and so forth. Returns an all-null * Source structure response to an error. */ Source lex_block(Source *in) { char const *start; Token token; Source out = *in; Source null = {{0}}; int depth = 1; /* Find the opening brace: */ token = lex_next(&start, &in->cursor, in->data.end); if (token != LEX_BRACE_L) return null; out.cursor = in->cursor; /* Find the ending brace: */ do { start = in->cursor; token = lex(&in->cursor, in->data.end); if (token == LEX_BRACE_L) ++depth; if (token == LEX_BRACE_R) --depth; } while (token != LEX_END && depth); if (token == LEX_END) return null; out.data.end = start; return out; }
// scan through whitespace static void scan_whitespace(Lexer *l) { char c; for (; (c = lex_current(l)), !lex_eof(l); lex_next(l)) { if (!is_whitespace(c)) { break; } } }
/* wrapper upon nid generation functions depending on value of "p" */ t_prefix nid_generate(t_prefix p1, t_prefix p2, fnumber p) { if (!p.getx()) return lex_next(p1, p2); else if (p.getx()==1 && p.gety()==2) return lex_middle(p1, p2); else return lex_between(p1, p2, p); }
static int testnext(ktap_lexstate *ls, int c) { if (ls->t.token == c) { lex_next(ls); return 1; } else return 0; }
static ktap_string *str_checkname(ktap_lexstate *ls) { ktap_string *ts; check(ls, TK_NAME); ts = ls->t.seminfo.ts; lex_next(ls); return ts; }
static Tstring *str_checkname(LexState *ls) { Tstring *ts; check(ls, TK_NAME); ts = ls->t.seminfo.ts; lex_next(ls); return ts; }
static int recv_greeting(req_t *req) { /* Performs the initial handshake with the client * (SOMEDAY including authentication & encryption, if needed). * Returns 0 if the greeting is valid, or -1 on error. */ int n; char buf[MAX_SOCK_LINE]; Lex l; int done = 0; int tok; assert(req->sd >= 0); if ((n = read_line(req->sd, buf, sizeof(buf))) < 0) { log_msg(LOG_NOTICE, "Unable to read greeting from <%s:%d>: %s", req->fqdn, req->port, strerror(errno)); return(-1); } else if (n == 0) { log_msg(LOG_NOTICE, "Connection terminated by <%s:%d>", req->fqdn, req->port); return(-1); } DPRINTF((5, "Received greeting: %s", buf)); l = lex_create(buf, proto_strs); while (!done) { tok = lex_next(l); switch(tok) { case CONMAN_TOK_HELLO: parse_greeting(l, req); break; case LEX_EOF: case LEX_EOL: done = 1; break; default: break; } } lex_destroy(l); /* Validate greeting. */ if (!req->user) { req->user = create_string("unknown"); send_rsp(req, CONMAN_ERR_BAD_REQUEST, "Invalid greeting: no user specified"); return(-1); } /* Send response to greeting. */ return(send_rsp(req, CONMAN_ERR_NONE, NULL)); }
/* get the next useful token, filtering out useless tokens like whitespace, newline and comments. */ void parse_next(ParseState* ps) { if (parse_hasError(ps)) return; token_t tok = TK_NONE; do { tok = lex_next(ps->ls); //lex_debugPrintToken(ps->ls, tok); } while (ps->ls->in_comment || tok == TK_WHITESPACE || tok == TK_NEWLINE); ps->token = tok; }
static void parse_cmd_opts(Lex l, req_t *req) { /* Parses the command options for the given request. */ int done = 0; int tok; char *str; while (!done) { tok = lex_next(l); switch(tok) { case CONMAN_TOK_CONSOLE: if ((lex_next(l) == '=') && (lex_next(l) == LEX_STR) && (*lex_text(l) != '\0')) { str = lex_decode(create_string(lex_text(l))); list_append(req->consoles, str); } break; case CONMAN_TOK_OPTION: if (lex_next(l) == '=') { if (lex_next(l) == CONMAN_TOK_BROADCAST) req->enableBroadcast = 1; else if (lex_prev(l) == CONMAN_TOK_FORCE) req->enableForce = 1; else if (lex_prev(l) == CONMAN_TOK_JOIN) req->enableJoin = 1; else if (lex_prev(l) == CONMAN_TOK_QUIET) req->enableQuiet = 1; else if (lex_prev(l) == CONMAN_TOK_REGEX) req->enableRegex = 1; } break; case LEX_EOF: case LEX_EOL: done = 1; break; default: break; } } return; }
static js_token_t *next(grammar_t *gmr) { if (gmr->listLen) { gmr->listLen--; js_token_t *removed = gmr->next; gmr->next = removed->next; return removed; } else { js_token_t *ret = lex_next(gmr->lex); return ret; } }
static int recv_req(req_t *req) { /* Receives the request from the client after the greeting has completed. * Returns 0 if the request is read OK, or -1 on error. */ int n; char buf[MAX_SOCK_LINE]; Lex l; int done = 0; int tok; assert(req->sd >= 0); if ((n = read_line(req->sd, buf, sizeof(buf))) < 0) { log_msg(LOG_NOTICE, "Unable to read request from <%s:%d>: %s", req->fqdn, req->port, strerror(errno)); return(-1); } else if (n == 0) { log_msg(LOG_NOTICE, "Connection terminated by <%s:%d>", req->fqdn, req->port); return(-1); } DPRINTF((5, "Received request: %s", buf)); l = lex_create(buf, proto_strs); while (!done) { tok = lex_next(l); switch(tok) { case CONMAN_TOK_CONNECT: req->command = CONMAN_CMD_CONNECT; parse_cmd_opts(l, req); break; case CONMAN_TOK_MONITOR: req->command = CONMAN_CMD_MONITOR; parse_cmd_opts(l, req); break; case CONMAN_TOK_QUERY: req->command = CONMAN_CMD_QUERY; parse_cmd_opts(l, req); break; case LEX_EOF: case LEX_EOL: done = 1; break; default: break; } } lex_destroy(l); return(0); }
/** Initialize parser object. * * Set up parser @a parse to use lexer @a lex for input and to store * output (i.e. new declarations) to program @a prog. @a prog is not * necessarily empty, the declarations being parsed are simply added * to it. * * @param parse Parser object. * @param prog Destination program stree. * @param lex Input lexer. */ void parse_init(parse_t *parse, stree_program_t *prog, struct lex *lex) { parse->program = prog; parse->cur_mod = parse->program->module; parse->lex = lex; parse->error = b_false; parse->error_bailout = b_false; lex_next(parse->lex); }
static int lex_read_string( struct lexState *ls ) { char tmp[STRING_MAX_LEN + 1]; size_t pos = 0; char c = lex_next( ls ); char prev_c = 0; while( c != '\n' && c != '"' && pos < STRING_MAX_LEN ) { if( ( c == 'n' || c == 't' ) && prev_c == '\\' ) { switch( c ) { case 'n': tmp[pos-1] = (char)10; break; case 't': tmp[pos-1] = (char)9; break; } } else { tmp[pos++] = c; } prev_c = c; c = lex_next( ls ); } if( pos >= STRING_MAX_LEN ) { lex_settoken( ls, TK_ERROR, 0 ); } else { tmp[pos] = 0; lex_settoken( ls, TK_STRING, tmp ); } return ls->token.type; }
static int lex_read_number( struct lexState *ls, char c ) { char tmp[NUMBER_MAX_LEN + 1]; size_t pos = 0; int dot_flag = 0; /* to identify float number */ do { tmp[pos++] = c; c = lex_next( ls ); if( !dot_flag && c == '.' ) { dot_flag = 1; tmp[pos++] = c; c = lex_next( ls ); } }while( isdigit( c ) && pos < NUMBER_MAX_LEN ); lex_back( ls ); tmp[pos] = 0; lex_settoken( ls, dot_flag ? TK_FLOAT : TK_NUM, tmp ); return ls->token.type; }
static void parse_greeting(Lex l, req_t *req) { /* Parses the "HELLO" command from the client: * HELLO USER='******' TTY='<str>' */ int done = 0; int tok; while (!done) { tok = lex_next(l); switch(tok) { case CONMAN_TOK_USER: if ((lex_next(l) == '=') && (lex_next(l) == LEX_STR) && (*lex_text(l) != '\0')) { if (req->user) free(req->user); req->user = lex_decode(create_string(lex_text(l))); } break; case CONMAN_TOK_TTY: if ((lex_next(l) == '=') && (lex_next(l) == LEX_STR) && (*lex_text(l) != '\0')) { if (req->tty) free(req->tty); req->tty = lex_decode(create_string(lex_text(l))); } break; case LEX_EOF: case LEX_EOL: done = 1; break; default: break; } } return; }
static int lex_read_id( struct lexState *ls, char c ) { char tmp[ID_MAX_LEN + 1]; size_t pos = 0; do { tmp[pos++] = c; c = lex_next( ls ); }while( isdigit( c ) || isalpha( c ) || c == '_' ); lex_back( ls ); tmp[pos] = 0; lex_settoken( ls, TK_ID, tmp ); return ls->token.type; }
void lex_parse_test(char *buf, char *toks[]) { Lex l; int tok; int newline = 1; if (!buf || !(l = lex_create(buf, toks))) return; while ((tok = lex_next(l)) != LEX_EOF) { assert(lex_prev(l) == tok); if (newline) { printf("%3d: ", lex_line(l)); newline = 0; } switch(tok) { case LEX_ERR: printf("ERR\n"); newline = 1; break; case LEX_EOL: printf("EOL\n"); newline = 1; break; case LEX_INT: printf("INT(%d) ", atoi(lex_text(l))); break; case LEX_STR: printf("STR(%s) ", lex_text(l)); break; default: if (tok < LEX_TOK_OFFSET) printf("CHR(%c) ", lex_text(l)[0]); else if (toks) printf("TOK(%d:%s) ", tok, toks[LEX_UNTOK(tok)]); else printf("\nINTERNAL ERROR: line=%d, tok=%d, str=\"%s\"\n", lex_line(l), lex_prev(l), lex_text(l)); break; } } lex_destroy(l); return; }
static void *parse_config(struct parser *parser) { struct lexeme *lexeme; while (lex_next(&parser->lexer, &lexeme)) { switch (lexeme->type) { case LEXEME_EQUAL: return parse_key_value; case LEXEME_OPEN_BRACKET: return parse_section; case LEXEME_LINEFEED: if (parser->buffer.population) return parse_section_shorthand; return parse_config; case LEXEME_STRING: lexeme_buffer_emit(&parser->buffer, lexeme); break; case LEXEME_CLOSE_BRACKET: { struct config_line line = { .type = CONFIG_LINE_TYPE_SECTION_END }; config_buffer_emit(&parser->items, &line); return parse_config; } case LEXEME_EOF: return NULL; default: lwan_status_error("Unexpected lexeme type: %s", lexeme_type_str[lexeme->type]); return NULL; } } return NULL; }
size_t lex_keyword(Lexer *l) { enum { kKwExprFunc }; char c; for (size_t i = 0; (c = lex_current(l)), !lex_eof(l); i++, lex_next(l)) { if (c >= 'a' && c <= 'z') { // keywords are always lowercase alphabetics } else if (c == ' ') { // proper end of a keyword char *s[] = {"var", "func"}; Keyword k[] = {kKeywordVar, kKeywordFunc}; for (size_t j = 0; j < sizeof(k) / sizeof(Keyword); j++) { if (memcmp(&l->input[-i], s[j], i) == 0) { // found keyword scan_whitespace(l); lex_emit(l, (Token){ .type = kTokenTypeKeyword, .keyword = k[j], }); return kKwExprFunc; } }
static void checknext(ktap_lexstate *ls, int c) { check(ls, c); lex_next(ls); }
/** Parse class, struct or interface member. * * @param parse Parser object. * @param outer_csi CSI containing this declaration. * @return New syntax tree node. In case of parse error, * @c NULL may (but need not) be returned. */ static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi) { stree_csimbr_t *csimbr; stree_csi_t *csi; stree_ctor_t *ctor; stree_deleg_t *deleg; stree_enum_t *enum_d; stree_fun_t *fun; stree_var_t *var; stree_prop_t *prop; csimbr = NULL; switch (lcur_lc(parse)) { case lc_class: case lc_struct: case lc_interface: csi = parse_csi(parse, lcur_lc(parse), outer_csi); if (csi != NULL) { csimbr = stree_csimbr_new(csimbr_csi); csimbr->u.csi = csi; } break; case lc_new: ctor = parse_ctor(parse, outer_csi); if (ctor != NULL) { csimbr = stree_csimbr_new(csimbr_ctor); csimbr->u.ctor = ctor; } break; case lc_deleg: deleg = parse_deleg(parse, outer_csi); if (deleg != NULL) { csimbr = stree_csimbr_new(csimbr_deleg); csimbr->u.deleg = deleg; } break; case lc_enum: enum_d = parse_enum(parse, outer_csi); if (enum_d != NULL) { csimbr = stree_csimbr_new(csimbr_enum); csimbr->u.enum_d = enum_d; } break; case lc_fun: fun = parse_fun(parse, outer_csi); csimbr = stree_csimbr_new(csimbr_fun); csimbr->u.fun = fun; break; case lc_var: var = parse_var(parse, outer_csi); if (var != NULL) { csimbr = stree_csimbr_new(csimbr_var); csimbr->u.var = var; } break; case lc_prop: prop = parse_prop(parse, outer_csi); csimbr = stree_csimbr_new(csimbr_prop); csimbr->u.prop = prop; break; default: lunexpected_error(parse); lex_next(parse->lex); break; } return csimbr; }
token * lex_next(lexer * lex) { switch(lex->state) { case LEX_DEF: _lex_adv(lex); if(EOF == lex->current_char) { return lex_next(_lex_set_state(lex, LEX_DONE)); } else if(_is_int(lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_IN_INT)); } else if(_is_space(lex->current_char)) { return lex_next(lex); } else if(_is_str_end(lex->current_char)) { return lex_next(_lex_adv(_lex_set_state(lex, LEX_IN_STR))); } else if(_is_id_start(lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_IN_ID)); } else if(_is_ctrl_char(lex->current_char)) { return _token_ctrl_char(lex->current_char); } else { return lex_next(_lex_set_state(lex, LEX_ERR)); } case LEX_IN_INT: if(_is_int(lex->current_char)) { if(0 == str_add(lex->tok_buf, lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_ERR)); } return lex_next(_lex_adv(lex)); } return _tok_new(lex, TOK_INT, LEX_DEF); case LEX_IN_ID: if(_is_id(lex->current_char)) { if(0 == str_add(lex->tok_buf, lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_ERR)); } return lex_next(_lex_adv(lex)); } if(_is_keyword(lex->tok_buf)) { return _tok_new(lex, TOK_KEY, LEX_DEF); } return _tok_new(lex, TOK_ID, LEX_DEF); case LEX_IN_STR: if(!_is_str_end(lex->current_char)) { if(_is_escape(lex->current_char)) { return lex_next(_lex_adv(_lex_set_state(lex, LEX_IN_ESC))); } if(0 == str_add(lex->tok_buf, lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_ERR)); } return lex_next(_lex_adv(lex)); } return _tok_new(lex, TOK_STR, LEX_DEF); case LEX_IN_ESC: if(_is_escapable(lex->current_char)) { _lex_set_char(lex, _make_escape(lex->current_char)); if(0 == str_add(lex->tok_buf, lex->current_char)) { return lex_next(_lex_set_state(lex, LEX_ERR)); } return lex_next(_lex_adv(_lex_set_state(lex, LEX_IN_STR))); } return lex_next(_lex_set_state(lex, LEX_ERR)); case LEX_ERR: return _tok_new(lex, TOK_ERR, LEX_DEF); case LEX_DONE: default: return _tok_new(lex, TOK_EOF, LEX_DONE); } }
static void checknext (LexState *ls, int c) { check(ls, c); lex_next(ls); }
/* Save previous character and get next character. */ static LJ_AINLINE LexChar lex_savenext(LexState *ls) { lex_save(ls, ls->c); return lex_next(ls); }