[njs] Refactored out terminal tokens into njs_parser_terminal.c.
Dmitry Volyntsev
xeioex at nginx.com
Sun Mar 31 17:53:58 UTC 2019
details: https://hg.nginx.org/njs/rev/1bce636aed3d
branches:
changeset: 861:1bce636aed3d
user: hongzhidao <hongzhidao at gmail.com>
date: Sun Mar 31 22:59:04 2019 +0800
description:
Refactored out terminal tokens into njs_parser_terminal.c.
diffstat:
auto/sources | 1 +
njs/njs_parser.c | 901 +-------------------------------------------
njs/njs_parser.h | 49 ++-
njs/njs_parser_expression.c | 4 +-
njs/njs_parser_terminal.c | 866 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 919 insertions(+), 902 deletions(-)
diffs (truncated from 1937 to 1000 lines):
diff -r 5f273795d8dc -r 1bce636aed3d auto/sources
--- a/auto/sources Wed Mar 27 20:49:03 2019 +0300
+++ b/auto/sources Sun Mar 31 22:59:04 2019 +0800
@@ -53,6 +53,7 @@ NJS_LIB_SRCS=" \
njs/njs_lexer.c \
njs/njs_lexer_keyword.c \
njs/njs_parser.c \
+ njs/njs_parser_terminal.c \
njs/njs_parser_expression.c \
njs/njs_generator.c \
njs/njs_disassembler.c \
diff -r 5f273795d8dc -r 1bce636aed3d njs/njs_parser.c
--- a/njs/njs_parser.c Wed Mar 27 20:49:03 2019 +0300
+++ b/njs/njs_parser.c Sun Mar 31 22:59:04 2019 +0800
@@ -67,21 +67,6 @@ static nxt_int_t njs_parser_import_hoist
static nxt_int_t njs_parser_export_sink(njs_vm_t *vm, njs_parser_t *parser);
static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm,
njs_parser_t *parser);
-static njs_parser_node_t *njs_parser_reference(njs_vm_t *vm,
- njs_parser_t *parser, njs_token_t token, nxt_str_t *name, uint32_t hash,
- uint32_t token_line);
-static nxt_int_t njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node, njs_value_type_t type, nxt_str_t *name,
- uint32_t hash);
-static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *obj);
-static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *obj);
-static nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value);
-static njs_token_t njs_parser_escape_string_create(njs_vm_t *vm,
- njs_parser_t *parser, njs_value_t *value);
-static njs_token_t njs_parser_unexpected_token(njs_vm_t *vm,
- njs_parser_t *parser, njs_token_t token);
#define njs_parser_chain_current(parser) \
@@ -93,15 +78,6 @@ static njs_token_t njs_parser_unexpected
#define njs_parser_chain_top_set(parser, node) \
(parser)->scope->top = node
-#define njs_parser_key_hash(parser) \
- (parser)->lexer->lexer_token->key_hash
-
-#define njs_parser_number(parser) \
- (parser)->lexer->lexer_token->number
-
-#define njs_parser_token_line(parser) \
- (parser)->lexer->lexer_token->token_line
-
nxt_int_t
njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev)
@@ -515,36 +491,6 @@ njs_parser_block(njs_vm_t *vm, njs_parse
}
-nxt_inline njs_token_t
-njs_parser_match(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
- njs_token_t match)
-{
- if (nxt_fast_path(token == match)) {
- return njs_parser_token(vm, parser);
- }
-
- return njs_parser_unexpected_token(vm, parser, token);
-}
-
-
-nxt_inline njs_variable_t *
-njs_parser_variable_add(njs_vm_t *vm, njs_parser_t *parser,
- njs_variable_type_t type)
-{
- return njs_variable_add(vm, parser->scope, njs_parser_text(parser),
- njs_parser_key_hash(parser), type);
-}
-
-nxt_inline njs_ret_t
-njs_parser_variable_reference(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node, njs_reference_type_t type)
-{
- return njs_variable_reference(vm, parser->scope, node,
- njs_parser_text(parser),
- njs_parser_key_hash(parser), type);
-}
-
-
static njs_token_t
njs_parser_labelled_statement(njs_vm_t *vm, njs_parser_t *parser)
{
@@ -688,7 +634,7 @@ njs_parser_function_declaration(njs_vm_t
}
-static njs_token_t
+njs_token_t
njs_parser_function_expression(njs_vm_t *vm, njs_parser_t *parser)
{
njs_ret_t ret;
@@ -2226,849 +2172,6 @@ njs_parser_property_token(njs_vm_t *vm,
}
-njs_token_t
-njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
-{
- double num;
- njs_ret_t ret;
- njs_parser_node_t *node;
-
- if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
-
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- token = njs_parser_expression(vm, parser, token);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- return njs_parser_match(vm, parser, token, NJS_TOKEN_CLOSE_PARENTHESIS);
- }
-
- if (token == NJS_TOKEN_FUNCTION) {
- return njs_parser_function_expression(vm, parser);
- }
-
- switch (token) {
-
- case NJS_TOKEN_OPEN_BRACE:
- nxt_thread_log_debug("JS: OBJECT");
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- parser->node = node;
-
- token = njs_parser_object(vm, parser, node);
-
- if (parser->node != node) {
- /* The object is not empty. */
- node->left = parser->node;
- parser->node = node;
- }
-
- return token;
-
- case NJS_TOKEN_OPEN_BRACKET:
- nxt_thread_log_debug("JS: ARRAY");
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_ARRAY);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- parser->node = node;
-
- token = njs_parser_array(vm, parser, node);
-
- if (parser->node != node) {
- /* The array is not empty. */
- node->left = parser->node;
- parser->node = node;
- }
-
- return token;
-
- case NJS_TOKEN_DIVISION:
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_REGEXP);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- token = njs_regexp_literal(vm, parser, &node->u.value);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- nxt_thread_log_debug("REGEX: '%V'", njs_parser_text(parser));
-
- break;
-
- case NJS_TOKEN_STRING:
- nxt_thread_log_debug("JS: '%V'", njs_parser_text(parser));
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- ret = njs_parser_string_create(vm, &node->u.value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NJS_TOKEN_ERROR;
- }
-
- break;
-
- case NJS_TOKEN_ESCAPE_STRING:
- nxt_thread_log_debug("JS: '%V'", njs_parser_text(parser));
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- ret = njs_parser_escape_string_create(vm, parser, &node->u.value);
- if (nxt_slow_path(ret != NJS_TOKEN_STRING)) {
- return ret;
- }
-
- break;
-
- case NJS_TOKEN_UNTERMINATED_STRING:
- njs_parser_syntax_error(vm, parser, "Unterminated string \"%V\"",
- njs_parser_text(parser));
-
- return NJS_TOKEN_ILLEGAL;
-
- case NJS_TOKEN_NUMBER:
- num = njs_parser_number(parser);
- nxt_thread_log_debug("JS: %f", num);
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_NUMBER);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- node->u.value.data.u.number = num;
- node->u.value.type = NJS_NUMBER;
- node->u.value.data.truth = njs_is_number_true(num);
-
- break;
-
- case NJS_TOKEN_BOOLEAN:
- num = njs_parser_number(parser);
- nxt_thread_log_debug("JS: boolean: %V", njs_parser_text(parser));
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_BOOLEAN);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- if (num == 0) {
- node->u.value = njs_value_false;
-
- } else {
- node->u.value = njs_value_true;
- }
-
- break;
-
- default:
- node = njs_parser_reference(vm, parser, token,
- njs_parser_text(parser),
- njs_parser_key_hash(parser),
- njs_parser_token_line(parser));
-
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- break;
- }
-
- parser->node = node;
-
- return njs_parser_token(vm, parser);
-}
-
-
-static njs_parser_node_t *
-njs_parser_reference(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
- nxt_str_t *name, uint32_t hash, uint32_t token_line)
-{
- njs_ret_t ret;
- njs_value_t *ext;
- njs_parser_node_t *node;
- njs_parser_scope_t *scope;
-
- node = njs_parser_node_new(vm, parser, token);
- if (nxt_slow_path(node == NULL)) {
- return NULL;
- }
-
- switch (token) {
-
- case NJS_TOKEN_NULL:
- nxt_thread_log_debug("JS: null");
-
- node->u.value = njs_value_null;
- break;
-
- case NJS_TOKEN_UNDEFINED:
- nxt_thread_log_debug("JS: undefined");
-
- node->u.value = njs_value_undefined;
- break;
-
- case NJS_TOKEN_THIS:
- nxt_thread_log_debug("JS: this");
-
- scope = parser->scope;
-
- while (scope->type != NJS_SCOPE_GLOBAL) {
- if (scope->type == NJS_SCOPE_FUNCTION) {
- node->index = NJS_INDEX_THIS;
- break;
- }
-
- scope = scope->parent;
- }
-
- if (node->index == NJS_INDEX_THIS) {
- break;
- }
-
- node->token = NJS_TOKEN_GLOBAL_THIS;
-
- /* Fall through. */
-
- case NJS_TOKEN_NJS:
- case NJS_TOKEN_MATH:
- case NJS_TOKEN_JSON:
- ret = njs_parser_builtin(vm, parser, node, NJS_OBJECT, name, hash);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NULL;
- }
-
- break;
-
- case NJS_TOKEN_ARGUMENTS:
- nxt_thread_log_debug("JS: arguments");
-
- if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
- njs_parser_syntax_error(vm, parser, "\"%V\" object "
- "in global scope", name);
-
- return NULL;
- }
-
- parser->scope->arguments_object = 1;
-
- break;
-
- case NJS_TOKEN_OBJECT_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT;
- break;
-
- case NJS_TOKEN_ARRAY_CONSTRUCTOR:
- node->index = NJS_INDEX_ARRAY;
- break;
-
- case NJS_TOKEN_BOOLEAN_CONSTRUCTOR:
- node->index = NJS_INDEX_BOOLEAN;
- break;
-
- case NJS_TOKEN_NUMBER_CONSTRUCTOR:
- node->index = NJS_INDEX_NUMBER;
- break;
-
- case NJS_TOKEN_STRING_CONSTRUCTOR:
- node->index = NJS_INDEX_STRING;
- break;
-
- case NJS_TOKEN_FUNCTION_CONSTRUCTOR:
- node->index = NJS_INDEX_FUNCTION;
- break;
-
- case NJS_TOKEN_REGEXP_CONSTRUCTOR:
- node->index = NJS_INDEX_REGEXP;
- break;
-
- case NJS_TOKEN_DATE_CONSTRUCTOR:
- node->index = NJS_INDEX_DATE;
- break;
-
- case NJS_TOKEN_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_ERROR;
- break;
-
- case NJS_TOKEN_EVAL_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_EVAL_ERROR;
- break;
-
- case NJS_TOKEN_INTERNAL_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_INTERNAL_ERROR;
- break;
-
- case NJS_TOKEN_RANGE_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_RANGE_ERROR;
- break;
-
- case NJS_TOKEN_REF_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_REF_ERROR;
- break;
-
- case NJS_TOKEN_SYNTAX_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_SYNTAX_ERROR;
- break;
-
- case NJS_TOKEN_TYPE_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_TYPE_ERROR;
- break;
-
- case NJS_TOKEN_URI_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_URI_ERROR;
- break;
-
- case NJS_TOKEN_MEMORY_ERROR_CONSTRUCTOR:
- node->index = NJS_INDEX_OBJECT_MEMORY_ERROR;
- break;
-
- case NJS_TOKEN_EVAL:
- case NJS_TOKEN_TO_STRING:
- case NJS_TOKEN_IS_NAN:
- case NJS_TOKEN_IS_FINITE:
- case NJS_TOKEN_PARSE_INT:
- case NJS_TOKEN_PARSE_FLOAT:
- case NJS_TOKEN_ENCODE_URI:
- case NJS_TOKEN_ENCODE_URI_COMPONENT:
- case NJS_TOKEN_DECODE_URI:
- case NJS_TOKEN_DECODE_URI_COMPONENT:
- case NJS_TOKEN_REQUIRE:
- case NJS_TOKEN_SET_TIMEOUT:
- case NJS_TOKEN_SET_IMMEDIATE:
- case NJS_TOKEN_CLEAR_TIMEOUT:
- ret = njs_parser_builtin(vm, parser, node, NJS_FUNCTION, name, hash);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NULL;
- }
-
- break;
-
- case NJS_TOKEN_NAME:
- nxt_thread_log_debug("JS: %V", name);
-
- node->token_line = token_line;
-
- ext = njs_external_lookup(vm, name, hash);
-
- if (ext != NULL) {
- node->token = NJS_TOKEN_EXTERNAL;
- node->u.value = *ext;
- node->index = (njs_index_t) ext;
- break;
- }
-
- ret = njs_variable_reference(vm, parser->scope, node, name, hash,
- NJS_REFERENCE);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NULL;
- }
-
- break;
-
- default:
- (void) njs_parser_unexpected_token(vm, parser, token);
- return NULL;
- }
-
- return node;
-}
-
-
-static nxt_int_t
-njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node,
- njs_value_type_t type, nxt_str_t *name, uint32_t hash)
-{
- njs_ret_t ret;
- nxt_uint_t index;
- njs_variable_t *var;
- njs_parser_scope_t *scope;
-
- scope = njs_parser_global_scope(vm);
-
- var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
- if (nxt_slow_path(var == NULL)) {
- return NXT_ERROR;
- }
-
- /* TODO: once */
- switch (type) {
- case NJS_OBJECT:
- index = node->token - NJS_TOKEN_FIRST_OBJECT;
- var->value.data.u.object = &vm->shared->objects[index];
- break;
-
- case NJS_FUNCTION:
- index = node->token - NJS_TOKEN_FIRST_FUNCTION;
- var->value.data.u.function = &vm->shared->functions[index];
- break;
-
- default:
- return NXT_ERROR;
- }
-
- var->value.type = type;
- var->value.data.truth = 1;
-
- ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
-
- return NXT_OK;
-}
-
-
-/*
- * ES6: 12.2.6 Object Initializer
- * Supported syntax:
- * PropertyDefinition:
- * PropertyName : AssignmentExpression
- * IdentifierReference
- * PropertyName:
- * IdentifierName, StringLiteral, NumericLiteral.
- */
-static njs_token_t
-njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj)
-{
- uint32_t hash, token_line;
- nxt_str_t name;
- njs_token_t token;
- njs_lexer_t *lexer;
- njs_parser_node_t *stmt, *assign, *object, *propref, *left, *expression;
-
- left = NULL;
- lexer = parser->lexer;
-
- /* GCC and Clang complain about uninitialized hash. */
- hash = 0;
- token_line = 0;
-
- object = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT_VALUE);
- if (nxt_slow_path(object == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- object->u.object = obj;
-
- for ( ;; ) {
- token = njs_parser_property_token(vm, parser);
-
- name.start = NULL;
-
- switch (token) {
-
- case NJS_TOKEN_CLOSE_BRACE:
- return njs_parser_token(vm, parser);
-
- case NJS_TOKEN_NAME:
- name = *njs_parser_text(parser);
-
- hash = njs_parser_key_hash(parser);
- token_line = njs_parser_token_line(parser);
-
- token = njs_parser_token(vm, parser);
- break;
-
- case NJS_TOKEN_NUMBER:
- case NJS_TOKEN_STRING:
- case NJS_TOKEN_ESCAPE_STRING:
- token = njs_parser_terminal(vm, parser, token);
- break;
-
- default:
- return NJS_TOKEN_ILLEGAL;
- }
-
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- propref = njs_parser_node_new(vm, parser, NJS_TOKEN_PROPERTY);
- if (nxt_slow_path(propref == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- propref->left = object;
- propref->right = parser->node;
-
- if (name.start != NULL
- && (token == NJS_TOKEN_COMMA || token == NJS_TOKEN_CLOSE_BRACE)
- && lexer->property_token != NJS_TOKEN_THIS
- && lexer->property_token != NJS_TOKEN_GLOBAL_THIS)
- {
- expression = njs_parser_reference(vm, parser, lexer->property_token,
- &name, hash, token_line);
- if (nxt_slow_path(expression == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- } else {
- token = njs_parser_match(vm, parser, token, NJS_TOKEN_COLON);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- token = njs_parser_assignment_expression(vm, parser, token);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- expression = parser->node;
- }
-
- assign = njs_parser_node_new(vm, parser, NJS_TOKEN_ASSIGNMENT);
- if (nxt_slow_path(assign == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- assign->u.operation = njs_vmcode_move;
- assign->left = propref;
- assign->right = expression;
-
- stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- if (nxt_slow_path(stmt == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- stmt->left = left;
- stmt->right = assign;
-
- parser->node = stmt;
-
- left = stmt;
-
- if (token == NJS_TOKEN_CLOSE_BRACE) {
- return njs_parser_token(vm, parser);
- }
-
- if (nxt_slow_path(token != NJS_TOKEN_COMMA)) {
- return NJS_TOKEN_ILLEGAL;
- }
- }
-}
-
-
-static njs_token_t
-njs_parser_array(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj)
-{
- nxt_uint_t index;
- njs_token_t token;
- njs_parser_node_t *stmt, *assign, *object, *propref, *left, *node;
-
- index = 0;
- left = NULL;
-
- for ( ;; ) {
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- if (token == NJS_TOKEN_CLOSE_BRACKET) {
- break;
- }
-
- if (token == NJS_TOKEN_COMMA) {
- obj->ctor = 1;
- index++;
- continue;
- }
-
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_NUMBER);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- node->u.value.data.u.number = index;
- node->u.value.type = NJS_NUMBER;
- node->u.value.data.truth = (index != 0);
- index++;
-
- object = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT_VALUE);
- if (nxt_slow_path(object == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- object->u.object = obj;
-
- propref = njs_parser_node_new(vm, parser, NJS_TOKEN_PROPERTY);
- if (nxt_slow_path(propref == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- propref->left = object;
- propref->right = node;
-
- token = njs_parser_assignment_expression(vm, parser, token);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
-
- assign = njs_parser_node_new(vm, parser, NJS_TOKEN_ASSIGNMENT);
- if (nxt_slow_path(assign == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- assign->u.operation = njs_vmcode_move;
- assign->left = propref;
- assign->right = parser->node;
-
- stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
- if (nxt_slow_path(stmt == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- stmt->left = left;
- stmt->right = assign;
-
- parser->node = stmt;
- left = stmt;
-
- obj->ctor = 0;
-
- if (token == NJS_TOKEN_CLOSE_BRACKET) {
- break;
- }
-
- if (nxt_slow_path(token != NJS_TOKEN_COMMA)) {
- return NJS_TOKEN_ILLEGAL;
- }
- }
-
- obj->u.length = index;
-
- return njs_parser_token(vm, parser);
-}
-
-
-static nxt_int_t
-njs_parser_string_create(njs_vm_t *vm, njs_value_t *value)
-{
- u_char *p;
- ssize_t length;
- nxt_str_t *src;
-
- src = njs_parser_text(vm->parser);
-
- length = nxt_utf8_length(src->start, src->length);
-
- if (nxt_slow_path(length < 0)) {
- length = 0;
- }
-
- p = njs_string_alloc(vm, value, src->length, length);
-
- if (nxt_fast_path(p != NULL)) {
- memcpy(p, src->start, src->length);
-
- if (length > NJS_STRING_MAP_STRIDE && (size_t) length != src->length) {
- njs_string_offset_map_init(p, src->length);
- }
-
- return NXT_OK;
- }
-
- return NXT_ERROR;
-}
-
-
-static njs_token_t
-njs_parser_escape_string_create(njs_vm_t *vm, njs_parser_t *parser,
- njs_value_t *value)
-{
- u_char c, *start, *dst;
- size_t size,length, hex_length;
- uint64_t u;
- nxt_str_t *string;
- const u_char *p, *src, *end, *hex_end;
-
- start = NULL;
- dst = NULL;
-
- for ( ;; ) {
- /*
- * The loop runs twice: at the first step string size and
- * UTF-8 length are evaluated. Then the string is allocated
- * and at the second step string content is copied.
- */
- size = 0;
- length = 0;
-
- string = njs_parser_text(parser);
- src = string->start;
- end = src + string->length;
-
- while (src < end) {
- c = *src++;
-
- if (c == '\\') {
- /*
- * Testing "src == end" is not required here
- * since this has been already tested by lexer.
- */
- c = *src++;
-
- switch (c) {
-
- case 'u':
- hex_length = 4;
- /*
- * A character after "u" can be safely tested here
- * because there is always a closing quote at the
- * end of string: ...\u".
- */
- if (*src != '{') {
- goto hex_length_test;
- }
-
- src++;
- hex_length = 0;
- hex_end = end;
-
- goto hex;
-
- case 'x':
- hex_length = 2;
- goto hex_length_test;
-
- case '0':
- c = '\0';
- break;
-
- case 'b':
- c = '\b';
- break;
-
- case 'f':
- c = '\f';
- break;
-
- case 'n':
- c = '\n';
- break;
-
- case 'r':
- c = '\r';
- break;
-
- case 't':
- c = '\t';
- break;
-
- case 'v':
- c = '\v';
- break;
-
- case '\r':
- /*
- * A character after "\r" can be safely tested here
- * because there is always a closing quote at the
- * end of string: ...\\r".
- */
- if (*src == '\n') {
- src++;
- }
-
- continue;
-
- case '\n':
- continue;
-
- default:
- break;
- }
- }
-
- size++;
- length++;
-
- if (dst != NULL) {
- *dst++ = c;
- }
-
- continue;
-
- hex_length_test:
-
- hex_end = src + hex_length;
-
- if (hex_end > end) {
- goto invalid;
- }
-
- hex:
-
- p = src;
- u = njs_number_hex_parse(&src, hex_end);
-
- if (hex_length != 0) {
- if (src != hex_end) {
- goto invalid;
- }
-
- } else {
- if (src == p || (src - p) > 6) {
- goto invalid;
- }
-
- if (src == end || *src++ != '}') {
- goto invalid;
- }
- }
-
- size += nxt_utf8_size(u);
- length++;
-
- if (dst != NULL) {
- dst = nxt_utf8_encode(dst, (uint32_t) u);
- if (dst == NULL) {
- goto invalid;
- }
- }
- }
-
- if (start != NULL) {
- if (length > NJS_STRING_MAP_STRIDE && length != size) {
- njs_string_offset_map_init(start, size);
- }
-
- return NJS_TOKEN_STRING;
- }
-
- start = njs_string_alloc(vm, value, size, length);
- if (nxt_slow_path(start == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- dst = start;
- }
-
-invalid:
-
- njs_parser_syntax_error(vm, parser, "Invalid Unicode code point \"%V\"",
- njs_parser_text(parser));
-
- return NJS_TOKEN_ILLEGAL;
-}
-
-
nxt_bool_t
njs_parser_has_side_effect(njs_parser_node_t *node)
{
@@ -3100,7 +2203,7 @@ njs_parser_has_side_effect(njs_parser_no
}
-static njs_token_t
+njs_token_t
njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token)
{
diff -r 5f273795d8dc -r 1bce636aed3d njs/njs_parser.h
--- a/njs/njs_parser.h Wed Mar 27 20:49:03 2019 +0300
+++ b/njs/njs_parser.h Sun Mar 31 22:59:04 2019 +0800
@@ -77,24 +77,26 @@ struct njs_parser_s {
nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_t *prev);
-njs_token_t njs_parser_arguments(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *parent);
njs_token_t njs_parser_expression(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
njs_token_t njs_parser_var_expression(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
njs_token_t njs_parser_assignment_expression(njs_vm_t *vm,
njs_parser_t *parser, njs_token_t token);
+njs_token_t njs_parser_function_expression(njs_vm_t *vm, njs_parser_t *parser);
njs_token_t njs_parser_module_lambda(njs_vm_t *vm, njs_parser_t *parser);
njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
njs_token_t njs_parser_property_token(njs_vm_t *vm, njs_parser_t *parser);
+nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value);
njs_token_t njs_parser_lambda_statements(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node);
njs_index_t njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node);
njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node);
nxt_bool_t njs_parser_has_side_effect(njs_parser_node_t *node);
+njs_token_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
+ njs_token_t token);
u_char *njs_parser_trace_handler(nxt_trace_t *trace, nxt_trace_data_t *td,
u_char *start);
void njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
@@ -115,6 +117,18 @@ void njs_parser_node_error(njs_vm_t *vm,
&(parser)->lexer->lexer_token->text
+#define njs_parser_key_hash(parser) \
+ (parser)->lexer->lexer_token->key_hash
+
+
+#define njs_parser_number(parser) \
+ (parser)->lexer->lexer_token->number
+
More information about the nginx-devel
mailing list