lang: interpolate: Fix string interpolation of dollar symbols

Dollar symbols were failing to parse when not followed by a non-brace,
non-dollar, non-EOF token and causing expected tests to fail. This
simplifies the rules to allow the remaining tests to succeed.

Fix and reinstate the final few failing tests, and add another.

Allow any escape sequence to be matched so that invalid sequences
produce a meaningful error message instead of a generic "cannot parse":

    ast: interpolate: interpolating: V: \?
    unhandled escape sequence token: \?

Tidy the related Makefile rule for generating the ragel parser.

Signed-off-by: Joe Groocock <me@frebib.net>
This commit is contained in:
Joe Groocock
2021-09-28 22:40:49 +01:00
parent c555478b54
commit b9741e87bd
6 changed files with 26 additions and 37 deletions

View File

@@ -76,7 +76,7 @@ func Parse(data string) (out Stream, _ error) {
var = '${' var_name '}' ;
# Any special escape characters are matched here.
escaped_lit = '\\' ( 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '\\' | '"' | '$' )
escaped_lit = '\\' (any)
@{
switch s := data[fpc:fpc+1]; s {
case "a":
@@ -105,23 +105,16 @@ func Parse(data string) (out Stream, _ error) {
// x = "\x00"
default:
//x = s // in case we want to avoid erroring
// this is a programming (parser) error I think
return nil, fmt.Errorf("unhandled escape sequence token: %s", s)
return nil, fmt.Errorf("unknown escape sequence: \\%s", s)
}
l = Literal{Value: x}
};
# XXX: explicitly try and add this one?
#escape_lit = '\\\\'
#@{
# l = Literal{Value: "\\\\"}
#};
# Anything followed by a '$' that is not a '{' is used as-is
# with the dollar.
dollar_lit = '$' (any - '{')
# A lone dollar is a literal, if it is not a var. The `token` rule
# declares a var match is attempted first, else a `lit` and thus this.
dollar_lit = '$'
@{
l = Literal{Value: data[fpc-1:fpc+1]}
l = Literal{Value: data[fpc:fpc+1]}
};
# Literal strings that don't contain '$' or '\'.