nxt_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, nxt_str_t *file,
u_char *start, u_char *end);
njs_token_t njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer);
-njs_token_t njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset);
+njs_token_t njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer,
+ size_t offset);
nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
void njs_lexer_keyword(njs_lexer_t *lexer, njs_lexer_token_t *lt);
-#define njs_lexer_rollback(lexer) \
- (lexer)->start = (lexer)->prev_start
+#define njs_lexer_rollback(lexer) \
+ do { \
+ nxt_queue_insert_head(&(lexer)->preread, &(lexer)->lexer_token->link); \
+ (lexer)->lexer_token = NULL; \
+ } while (0)
#endif /* _NJS_LEXER_H_INCLUDED_ */
njs_parser_statement(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token)
{
+ size_t offset;
+
parser->node = NULL;
switch (token) {
default:
- if (token == NJS_TOKEN_NAME
- && njs_parser_peek_token(vm, parser, 0) == NJS_TOKEN_COLON)
- {
- return njs_parser_labelled_statement(vm, parser);
- }
-
switch (token) {
case NJS_TOKEN_VAR:
token = njs_parser_var_statement(vm, parser);
token = njs_parser_brk_statement(vm, parser, token);
break;
+ case NJS_TOKEN_NAME:
+ offset = 0;
+ if (njs_parser_peek_token(vm, parser, &offset) == NJS_TOKEN_COLON) {
+ return njs_parser_labelled_statement(vm, parser);
+ }
+
+ /* Fall through. */
+
default:
token = njs_parser_expression(vm, parser, token);
break;
njs_value_type_t type, const char *fmt, ...);
-#define njs_parser_peek_token(vm, parser, offset) \
- njs_lexer_peek_token(vm, (parser)->lexer, offset)
-
-
#define njs_parser_is_lvalue(node) \
((node)->token == NJS_TOKEN_NAME || (node)->token == NJS_TOKEN_PROPERTY)
do {
token = njs_lexer_token(vm, parser->lexer);
+ } while (nxt_slow_path(token == NJS_TOKEN_LINE_END));
+
+ return token;
+}
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- }
+nxt_inline njs_token_t
+njs_parser_peek_token(njs_vm_t *vm, njs_parser_t *parser, size_t *offset)
+{
+ njs_token_t token;
+
+ do {
+ token = njs_lexer_peek_token(vm, parser->lexer, (*offset)++);
} while (nxt_slow_path(token == NJS_TOKEN_LINE_END));
return token;
{ nxt_string("var a; a = 0; ++ \n a"),
nxt_string("1") },
+ { nxt_string("var a; a = 0\n ++a"),
+ nxt_string("1") },
+
{ nxt_string("a = 0; a \n ++"),
nxt_string("SyntaxError: Unexpected end of input in 2") },
{ nxt_string("a: throw 'a'"),
nxt_string("a") },
+ { nxt_string("a\n:\n1"),
+ nxt_string("1") },
+
+ { nxt_string("a\n\n:1"),
+ nxt_string("1") },
+
+ { nxt_string("a:\n\n1"),
+ nxt_string("1") },
+
+ { nxt_string("a:\n\n"),
+ nxt_string("SyntaxError: Unexpected end of input in 3") },
+
{ nxt_string("a : var n = 0; b :++n"),
nxt_string("1") },