wip heredoc
This commit is contained in:
@@ -30,8 +30,7 @@ struct Context {
|
|||||||
ContextType type;
|
ContextType type;
|
||||||
|
|
||||||
// valid if type == HEREDOC_TEMPLATE
|
// valid if type == HEREDOC_TEMPLATE
|
||||||
char* identifier;
|
string heredoc_identifier;
|
||||||
size_t identifier_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scanner {
|
struct Scanner {
|
||||||
@@ -141,31 +140,27 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle heredoc identifier
|
// handle heredoc context
|
||||||
if (valid_symbols[HEREDOC_IDENTIFIER]) {
|
if (valid_symbols[HEREDOC_IDENTIFIER] && !in_heredoc_context()) {
|
||||||
if (lexer->lookahead != 'E') {
|
string identifier;
|
||||||
if (valid_symbols[TEMPLATE_LITERAL_CHUNK]) {
|
while (iswalnum(lexer->lookahead) || lexer->lookahead == '_' || lexer->lookahead == '-') {
|
||||||
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
|
identifier.push_back(lexer->lookahead);
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
context_stack.push_back({ .type = HEREDOC_TEMPLATE, .heredoc_identifier = identifier });
|
||||||
|
return accept_and_advance(lexer, HEREDOC_IDENTIFIER);
|
||||||
|
}
|
||||||
|
if (valid_symbols[HEREDOC_IDENTIFIER] && in_heredoc_context()) {
|
||||||
|
string expected_identifier = context_stack.back().heredoc_identifier;
|
||||||
|
|
||||||
|
for (string::iterator it = expected_identifier.begin(); it != expected_identifier.end(); ++it) {
|
||||||
|
if (lexer->lookahead == *it) {
|
||||||
|
advance(lexer);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
|
||||||
}
|
|
||||||
}
|
|
||||||
advance(lexer);
|
|
||||||
if (lexer->lookahead != 'O') {
|
|
||||||
if (valid_symbols[TEMPLATE_LITERAL_CHUNK]) {
|
|
||||||
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
advance(lexer);
|
|
||||||
if (lexer->lookahead != 'F') {
|
|
||||||
if (valid_symbols[TEMPLATE_LITERAL_CHUNK]) {
|
|
||||||
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
context_stack.pop_back();
|
||||||
return accept_and_advance(lexer, HEREDOC_IDENTIFIER);
|
return accept_and_advance(lexer, HEREDOC_IDENTIFIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +175,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
vector<Context> context_stack;
|
vector<Context> context_stack;
|
||||||
vector<string> heredoc_identifier_stack;
|
|
||||||
|
|
||||||
void advance(TSLexer* lexer) {
|
void advance(TSLexer* lexer) {
|
||||||
lexer->advance(lexer, false);
|
lexer->advance(lexer, false);
|
||||||
@@ -197,6 +191,7 @@ private:
|
|||||||
advance(lexer);
|
advance(lexer);
|
||||||
return accept_inplace(lexer, token);
|
return accept_inplace(lexer, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool consume_wxdigit(TSLexer* lexer) {
|
bool consume_wxdigit(TSLexer* lexer) {
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
return iswxdigit(lexer->lookahead);
|
return iswxdigit(lexer->lookahead);
|
||||||
@@ -213,8 +208,12 @@ private:
|
|||||||
return in_context_type(QUOTED_TEMPLATE);
|
return in_context_type(QUOTED_TEMPLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_heredoc_context() {
|
||||||
|
return in_context_type(HEREDOC_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
bool in_template_context() {
|
bool in_template_context() {
|
||||||
return in_context_type(QUOTED_TEMPLATE) || in_context_type(HEREDOC_TEMPLATE);
|
return in_quoted_context() || in_heredoc_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_interpolation_context() {
|
bool in_interpolation_context() {
|
||||||
|
|||||||
@@ -1,22 +1,3 @@
|
|||||||
================================================================================
|
|
||||||
bad escape sequence 2
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
foo = "bar\uZZ"
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(config_file
|
|
||||||
(body
|
|
||||||
(attribute
|
|
||||||
(identifier)
|
|
||||||
(expression
|
|
||||||
(literal_value
|
|
||||||
(string_lit
|
|
||||||
(template_literal
|
|
||||||
(ERROR
|
|
||||||
(UNEXPECTED '\')))))))))
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
unescaped tab
|
unescaped tab
|
||||||
================================================================================
|
================================================================================
|
||||||
@@ -34,25 +15,6 @@ foo = "foo bar"
|
|||||||
(string_lit
|
(string_lit
|
||||||
(template_literal)))))))
|
(template_literal)))))))
|
||||||
|
|
||||||
================================================================================
|
|
||||||
unescaped backslash
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
foo = "foo\bar"
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(config_file
|
|
||||||
(body
|
|
||||||
(attribute
|
|
||||||
(identifier)
|
|
||||||
(expression
|
|
||||||
(literal_value
|
|
||||||
(string_lit
|
|
||||||
(template_literal
|
|
||||||
(ERROR
|
|
||||||
(UNEXPECTED '\')))))))))
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
escaped backslash at end
|
escaped backslash at end
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user