Enable regular expressions.
- add regular expressions support to JS parser and interpreter; - add tests for regular expressions. JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
This commit is contained in:
@@ -15,9 +15,14 @@
|
||||
*/
|
||||
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "jsp-mm.h"
|
||||
#include "lexer.h"
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "parser.h"
|
||||
#include "stack.h"
|
||||
#include "syntax-errors.h"
|
||||
|
||||
static token saved_token, prev_token, sent_token, empty_token;
|
||||
@@ -961,6 +966,76 @@ parse_string (void)
|
||||
return ret;
|
||||
} /* parse_string */
|
||||
|
||||
/**
|
||||
* 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 ecma_char_t*) token_start,
|
||||
static_cast<ecma_length_t> (buffer - token_start));
|
||||
|
||||
token_start = NULL;
|
||||
return result;
|
||||
} /* parse_regexp */
|
||||
|
||||
static void
|
||||
grobble_whitespaces (void)
|
||||
{
|
||||
@@ -1084,10 +1159,27 @@ lexer_next_token_private (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '/' && LA (1) == '/')
|
||||
|
||||
if (c == '/')
|
||||
{
|
||||
replace_comment_by_newline ();
|
||||
return lexer_next_token_private ();
|
||||
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)
|
||||
@@ -1203,7 +1295,6 @@ lexer_next_token (void)
|
||||
|
||||
prev_token = sent_token;
|
||||
sent_token = lexer_next_token_private ();
|
||||
|
||||
if (sent_token.type == TOK_NEWLINE)
|
||||
{
|
||||
dump_current_line ();
|
||||
|
||||
Reference in New Issue
Block a user