Add double-paren expression
* Use the external scanner for regexes * Add some missing operators Fixes #22 Fixes #32
This commit is contained in:
parent
0123b9559f
commit
246bad66dd
|
@ -90,7 +90,7 @@ F="${G%% *}"
|
|||
(string (expansion (subscript (variable_name) (word)))))
|
||||
(variable_assignment
|
||||
(variable_name)
|
||||
(string (expansion (variable_name) (regex) (word) (word))))
|
||||
(string (expansion (variable_name) (regex))))
|
||||
(variable_assignment
|
||||
(variable_name)
|
||||
(string (expansion (variable_name) (word) (word)))))
|
||||
|
|
26
grammar.js
26
grammar.js
|
@ -34,6 +34,7 @@ module.exports = grammar({
|
|||
$._empty_value,
|
||||
$._concat,
|
||||
$.variable_name, // Variable name followed by an operator like '=' or '+='
|
||||
$.regex,
|
||||
'}',
|
||||
']',
|
||||
'\n',
|
||||
|
@ -229,7 +230,8 @@ module.exports = grammar({
|
|||
test_command: $ => seq(
|
||||
choice(
|
||||
seq('[', $._expression, ']'),
|
||||
seq('[[', $._expression, ']]')
|
||||
seq('[[', $._expression, ']]'),
|
||||
seq('((', $._expression, '))')
|
||||
),
|
||||
repeat(choice(
|
||||
$.file_redirect,
|
||||
|
@ -265,7 +267,7 @@ module.exports = grammar({
|
|||
$._literal,
|
||||
seq(
|
||||
choice('=~', '=='),
|
||||
choice($.regex, $._literal)
|
||||
choice($._literal, $.regex)
|
||||
)
|
||||
)),
|
||||
repeat(choice(
|
||||
|
@ -338,13 +340,20 @@ module.exports = grammar({
|
|||
$._literal,
|
||||
$.unary_expression,
|
||||
$.binary_expression,
|
||||
$.postfix_expression,
|
||||
$.parenthesized_expression
|
||||
),
|
||||
|
||||
binary_expression: $ => prec.left(choice(
|
||||
seq(
|
||||
$._expression,
|
||||
choice('==', '=', '=~', '!=', '<', '>', '||', '&&', $.test_operator),
|
||||
choice(
|
||||
'=', '==', '=~', '!=',
|
||||
'+', '-', '+=', '-=',
|
||||
'<', '>', '<=', '>=',
|
||||
'||', '&&',
|
||||
$.test_operator
|
||||
),
|
||||
$._expression
|
||||
),
|
||||
seq(
|
||||
|
@ -359,6 +368,11 @@ module.exports = grammar({
|
|||
$._expression
|
||||
)),
|
||||
|
||||
postfix_expression: $ => seq(
|
||||
$._expression,
|
||||
choice('++', '--'),
|
||||
),
|
||||
|
||||
parenthesized_expression: $ => seq(
|
||||
'(',
|
||||
$._expression,
|
||||
|
@ -453,7 +467,7 @@ module.exports = grammar({
|
|||
),
|
||||
optional(seq(
|
||||
token(prec(1, '/')),
|
||||
alias($.regex_without_right_brace, $.regex)
|
||||
optional($.regex)
|
||||
)),
|
||||
repeat(choice(
|
||||
$._literal,
|
||||
|
@ -488,10 +502,6 @@ module.exports = grammar({
|
|||
|
||||
test_operator: $ => token(prec(1, seq('-', /[a-zA-Z]+/))),
|
||||
|
||||
regex: $ => /([^"\s]|\\.)([^\s]|\\.)*/,
|
||||
|
||||
regex_without_right_brace: $ => /([^"\s}]|\\.)([^\s}]|\\.)*/,
|
||||
|
||||
_terminator: $ => choice(';', ';;', '\n', '&')
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,7 +4,6 @@ examples/bash-it/plugins/available/go.plugin.bash
|
|||
examples/bash-it/install.sh
|
||||
examples/bash-it/completion/available/svn.completion.bash
|
||||
examples/bash-it/completion/available/docker-compose.completion.bash
|
||||
examples/bash-it/completion/available/jboss7.completion.bash
|
||||
examples/bash-it/completion/available/gh.completion.bash
|
||||
examples/bash-it/completion/available/drush.completion.bash
|
||||
examples/bash-it/completion/available/hub.completion.bash
|
||||
|
@ -12,7 +11,6 @@ examples/bash-it/completion/available/docker-machine.completion.bash
|
|||
examples/bash-it/completion/available/git.completion.bash
|
||||
examples/bash-it/completion/available/defaults.completion.bash
|
||||
examples/bash-it/completion/available/packer.completion.bash
|
||||
examples/bash-it/completion/available/vault.completion.bash
|
||||
examples/bash-it/completion/available/docker.completion.bash
|
||||
examples/bash-it/completion/available/tmux.completion.bash
|
||||
examples/bash-it/lib/preexec.bash
|
||||
|
|
|
@ -858,6 +858,23 @@
|
|||
"value": "]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "(("
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expression"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "))"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1031,11 +1048,11 @@
|
|||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "regex"
|
||||
"name": "_literal"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_literal"
|
||||
"name": "regex"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1326,6 +1343,10 @@
|
|||
"type": "SYMBOL",
|
||||
"name": "binary_expression"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "postfix_expression"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "parenthesized_expression"
|
||||
|
@ -1350,11 +1371,11 @@
|
|||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "=="
|
||||
"value": "="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "="
|
||||
"value": "=="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
|
@ -1364,6 +1385,22 @@
|
|||
"type": "STRING",
|
||||
"value": "!="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "+"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "-"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "+="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "-="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<"
|
||||
|
@ -1372,6 +1409,14 @@
|
|||
"type": "STRING",
|
||||
"value": ">"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">="
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "||"
|
||||
|
@ -1447,6 +1492,28 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"postfix_expression": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expression"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "++"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "--"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"parenthesized_expression": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
@ -1874,13 +1941,16 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"type": "ALIAS",
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "regex_without_right_brace"
|
||||
"name": "regex"
|
||||
},
|
||||
"named": true,
|
||||
"value": "regex"
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -2114,14 +2184,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"regex": {
|
||||
"type": "PATTERN",
|
||||
"value": "([^\"\\s]|\\\\.)([^\\s]|\\\\.)*"
|
||||
},
|
||||
"regex_without_right_brace": {
|
||||
"type": "PATTERN",
|
||||
"value": "([^\"\\s}]|\\\\.)([^\\s}]|\\\\.)*"
|
||||
},
|
||||
"_terminator": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
|
@ -2192,6 +2254,10 @@
|
|||
"type": "SYMBOL",
|
||||
"name": "variable_name"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "regex"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "}"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,6 +16,7 @@ enum TokenType {
|
|||
EMPTY_VALUE,
|
||||
CONCAT,
|
||||
VARIABLE_NAME,
|
||||
REGEX,
|
||||
CLOSING_BRACE,
|
||||
CLOSING_BRACKET,
|
||||
NEWLINE,
|
||||
|
@ -202,6 +203,63 @@ struct Scanner {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (valid_symbols[REGEX]) {
|
||||
while (iswspace(lexer->lookahead)) skip(lexer);
|
||||
|
||||
if (
|
||||
lexer->lookahead != '"' &&
|
||||
lexer->lookahead != '\'' &&
|
||||
lexer->lookahead != '$'
|
||||
) {
|
||||
struct State {
|
||||
bool done;
|
||||
uint32_t paren_depth;
|
||||
uint32_t bracket_depth;
|
||||
uint32_t brace_depth;
|
||||
};
|
||||
|
||||
lexer->mark_end(lexer);
|
||||
|
||||
State state = {false, 0, 0, 0};
|
||||
while (!state.done) {
|
||||
switch (lexer->lookahead) {
|
||||
case '\0':
|
||||
return false;
|
||||
case '(':
|
||||
state.paren_depth++;
|
||||
break;
|
||||
case '[':
|
||||
state.bracket_depth++;
|
||||
break;
|
||||
case '{':
|
||||
state.bracket_depth++;
|
||||
break;
|
||||
case ')':
|
||||
if (state.paren_depth == 0) state.done = true;
|
||||
state.paren_depth--;
|
||||
break;
|
||||
case ']':
|
||||
if (state.bracket_depth == 0) state.done = true;
|
||||
state.bracket_depth--;
|
||||
break;
|
||||
case '}':
|
||||
if (state.brace_depth == 0) state.done = true;
|
||||
state.brace_depth--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!state.done) {
|
||||
bool was_space = iswspace(lexer->lookahead);
|
||||
advance(lexer);
|
||||
if (!was_space) lexer->mark_end(lexer);
|
||||
}
|
||||
}
|
||||
|
||||
lexer->result_symbol = REGEX;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue