Parse string literals

This commit is contained in:
2026-05-14 14:10:14 -06:00
parent 3b572f6b30
commit 3ef897feab
5 changed files with 5952 additions and 5109 deletions

View File

@@ -271,6 +271,18 @@ pub fn expr(db: &dyn Database, ast: AstNode) -> Expr {
Integer(0)
}
})
} else if let Some(str) = ast.get_field(db, "string") {
let contents = str.contents(db);
let s = contents
.slice(1..(contents.len_chars() - 1))
.to_string()
.replace(r"\\", "\\")
.replace(r"\n", "\n")
.replace(r"\r", "\r")
.replace(r"\t", "\t")
.replace(r"\0", "\0")
.replace("\\\"", "\"");
Value(String(s))
} else if let Some(unary) = ast.get_field(db, "unary") {
let op = unary.expect_field(db, "op").expect_parse(db);
let term = Arc::new(expr(db, unary.expect_field(db, "term")));

View File

@@ -66,6 +66,16 @@ export default grammar({
integer: _ => choice("0", /-?[1-9][0-9]*/),
string_literal: $ => seq(
'"',
repeat(choice($.string_content, $.escape_sequence)),
'"',
),
string_content: _ => token.immediate(prec(1, /[^\\"]+/)),
escape_sequence: _ => token.immediate(/\\[bfnrtv\"\\]/),
type_alias: $ => seq(
"type",
field("name", $.symbol),
@@ -130,6 +140,7 @@ export default grammar({
field("false", "False"),
field("symbol", $.name),
field("integer", $.integer),
field("string", $.string_literal),
// operations
field("unary", $.unary_expr),

View File

@@ -101,6 +101,53 @@
}
]
},
"string_literal": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "string_content"
},
{
"type": "SYMBOL",
"name": "escape_sequence"
}
]
}
},
{
"type": "STRING",
"value": "\""
}
]
},
"string_content": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PREC",
"value": 1,
"content": {
"type": "PATTERN",
"value": "[^\\\\\"]+"
}
}
},
"escape_sequence": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "\\\\[bfnrtv\\\"\\\\]"
}
},
"type_alias": {
"type": "SEQ",
"members": [
@@ -711,6 +758,14 @@
"name": "integer"
}
},
{
"type": "FIELD",
"name": "string",
"content": {
"type": "SYMBOL",
"name": "string_literal"
}
},
{
"type": "FIELD",
"name": "unary",

View File

@@ -275,6 +275,16 @@
}
]
},
"string": {
"multiple": false,
"required": false,
"types": [
{
"type": "string_literal",
"named": true
}
]
},
"symbol": {
"multiple": false,
"required": false,
@@ -532,6 +542,25 @@
}
}
},
{
"type": "string_literal",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "escape_sequence",
"named": true
},
{
"type": "string_content",
"named": true
}
]
}
},
{
"type": "tuple",
"named": true,
@@ -639,6 +668,10 @@
"type": "!=",
"named": false
},
{
"type": "\"",
"named": false
},
{
"type": "&&",
"named": false
@@ -747,6 +780,10 @@
"type": "define",
"named": false
},
{
"type": "escape_sequence",
"named": true
},
{
"type": "import",
"named": false
@@ -767,6 +804,10 @@
"type": "soft",
"named": false
},
{
"type": "string_content",
"named": true
},
{
"type": "symbol",
"named": true

File diff suppressed because it is too large Load Diff