static bool replace_comment_by_newline (void) { ecma_char_t c = LA (0); bool multiline; bool was_newlines = false; JERRY_ASSERT (LA (0) == '/'); JERRY_ASSERT (LA (1) == '/' || LA (1) == '*'); multiline = (LA (1) == '*'); consume_char (); consume_char (); while (true) { c = LA (0); if (!multiline && (c == '\n' || c == '\0')) { return false; } if (multiline && c == '*' && LA (1) == '/') { consume_char (); consume_char (); if (was_newlines) { return true; } else { return false; } } if (multiline && c == '\n') { was_newlines = true; } if (multiline && c == '\0') { PARSE_ERROR ("Unclosed multiline comment", buffer - buffer_start); } consume_char (); } }
void VLogLexer::do_things() { consume_char(); lex_state = is_kwid_char(current_char) ? LEX_KWID : LEX_NON_KWID; if(eof) return; while(next_token()); }
static void name(parser_context *context, step *name_step) { enter_state(context, ST_NAME); size_t offset = context->cursor; while(offset < context->length) { if('.' == context->input[offset] || '[' == context->input[offset]) { break; } offset++; } while(isspace(context->input[offset - 1])) { offset--; } bool quoted = false; if('\'' == get_char(context) && '\'' == context->input[offset - 1]) { consume_char(context); offset--; quoted = true; } name_step->test.name.length = offset - context->cursor; if(0 == name_step->test.name.length) { context->result.code = ERR_EXPECTED_NAME_CHAR; return; } name_step->test.name.value = (uint8_t *)calloc(1, name_step->test.name.length); if(NULL == name_step->test.name.value) { context->result.code = ERR_PARSER_OUT_OF_MEMORY; return; } memcpy(name_step->test.name.value, context->input + context->cursor, name_step->test.name.length); consume_chars(context, name_step->test.name.length); if(quoted) { consume_char(context); } skip_ws(context); }
static void grobble_whitespaces (void) { ecma_char_t c = LA (0); while ((isspace (c) && c != '\n')) { consume_char (); c = LA (0); } }
static void abbreviated_relative_path(parser_context *context) { enter_state(context, ST_ABBREVIATED_RELATIVE_PATH); size_t mark = context->cursor; skip_ws(context); if('.' != get_char(context)) { unexpected_value(context, '.'); return; } consume_char(context); skip_ws(context); if('.' != get_char(context)) { unexpected_value(context, '.'); reset(context, mark); return; } consume_char(context); context->current_step_kind = RECURSIVE; relative_path(context); }
static void wildcard_name(parser_context *context) { enter_state(context, ST_WILDCARD_NAME_TEST); step *current = make_step(context->current_step_kind, WILDCARD_TEST); if(NULL == current) { context->result.code = ERR_PARSER_OUT_OF_MEMORY; return; } push_step(context, current); consume_char(context); context->result.code = JSONPATH_SUCCESS; }
static FcBool expect_char (FcFormatContext *c, FcChar8 term) { FcBool res = consume_char (c, term); if (!res) { if (c->format == c->format_orig + c->format_len) message ("format ended while expecting '%c'", term); else message ("expected '%c' at %d", term, c->format - c->format_orig + 1); } return res; }
static void wildcard_predicate(parser_context *context) { enter_state(context, ST_WILDCARD_PREDICATE); skip_ws(context); if('*' == get_char(context)) { context->result.code = JSONPATH_SUCCESS; consume_char(context); add_predicate(context, WILDCARD); } else { unexpected_value(context, '*'); } }
static void qualified_path(parser_context *context) { enter_state(context, ST_QUALIFIED_PATH); skip_ws(context); abbreviated_relative_path(context); skip_ws(context); if(JSONPATH_SUCCESS == context->result.code || !has_more_input(context)) { return; } else if('.' == get_char(context)) { consume_char(context); context->current_step_kind = SINGLE; relative_path(context); } else { unexpected_value(context, '.'); } }
bool VLogLexer::next_token() { bool whitespace; bool kwid_char; bool seen_match; unsigned int current_match; while(true) { switch(lex_state) { case LEX_KWID: seen_match = false; for(int i = 0;i < num_token_mappings; ++i) { if(live_token_mappings[i]) { char token_char = token_mapping_table[i].str[token_buf_pos]; if(current_char == token_char) { if(token_mapping_table[i].str[token_buf_pos + 1] == 0) { seen_match = true; current_match = i; } } else { live_token_mappings[i] = false; } } } break; case LEX_NON_KWID: switch(current_char) { case '@': emit_token(TOKEN_AT); break; case '(': emit_token(TOKEN_LBRACKET); break; case ')': emit_token(TOKEN_RBRACKET); break; case '[': emit_token(TOKEN_LSQBRACKET); break; case ']': emit_token(TOKEN_RSQBRACKET); break; case '{': emit_token(TOKEN_LBRACE); break; case '}': emit_token(TOKEN_RBRACE); break; case '>': lex_state = LEX_GT; break; case '<': lex_state = LEX_LT; break; case ',': emit_token(TOKEN_COMMA); break; case ';': emit_token(TOKEN_SEMICOLON); break; case '=': emit_token(TOKEN_EQ); break; default: throw TokenErr("Unexpected character", line_char, current_line); break; } break; } if(lex_state == LEX_KWID) { token_buffer[token_buf_pos] = current_char; token_buf_pos++; } whitespace = consume_char(); kwid_char = is_kwid_char(current_char); if(lex_state == LEX_KWID) { if(whitespace || !kwid_char) { if(seen_match) { emit_token(token_mapping_table[current_match].type); } else { emit_token(TOKEN_ID); } lex_state = kwid_char ? LEX_KWID : LEX_NON_KWID; return !eof; } } else { lex_state = kwid_char ? LEX_KWID : LEX_NON_KWID; return !eof; } } }
/** * Parse string literal (ECMA-262 v5, 7.8.5) */ static token parse_regexp (void) { token result; bool is_char_class = false; /* Eat up '/' */ JERRY_ASSERT ((ecma_char_t) LA (0) == '/'); consume_char (); new_token (); while (true) { ecma_char_t c = (ecma_char_t) LA (0); if (c == '\0') { PARSE_ERROR ("Unclosed string", token_start - buffer_start); } else if (c == '\n') { PARSE_ERROR ("RegExp literal shall not contain newline character", token_start - buffer_start); } else if (c == '\\') { consume_char (); } else if (c == '[') { is_char_class = true; } else if (c == ']') { is_char_class = false; } else if (c == '/' && !is_char_class) { /* Eat up '/' */ consume_char (); break; } consume_char (); } /* Try to parse RegExp flags */ while (true) { ecma_char_t c = (ecma_char_t) LA (0); if (c == '\0' || !ecma_char_is_word_char (c) || ecma_char_is_line_terminator (c)) { break; } consume_char (); } result = convert_string_to_token (TOK_REGEXP, (const lit_utf8_byte_t *) token_start, static_cast<ecma_length_t> (buffer - token_start)); token_start = NULL; return result; } /* parse_regexp */
/* In this function we cannot use strtol function since there is no octal literals in ECMAscript. */ static token parse_number (void) { ecma_char_t c = LA (0); bool is_hex = false; bool is_fp = false; bool is_exp = false; bool is_overflow = false; ecma_number_t fp_res = .0; size_t tok_length = 0, i; uint32_t res = 0; token known_token; JERRY_ASSERT (isdigit (c) || c == '.'); if (c == '0') { if (LA (1) == 'x' || LA (1) == 'X') { is_hex = true; } } if (c == '.') { JERRY_ASSERT (!isalpha (LA (1))); is_fp = true; } if (is_hex) { // Eat up '0x' consume_char (); consume_char (); new_token (); while (true) { c = LA (0); if (!isxdigit (c)) { break; } consume_char (); } if (isalpha (c) || c == '_' || c == '$') { PARSE_ERROR ("Integer literal shall not contain non-digit characters", buffer - buffer_start); } tok_length = (size_t) (buffer - token_start); for (i = 0; i < tok_length; i++) { if (!is_overflow) { res = (res << 4) + ecma_char_hex_to_int (token_start[i]); } else { fp_res = fp_res * 16 + (ecma_number_t) ecma_char_hex_to_int (token_start[i]); } if (res > 255) { fp_res = (ecma_number_t) res; is_overflow = true; res = 0; } } if (is_overflow) { known_token = convert_seen_num_to_token (fp_res); token_start = NULL; return known_token; } else { known_token = create_token (TOK_SMALL_INT, (uint8_t) res); token_start = NULL; return known_token; } } JERRY_ASSERT (!is_hex && !is_exp); new_token (); // Eat up '.' if (is_fp) { consume_char (); } while (true) { c = LA (0); if (is_fp && c == '.') { FIXME (/* This is wrong: 1..toString (). */) PARSE_ERROR ("Integer literal shall not contain more than one dot character", buffer - buffer_start); } if (is_exp && (c == 'e' || c == 'E')) { PARSE_ERROR ("Integer literal shall not contain more than exponential marker ('e' or 'E')", buffer - buffer_start); } if (c == '.') { if (isalpha (LA (1)) || LA (1) == '_' || LA (1) == '$') { PARSE_ERROR ("Integer literal shall not contain non-digit character after got character", buffer - buffer_start); } is_fp = true; consume_char (); continue; } if (c == 'e' || c == 'E') { if (LA (1) == '-' || LA (1) == '+') { consume_char (); } if (!isdigit (LA (1))) { PARSE_ERROR ("Integer literal shall not contain non-digit character after exponential marker ('e' or 'E')", buffer - buffer_start); } is_exp = true; consume_char (); continue; } if (isalpha (c) || c == '_' || c == '$') { PARSE_ERROR ("Integer literal shall not contain non-digit characters", buffer - buffer_start); } if (!isdigit (c)) { break; } consume_char (); } tok_length = (size_t) (buffer - token_start); if (is_fp || is_exp) { ecma_number_t res = ecma_utf8_string_to_number (token_start, (jerry_api_size_t) tok_length); JERRY_ASSERT (!ecma_number_is_nan (res)); known_token = convert_seen_num_to_token (res); token_start = NULL; return known_token; } if (*token_start == '0' && tok_length != 1) { if (strict_mode) { PARSE_ERROR ("Octal tnteger literals are not allowed in strict mode", token_start - buffer_start); } for (i = 0; i < tok_length; i++) { if (!is_overflow) { res = res * 8 + ecma_char_hex_to_int (token_start[i]); } else { fp_res = fp_res * 8 + (ecma_number_t) ecma_char_hex_to_int (token_start[i]); } if (res > 255) { fp_res = (ecma_number_t) res; is_overflow = true; res = 0; } } } else { for (i = 0; i < tok_length; i++) { if (!is_overflow) { res = res * 10 + ecma_char_hex_to_int (token_start[i]); } else { fp_res = fp_res * 10 + (ecma_number_t) ecma_char_hex_to_int (token_start[i]); } if (res > 255) { fp_res = (ecma_number_t) res; is_overflow = true; res = 0; } } } if (is_overflow) { known_token = convert_seen_num_to_token (fp_res); token_start = NULL; return known_token; } else { known_token = create_token (TOK_SMALL_INT, (uint8_t) res); token_start = NULL; return known_token; } }
/** * Parse identifier (ECMA-262 v5, 7.6) or keyword (7.6.1.1) */ static token parse_name (void) { ecma_char_t c = (ecma_char_t) LA (0); token known_token = empty_token; JERRY_ASSERT (isalpha (c) || c == '$' || c == '_'); new_token (); while (true) { c = (ecma_char_t) LA (0); if (!isalpha (c) && !isdigit (c) && c != '$' && c != '_' && c != '\\') { break; } else { consume_char (); if (c == '\\') { bool is_correct_sequence = (LA (0) == 'u'); if (is_correct_sequence) { consume_char (); } for (uint32_t i = 0; is_correct_sequence && i < 4; i++) { if (!isxdigit (LA (0))) { is_correct_sequence = false; break; } consume_char (); } if (!is_correct_sequence) { PARSE_ERROR ("Malformed escape sequence", token_start - buffer_start); } } } } known_token = convert_string_to_token_transform_escape_seq (TOK_NAME, token_start, (size_t) (buffer - token_start)); token_start = NULL; return known_token; } /* parse_name */
static token lexer_next_token_private (void) { ecma_char_t c = LA (0); JERRY_ASSERT (token_start == NULL); if (isalpha (c) || c == '$' || c == '_') { return parse_name (); } if (isdigit (c) || (c == '.' && isdigit (LA (1)))) { return parse_number (); } if (c == '\n') { consume_char (); return create_token (TOK_NEWLINE, 0); } if (c == '\0') { return create_token (TOK_EOF, 0); } if (c == '\'' || c == '"') { return parse_string (); } if (isspace (c)) { grobble_whitespaces (); return lexer_next_token_private (); } if (c == '/' && LA (1) == '*') { if (replace_comment_by_newline ()) { token ret; ret.type = TOK_NEWLINE; ret.uid = 0; return ret; } else { return lexer_next_token_private (); } } if (c == '/') { if (LA (1) == '/') { replace_comment_by_newline (); return lexer_next_token_private (); } else if (!(sent_token.type == TOK_NAME || sent_token.type == TOK_NULL || sent_token.type == TOK_BOOL || sent_token.type == TOK_CLOSE_BRACE || sent_token.type == TOK_CLOSE_SQUARE || sent_token.type == TOK_CLOSE_PAREN || sent_token.type == TOK_SMALL_INT || sent_token.type == TOK_NUMBER || sent_token.type == TOK_STRING || sent_token.type == TOK_REGEXP)) { return parse_regexp (); } } switch (c) { case '{': RETURN_PUNC (TOK_OPEN_BRACE); break; case '}': RETURN_PUNC (TOK_CLOSE_BRACE); break; case '(': RETURN_PUNC (TOK_OPEN_PAREN); break; case ')': RETURN_PUNC (TOK_CLOSE_PAREN); break; case '[': RETURN_PUNC (TOK_OPEN_SQUARE); break; case ']': RETURN_PUNC (TOK_CLOSE_SQUARE); break; case '.': RETURN_PUNC (TOK_DOT); break; case ';': RETURN_PUNC (TOK_SEMICOLON); break; case ',': RETURN_PUNC (TOK_COMMA); break; case '~': RETURN_PUNC (TOK_COMPL); break; case ':': RETURN_PUNC (TOK_COLON); break; case '?': RETURN_PUNC (TOK_QUERY); break; case '*': IF_LA_IS ('=', TOK_MULT_EQ, TOK_MULT); break; case '/': IF_LA_IS ('=', TOK_DIV_EQ, TOK_DIV); break; case '^': IF_LA_IS ('=', TOK_XOR_EQ, TOK_XOR); break; case '%': IF_LA_IS ('=', TOK_MOD_EQ, TOK_MOD); break; case '+': IF_LA_IS_OR ('+', TOK_DOUBLE_PLUS, '=', TOK_PLUS_EQ, TOK_PLUS); break; case '-': IF_LA_IS_OR ('-', TOK_DOUBLE_MINUS, '=', TOK_MINUS_EQ, TOK_MINUS); break; case '&': IF_LA_IS_OR ('&', TOK_DOUBLE_AND, '=', TOK_AND_EQ, TOK_AND); break; case '|': IF_LA_IS_OR ('|', TOK_DOUBLE_OR, '=', TOK_OR_EQ, TOK_OR); break; case '<': { switch (LA (1)) { case '<': IF_LA_N_IS ('=', TOK_LSHIFT_EQ, TOK_LSHIFT, 2); break; case '=': RETURN_PUNC_EX (TOK_LESS_EQ, 2); break; default: RETURN_PUNC (TOK_LESS); } break; } case '>': { switch (LA (1)) { case '>': { switch (LA (2)) { case '>': IF_LA_N_IS ('=', TOK_RSHIFT_EX_EQ, TOK_RSHIFT_EX, 3); break; case '=': RETURN_PUNC_EX (TOK_RSHIFT_EQ, 3); break; default: RETURN_PUNC_EX (TOK_RSHIFT, 2); } break; } case '=': RETURN_PUNC_EX (TOK_GREATER_EQ, 2); break; default: RETURN_PUNC (TOK_GREATER); } break; } case '=': { if (LA (1) == '=') { IF_LA_N_IS ('=', TOK_TRIPLE_EQ, TOK_DOUBLE_EQ, 2); } else { RETURN_PUNC (TOK_EQ); } break; } case '!': { if (LA (1) == '=') { IF_LA_N_IS ('=', TOK_NOT_DOUBLE_EQ, TOK_NOT_EQ, 2); } else { RETURN_PUNC (TOK_NOT); } break; } default: PARSE_SORRY ("Unknown character", buffer - buffer_start); } PARSE_SORRY ("Unknown character", buffer - buffer_start); }
/** * Parse string literal (ECMA-262 v5, 7.8.4) */ static token lexer_parse_string (void) { ecma_char_t c = (ecma_char_t) LA (0); JERRY_ASSERT (c == LIT_CHAR_SINGLE_QUOTE || c == LIT_CHAR_DOUBLE_QUOTE); new_token (); /* Consume quote character */ consume_char (); const ecma_char_t end_char = c; bool is_escape_sequence_occured = false; do { c = LA (0); consume_char (); if (lit_char_is_line_terminator (c)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "String literal shall not contain newline character", token_start_pos); } else if (c == LIT_CHAR_BACKSLASH) { is_escape_sequence_occured = true; ecma_char_t nc = (ecma_char_t) LA (0); consume_char (); if (nc == LIT_CHAR_CR) { nc = (ecma_char_t) LA (0); if (nc == LIT_CHAR_LF) { consume_char (); } } } } while (c != end_char && !lit_utf8_iterator_is_eos (&src_iter)); if (c == LIT_CHAR_NULL) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Unclosed string", token_start_pos); } const lit_utf8_size_t charset_size = TOK_SIZE () - 2; token ret; if (!is_escape_sequence_occured) { ret = lexer_create_token_for_charset (TOK_STRING, TOK_START () + 1, charset_size); } else { ret = lexer_create_token_for_charset_transform_escape_sequences (TOK_STRING, TOK_START () + 1, charset_size); } is_token_parse_in_progress = false; return ret; } /* lexer_parse_string */
/** * Parse string literal (ECMA-262 v5, 7.8.5) */ static token lexer_parse_regexp (void) { token result; bool is_char_class = false; JERRY_ASSERT (LA (0) == LIT_CHAR_SLASH); new_token (); /* Eat up '/' */ consume_char (); while (true) { if (lit_utf8_iterator_is_eos (&src_iter)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Unterminated RegExp literal", token_start_pos); } ecma_char_t c = (ecma_char_t) LA (0); if (lit_char_is_line_terminator (c)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "RegExp literal should not contain newline character", token_start_pos); } else if (c == LIT_CHAR_BACKSLASH) { consume_char (); if (lit_char_is_line_terminator (LA (0))) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "RegExp literal backslash sequence should not contain newline character", token_start_pos); } } else if (c == LIT_CHAR_LEFT_SQUARE) { is_char_class = true; } else if (c == LIT_CHAR_RIGHT_SQUARE) { is_char_class = false; } else if (c == LIT_CHAR_SLASH && !is_char_class) { /* Eat up '/' */ consume_char (); break; } consume_char (); } /* Try to parse RegExp flags */ while (true) { ecma_char_t c = (ecma_char_t) LA (0); if (!lit_char_is_word_char (c) || lit_char_is_line_terminator (c)) { break; } consume_char (); } result = lexer_create_token_for_charset (TOK_REGEXP, TOK_START () + 1, TOK_SIZE () - 1); is_token_parse_in_progress = false; return result; } /* lexer_parse_regexp */
static void slice_predicate(parser_context *context) { enter_state(context, ST_SLICE_PREDICATE); int_fast32_t from = INT_FAST32_MIN; int_fast32_t to = INT_FAST32_MAX; int_fast32_t extent = 1; predicate *pred = add_predicate(context, SLICE); if(!look_for(context, ":")) { parser_trace("slice: uh oh! no ':' found, aborting..."); context->result.code = ERR_UNSUPPORTED_PRED_TYPE; return; } skip_ws(context); if(isdigit(get_char(context)) || '-' == get_char(context) || '+' == get_char(context)) { parser_trace("slice: parsing from value..."); from = signed_integer(context); if(JSONPATH_SUCCESS != context->result.code) { parser_trace("slice: uh oh! couldn't parse from value, aborting..."); return; } parser_trace("slice: found from value: %d", to); pred->slice.specified |= SLICE_FROM; } else { parser_trace("slice: no from value specified"); } skip_ws(context); if(':' != get_char(context)) { parser_trace("slice: uh oh! missing ':' between from and to, aborting..."); unexpected_value(context, ':'); return; } consume_char(context); skip_ws(context); if(isdigit(get_char(context)) || '-' == get_char(context) || '+' == get_char(context)) { parser_trace("slice: parsing to value..."); to = signed_integer(context); if(JSONPATH_SUCCESS != context->result.code) { parser_trace("slice: uh oh! couldn't parse to value, aborting..."); return; } parser_trace("slice: found to value: %d", to); pred->slice.specified |= SLICE_TO; } else { parser_trace("slice: no to value specified"); } skip_ws(context); if(':' == get_char(context)) { consume_char(context); skip_ws(context); if(isdigit(get_char(context)) || '-' == get_char(context) || '+' == get_char(context)) { parser_trace("slice: parsing step value..."); extent = signed_integer(context); if(JSONPATH_SUCCESS != context->result.code) { parser_trace("slice: uh oh! couldn't parse step value, aborting..."); return; } if(0 == extent) { parser_trace("slice: uh oh! couldn't parse step value, aborting..."); context->result.code = ERR_STEP_CANNOT_BE_ZERO; return; } parser_trace("slice: found step value: %d", extent); pred->slice.specified |= SLICE_STEP; } else { parser_trace("slice: no step value specified"); } } context->result.code = JSONPATH_SUCCESS; pred->slice.from = from; pred->slice.to = to; pred->slice.step = extent; }
/** * Parse and construct lexer token * * Note: * Currently, lexer token doesn't fully correspond to Token, defined in ECMA-262, v5, 7.5. * For example, there is no new-line token type in the token definition of ECMA-262 v5. * * @return constructed token */ static token lexer_parse_token (void) { ecma_char_t c = LA (0); if (lit_char_is_white_space (c)) { while (lit_char_is_white_space (c)) { consume_char (); c = LA (0); } } if (lit_char_is_line_terminator (c)) { while (lit_char_is_line_terminator (c)) { consume_char (); c = LA (0); } return create_token (TOK_NEWLINE, 0); } JERRY_ASSERT (is_token_parse_in_progress == false); /* ECMA-262 v5, 7.6, Identifier */ if (lexer_is_char_can_be_identifier_start (c)) { return lexer_parse_identifier_or_keyword (); } /* ECMA-262 v5, 7.8.3, Numeric literal */ if (lit_char_is_decimal_digit (c) || (c == LIT_CHAR_DOT && lit_char_is_decimal_digit (LA (1)))) { return lexer_parse_number (); } if (c == LIT_CHAR_LF) { consume_char (); return create_token (TOK_NEWLINE, 0); } if (c == LIT_CHAR_NULL) { return create_token (TOK_EOF, 0); } if (c == LIT_CHAR_SINGLE_QUOTE || c == LIT_CHAR_DOUBLE_QUOTE) { return lexer_parse_string (); } /* ECMA-262 v5, 7.4, SingleLineComment or MultiLineComment */ if (c == LIT_CHAR_SLASH && (LA (1) == LIT_CHAR_SLASH || LA (1) == LIT_CHAR_ASTERISK)) { if (lexer_parse_comment ()) { return create_token (TOK_NEWLINE, 0); } else { return lexer_parse_token (); } } if (c == LIT_CHAR_SLASH && !(prev_non_lf_token.type == TOK_NAME || prev_non_lf_token.type == TOK_NULL || prev_non_lf_token.type == TOK_BOOL || prev_non_lf_token.type == TOK_CLOSE_BRACE || prev_non_lf_token.type == TOK_CLOSE_SQUARE || prev_non_lf_token.type == TOK_CLOSE_PAREN || prev_non_lf_token.type == TOK_SMALL_INT || prev_non_lf_token.type == TOK_NUMBER || prev_non_lf_token.type == TOK_STRING || prev_non_lf_token.type == TOK_REGEXP)) { return lexer_parse_regexp (); } /* ECMA-262 v5, 7.7, Punctuator */ switch (c) { case LIT_CHAR_LEFT_BRACE: { RETURN_PUNC (TOK_OPEN_BRACE); break; } case LIT_CHAR_RIGHT_BRACE: { RETURN_PUNC (TOK_CLOSE_BRACE); break; } case LIT_CHAR_LEFT_PAREN: { RETURN_PUNC (TOK_OPEN_PAREN); break; } case LIT_CHAR_RIGHT_PAREN: { RETURN_PUNC (TOK_CLOSE_PAREN); break; } case LIT_CHAR_LEFT_SQUARE: { RETURN_PUNC (TOK_OPEN_SQUARE); break; } case LIT_CHAR_RIGHT_SQUARE: { RETURN_PUNC (TOK_CLOSE_SQUARE); break; } case LIT_CHAR_DOT: { RETURN_PUNC (TOK_DOT); break; } case LIT_CHAR_SEMICOLON: { RETURN_PUNC (TOK_SEMICOLON); break; } case LIT_CHAR_COMMA: { RETURN_PUNC (TOK_COMMA); break; } case LIT_CHAR_TILDE: { RETURN_PUNC (TOK_COMPL); break; } case LIT_CHAR_COLON: { RETURN_PUNC (TOK_COLON); break; } case LIT_CHAR_QUESTION: { RETURN_PUNC (TOK_QUERY); break; } case LIT_CHAR_ASTERISK: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_MULT_EQ, TOK_MULT); break; } case LIT_CHAR_SLASH: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_DIV_EQ, TOK_DIV); break; } case LIT_CHAR_CIRCUMFLEX: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_XOR_EQ, TOK_XOR); break; } case LIT_CHAR_PERCENT: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_MOD_EQ, TOK_MOD); break; } case LIT_CHAR_PLUS: { IF_LA_IS_OR (LIT_CHAR_PLUS, TOK_DOUBLE_PLUS, LIT_CHAR_EQUALS, TOK_PLUS_EQ, TOK_PLUS); break; } case LIT_CHAR_MINUS: { IF_LA_IS_OR (LIT_CHAR_MINUS, TOK_DOUBLE_MINUS, LIT_CHAR_EQUALS, TOK_MINUS_EQ, TOK_MINUS); break; } case LIT_CHAR_AMPERSAND: { IF_LA_IS_OR (LIT_CHAR_AMPERSAND, TOK_DOUBLE_AND, LIT_CHAR_EQUALS, TOK_AND_EQ, TOK_AND); break; } case LIT_CHAR_VLINE: { IF_LA_IS_OR (LIT_CHAR_VLINE, TOK_DOUBLE_OR, LIT_CHAR_EQUALS, TOK_OR_EQ, TOK_OR); break; } case LIT_CHAR_LESS_THAN: { switch (LA (1)) { case LIT_CHAR_LESS_THAN: IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_LSHIFT_EQ, TOK_LSHIFT, 2); break; case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_LESS_EQ, 2); break; default: RETURN_PUNC (TOK_LESS); } break; } case LIT_CHAR_GREATER_THAN: { switch (LA (1)) { case LIT_CHAR_GREATER_THAN: { switch (LA (2)) { case LIT_CHAR_GREATER_THAN: IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_RSHIFT_EX_EQ, TOK_RSHIFT_EX, 3); break; case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_RSHIFT_EQ, 3); break; default: RETURN_PUNC_EX (TOK_RSHIFT, 2); } break; } case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_GREATER_EQ, 2); break; default: RETURN_PUNC (TOK_GREATER); } break; } case LIT_CHAR_EQUALS: { if (LA (1) == LIT_CHAR_EQUALS) { IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_TRIPLE_EQ, TOK_DOUBLE_EQ, 2); } else { RETURN_PUNC (TOK_EQ); } break; } case LIT_CHAR_EXCLAMATION: { if (LA (1) == LIT_CHAR_EQUALS) { IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_NOT_DOUBLE_EQ, TOK_NOT_EQ, 2); } else { RETURN_PUNC (TOK_NOT); } break; } } PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Illegal character", lit_utf8_iterator_get_pos (&src_iter)); } /* lexer_parse_token */
/** * Parse Identifier (ECMA-262 v5, 7.6) or ReservedWord (7.6.1; 7.8.1; 7.8.2). * * @return TOK_NAME - for Identifier, * TOK_KEYWORD - for Keyword or FutureReservedWord, * TOK_NULL - for NullLiteral, * TOK_BOOL - for BooleanLiteral */ static token lexer_parse_identifier_or_keyword (void) { ecma_char_t c = LA (0); JERRY_ASSERT (lexer_is_char_can_be_identifier_start (c)); new_token (); bool is_correct_identifier_name = true; bool is_escape_sequence_occured = false; bool is_all_chars_were_lowercase_ascii = true; while (true) { c = LA (0); if (c == LIT_CHAR_BACKSLASH) { consume_char (); is_escape_sequence_occured = true; bool is_unicode_escape_sequence = (LA (0) == LIT_CHAR_LOWERCASE_U); consume_char (); if (is_unicode_escape_sequence) { /* UnicodeEscapeSequence */ if (!lexer_convert_escape_sequence_digits_to_char (&src_iter, true, &c)) { is_correct_identifier_name = false; break; } else { /* c now contains character, encoded in the UnicodeEscapeSequence */ // Check character, converted from UnicodeEscapeSequence if (!lexer_is_char_can_be_identifier_part (c)) { is_correct_identifier_name = false; break; } } } else { is_correct_identifier_name = false; break; } } else if (!lexer_is_char_can_be_identifier_part (c)) { break; } else { if (!(c >= LIT_CHAR_ASCII_LOWERCASE_LETTERS_BEGIN && c <= LIT_CHAR_ASCII_LOWERCASE_LETTERS_END)) { is_all_chars_were_lowercase_ascii = false; } consume_char (); } } if (!is_correct_identifier_name) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Illegal identifier name", lit_utf8_iterator_get_pos (&src_iter)); } const lit_utf8_size_t charset_size = TOK_SIZE (); token ret = empty_token; if (!is_escape_sequence_occured && is_all_chars_were_lowercase_ascii) { /* Keyword or FutureReservedWord (TOK_KEYWORD), or boolean literal (TOK_BOOL), or null literal (TOK_NULL) */ ret = lexer_parse_reserved_word (TOK_START (), charset_size); } if (is_empty (ret)) { /* Identifier (TOK_NAME) */ if (!is_escape_sequence_occured) { ret = lexer_create_token_for_charset (TOK_NAME, TOK_START (), charset_size); } else { ret = lexer_create_token_for_charset_transform_escape_sequences (TOK_NAME, TOK_START (), charset_size); } } is_token_parse_in_progress = false; return ret; } /* lexer_parse_identifier_or_keyword */
/** * Parse numeric literal (ECMA-262, v5, 7.8.3) * * @return token of TOK_SMALL_INT or TOK_NUMBER types */ static token lexer_parse_number (void) { ecma_char_t c = LA (0); bool is_hex = false; bool is_fp = false; ecma_number_t fp_res = .0; size_t tok_length = 0, i; token known_token; JERRY_ASSERT (lit_char_is_decimal_digit (c) || c == LIT_CHAR_DOT); if (c == LIT_CHAR_0) { if (LA (1) == LIT_CHAR_LOWERCASE_X || LA (1) == LIT_CHAR_UPPERCASE_X) { is_hex = true; } } else if (c == LIT_CHAR_DOT) { JERRY_ASSERT (lit_char_is_decimal_digit (LA (1))); is_fp = true; } if (is_hex) { // Eat up '0x' consume_char (); consume_char (); new_token (); c = LA (0); if (!lit_char_is_hex_digit (c)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Invalid HexIntegerLiteral", lit_utf8_iterator_get_pos (&src_iter)); } do { consume_char (); c = LA (0); } while (lit_char_is_hex_digit (c)); if (lexer_is_char_can_be_identifier_start (c)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Identifier just after integer literal", lit_utf8_iterator_get_pos (&src_iter)); } tok_length = (size_t) (TOK_SIZE ()); const lit_utf8_byte_t *fp_buf_p = TOK_START (); /* token is constructed at end of function */ for (i = 0; i < tok_length; i++) { fp_res = fp_res * 16 + (ecma_number_t) lit_char_hex_to_int (fp_buf_p[i]); } } else { bool is_exp = false; new_token (); // Eat up '.' if (is_fp) { consume_char (); } while (true) { c = LA (0); if (c == LIT_CHAR_DOT) { if (is_fp) { /* token is constructed at end of function */ break; } else { is_fp = true; consume_char (); continue; } } else if (c == LIT_CHAR_LOWERCASE_E || c == LIT_CHAR_UPPERCASE_E) { if (is_exp) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Numeric literal shall not contain more than exponential marker ('e' or 'E')", lit_utf8_iterator_get_pos (&src_iter)); } else { is_exp = true; consume_char (); if (LA (0) == LIT_CHAR_MINUS || LA (0) == LIT_CHAR_PLUS) { consume_char (); } continue; } } else if (!lit_char_is_decimal_digit (c)) { if (lexer_is_char_can_be_identifier_start (c)) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Numeric literal shall not contain non-numeric characters", lit_utf8_iterator_get_pos (&src_iter)); } /* token is constructed at end of function */ break; } consume_char (); } tok_length = (size_t) (TOK_SIZE ()); if (is_fp || is_exp) { ecma_number_t res = ecma_utf8_string_to_number (TOK_START (), (jerry_api_size_t) tok_length); JERRY_ASSERT (!ecma_number_is_nan (res)); known_token = convert_seen_num_to_token (res); is_token_parse_in_progress = NULL; return known_token; } else if (*TOK_START () == LIT_CHAR_0 && tok_length != 1) { /* Octal integer literals */ if (strict_mode) { PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Octal integer literals are not allowed in strict mode", token_start_pos); } else { /* token is constructed at end of function */ const lit_utf8_byte_t *fp_buf_p = TOK_START (); for (i = 0; i < tok_length; i++) { fp_res = fp_res * 8 + (ecma_number_t) lit_char_hex_to_int (fp_buf_p[i]); } } } else { const lit_utf8_byte_t *fp_buf_p = TOK_START (); /* token is constructed at end of function */ ecma_number_t mult = 1.0f; for (i = tok_length; i > 0; i--, mult *= 10) { fp_res += (ecma_number_t) lit_char_hex_to_int (fp_buf_p[i - 1]) * mult; } } } if (fp_res >= 0 && fp_res <= 255 && (uint8_t) fp_res == fp_res) { known_token = create_token (TOK_SMALL_INT, (uint8_t) fp_res); is_token_parse_in_progress = NULL; return known_token; } else { known_token = convert_seen_num_to_token (fp_res); is_token_parse_in_progress = NULL; return known_token; } } /* lexer_parse_number */
/*--------------------------------------------------------------*/ int consume_path_instances_currentstates( FILE *ofp, int lno, int version, char *path ) { int status = 0; char *cptr, *cptr2; cptr = strstr(path, "/INSTANCES/"); if ( cptr == NULL ) { return(status); } cptr2 = strstr(path, "/CURRENTSTATES/"); if ( cptr2 != NULL ) { fprintf(ofp, "%d,%d", lno, version); char *xptr = path; consume_char(&xptr, '/'); // consume first slash // consume till next slash copy_till_char(&xptr, g_buffer, '/'); // this is cluster name if ( *g_buffer == '\0' ) { go_BYE(-1); } fprintf(ofp, ",%s", g_buffer); // cluster name zero_string_to_nullc(g_buffer); consume_char(&xptr, '/'); // consume slash copy_till_char(&xptr, g_buffer, '/'); // this is INSTANCES consume_char(&xptr, '/'); // consume slash copy_till_char(&xptr, g_buffer, '/'); // this is instance name if ( *g_buffer == '\0' ) { go_BYE(-1); } fprintf(ofp, ",%s", g_buffer); // instance name zero_string_to_nullc(g_buffer); consume_char(&xptr, '/'); // consume slash copy_till_char(&xptr, g_buffer, '/'); // this is CURRENTSTATES consume_char(&xptr, '/'); // consume slash copy_till_char(&xptr, g_buffer, '/'); consume_char(&xptr, '/'); // consume slash /* this is sessionid */ if ( *g_buffer == '\0' ) { go_BYE(-1); } fprintf(ofp, ",%s", g_buffer); zero_string_to_nullc(g_buffer); copy_till_char(&xptr, g_buffer, '/'); /* this is resource_group_name */ if ( *g_buffer == '\0' ) { go_BYE(-1); } fprintf(ofp, ",%s", g_buffer); zero_string_to_nullc(g_buffer); fprintf(ofp, "\n"); } BYE: return(status); }