Introduce NAME node and fix behavior of "or"

This commit is contained in:
oxalica 2022-07-24 03:39:11 +08:00
parent 3a4e18c5a5
commit 9b1fd4c0d2
13 changed files with 190 additions and 86 deletions

View file

@ -116,11 +116,11 @@ def! {
LET_IN,
LIST,
LITERAL,
NAME,
PARAM,
PAREN,
PAT,
PAT_FIELD,
REF,
SELECT,
STRING,
UNARY_OP,

View file

@ -152,7 +152,7 @@ pub fn lex(src: &[u8]) -> LexTokens {
b"in" => T![in],
b"inherit" => T![inherit],
b"let" => T![let],
// b"or" => T![or], Handled in parser.
b"or" => T![or],
b"rec" => T![rec],
b"then" => T![then],
b"with" => T![with],
@ -332,4 +332,25 @@ mod test {
"#]],
);
}
#[test]
fn or_is_keyword() {
check_lex(
"{ or = 1; } or",
expect![[r#"
L_CURLY "{"
SPACE " "
KW_OR "or"
SPACE " "
EQ "="
SPACE " "
INT "1"
SEMICOLON ";"
SPACE " "
R_CURLY "}"
SPACE " "
KW_OR "or"
"#]],
);
}
}

View file

@ -230,7 +230,9 @@ impl<'i> Parser<'i> {
self.pat();
if self.peek_non_ws() == Some(T![@]) {
self.bump(); // @
self.start_node(NAME);
self.want(IDENT);
self.finish_node();
}
self.finish_node();
@ -251,7 +253,9 @@ impl<'i> Parser<'i> {
self.start_node(LAMBDA);
self.start_node(PARAM);
self.start_node(NAME);
self.bump(); // IDENT
self.finish_node();
if self.peek_non_ws() == Some(T![@]) {
self.bump();
if self.peek_non_ws() == Some(T!['{']) {
@ -398,17 +402,22 @@ impl<'i> Parser<'i> {
self.start_node_at(cp, SELECT);
self.bump();
self.attrpath_opt();
// Check contectual keyword "or".
self.ws();
match self.tokens.last() {
Some(&(IDENT, range)) if &self.src[range] == "or" => {
self.tokens.pop();
self.builder.token(T![or].into(), &self.src[range]);
self.expr_select_opt();
}
_ => {}
if self.peek_non_ws() == Some(T![or]) {
self.bump();
self.expr_select_opt();
}
self.finish_node();
// Yes, this is wierd, but Nix parse `or` immediately after a non-select atom expression,
// and construct a Apply node, with higher priority than left-associative Apply.
// `a b or c` => `(a (b or)) c`
} else if self.peek_non_ws() == Some(T![or]) {
self.start_node_at(cp, APPLY);
self.start_node(NAME);
self.bump(); // or
self.finish_node();
self.finish_node();
}
}
@ -418,8 +427,8 @@ impl<'i> Parser<'i> {
// This must matches SyntaxKind::can_start_atom_expr.
match self.peek_non_ws() {
Some(IDENT) => {
self.start_node(REF);
self.bump();
self.start_node(NAME);
self.bump(); // IDENT
self.finish_node();
}
Some(INT | FLOAT | RELATIVE_PATH | ABSOLUTE_PATH | HOME_PATH | SEARCH_PATH | URI) => {
@ -521,7 +530,9 @@ impl<'i> Parser<'i> {
}
Some(IDENT) => {
self.start_node(PAT_FIELD);
self.start_node(NAME);
self.bump(); // IDENT
self.finish_node();
if self.peek_non_ws() == Some(T![?]) {
self.bump(); // ?
self.expr_function_opt();
@ -603,7 +614,11 @@ impl<'i> Parser<'i> {
fn attr_opt(&mut self) {
// This must matches SyntaxKind::can_start_attr.
match self.peek_non_ws() {
Some(IDENT) => self.bump(),
Some(IDENT | T![or]) => {
self.start_node(NAME);
self.bump();
self.finish_node();
}
Some(T!["${"]) => self.dynamic(),
Some(T!['"']) => self.string(STRING),
_ => self.error(Error::MissingAttr),
@ -681,7 +696,7 @@ impl SyntaxKind {
// This must matches Parser::attr_opt.
fn can_start_attr(self) -> bool {
matches!(self, T!["${"] | T!['"'] | IDENT)
matches!(self, T!["${"] | T!['"'] | T![or] | IDENT)
}
// This must matches Parser::expr_atom_opt.

View file

@ -0,0 +1,29 @@
Unexpected token at 2
Unexpected token at 9
Unexpected token at 14
SOURCE_FILE@0..21
BINARY_OP@0..21
BINARY_OP@0..12
LIST@0..6
L_BRACK@0..1 "["
SPACE@1..2 " "
KW_OR@2..4 "or"
SPACE@4..5 " "
R_BRACK@5..6 "]"
SPACE@6..7 " "
PLUS@7..8 "+"
SPACE@8..9 " "
APPLY@9..11
NAME@9..11
KW_OR@9..11 "or"
SPACE@11..12 " "
PLUS@12..13 "+"
SPACE@13..14 " "
APPLY@14..21
APPLY@14..16
NAME@14..16
KW_OR@14..16 "or"
SPACE@16..17 " "
NAME@17..20
IDENT@17..20 "foo"
SPACE@20..21 "\n"

View file

@ -0,0 +1 @@
[ or ] + or + or foo

View file

@ -41,7 +41,8 @@ SOURCE_FILE@0..78
SPACE@57..60 "\n "
LAMBDA@60..78
PARAM@60..61
IDENT@60..61 "a"
NAME@60..61
IDENT@60..61 "a"
COLON@61..62 ":"
SPACE@62..65 "\n "
LAMBDA@65..78
@ -50,7 +51,8 @@ SOURCE_FILE@0..78
L_CURLY@65..66 "{"
SPACE@66..67 " "
PAT_FIELD@67..69
IDENT@67..68 "b"
NAME@67..68
IDENT@67..68 "b"
SPACE@68..69 " "
R_CURLY@69..70 "}"
COLON@70..71 ":"

View file

@ -6,12 +6,14 @@ SOURCE_FILE@0..209
L_PAREN@4..5 "("
LAMBDA@5..12
PARAM@5..6
IDENT@5..6 "a"
NAME@5..6
IDENT@5..6 "a"
COLON@6..7 ":"
SPACE@7..8 " "
LAMBDA@8..12
PARAM@8..9
IDENT@8..9 "b"
NAME@8..9
IDENT@8..9 "b"
COLON@9..10 ":"
SPACE@10..11 " "
LITERAL@11..12
@ -64,7 +66,8 @@ SOURCE_FILE@0..209
L_CURLY@48..49 "{"
SPACE@49..50 " "
PAT_FIELD@50..52
IDENT@50..51 "a"
NAME@50..51
IDENT@50..51 "a"
SPACE@51..52 " "
R_CURLY@52..53 "}"
COLON@53..54 ":"
@ -81,7 +84,8 @@ SOURCE_FILE@0..209
L_CURLY@61..62 "{"
SPACE@62..63 " "
PAT_FIELD@63..64
IDENT@63..64 "a"
NAME@63..64
IDENT@63..64 "a"
COMMA@64..65 ","
SPACE@65..66 " "
R_CURLY@66..67 "}"
@ -99,7 +103,8 @@ SOURCE_FILE@0..209
L_CURLY@75..76 "{"
SPACE@76..77 " "
PAT_FIELD@77..78
IDENT@77..78 "a"
NAME@77..78
IDENT@77..78 "a"
COMMA@78..79 ","
SPACE@79..80 " "
DOT3@80..83 "..."
@ -119,11 +124,13 @@ SOURCE_FILE@0..209
L_CURLY@93..94 "{"
SPACE@94..95 " "
PAT_FIELD@95..96
IDENT@95..96 "a"
NAME@95..96
IDENT@95..96 "a"
COMMA@96..97 ","
SPACE@97..98 " "
PAT_FIELD@98..100
IDENT@98..99 "b"
NAME@98..99
IDENT@98..99 "b"
SPACE@99..100 " "
R_CURLY@100..101 "}"
COLON@101..102 ":"
@ -156,7 +163,8 @@ SOURCE_FILE@0..209
L_CURLY@124..125 "{"
SPACE@125..126 " "
PAT_FIELD@126..135
IDENT@126..127 "a"
NAME@126..127
IDENT@126..127 "a"
SPACE@127..128 " "
QUESTION@128..129 "?"
SPACE@129..130 " "
@ -167,12 +175,13 @@ SOURCE_FILE@0..209
R_CURLY@131..132 "}"
COLON@132..133 ":"
SPACE@133..134 " "
REF@134..135
NAME@134..135
IDENT@134..135 "a"
COMMA@135..136 ","
SPACE@136..137 " "
PAT_FIELD@137..138
IDENT@137..138 "b"
NAME@137..138
IDENT@137..138 "b"
COMMA@138..139 ","
SPACE@139..140 " "
DOT3@140..143 "..."
@ -188,7 +197,8 @@ SOURCE_FILE@0..209
L_PAREN@153..154 "("
LAMBDA@154..162
PARAM@154..159
IDENT@154..155 "a"
NAME@154..155
IDENT@154..155 "a"
AT@155..156 "@"
PAT@156..159
L_CURLY@156..157 "{"
@ -204,13 +214,15 @@ SOURCE_FILE@0..209
L_PAREN@166..167 "("
LAMBDA@167..177
PARAM@167..174
IDENT@167..168 "a"
NAME@167..168
IDENT@167..168 "a"
AT@168..169 "@"
PAT@169..174
L_CURLY@169..170 "{"
SPACE@170..171 " "
PAT_FIELD@171..173
IDENT@171..172 "a"
NAME@171..172
IDENT@171..172 "a"
SPACE@172..173 " "
R_CURLY@173..174 "}"
COLON@174..175 ":"
@ -228,7 +240,8 @@ SOURCE_FILE@0..209
SPACE@183..184 " "
R_CURLY@184..185 "}"
AT@185..186 "@"
IDENT@186..187 "a"
NAME@186..187
IDENT@186..187 "a"
COLON@187..188 ":"
SPACE@188..189 " "
LITERAL@189..190
@ -243,11 +256,13 @@ SOURCE_FILE@0..209
L_CURLY@195..196 "{"
SPACE@196..197 " "
PAT_FIELD@197..199
IDENT@197..198 "a"
NAME@197..198
IDENT@197..198 "a"
SPACE@198..199 " "
R_CURLY@199..200 "}"
AT@200..201 "@"
IDENT@201..202 "a"
NAME@201..202
IDENT@201..202 "a"
COLON@202..203 ":"
SPACE@203..204 " "
LITERAL@204..205

View file

@ -81,7 +81,8 @@ SOURCE_FILE@0..71
QUESTION@62..63 "?"
ATTR_PATH@63..66
SPACE@63..64 " "
IDENT@64..65 "a"
NAME@64..65
IDENT@64..65 "a"
SPACE@65..66 " "
SLASH2@66..68 "//"
SPACE@68..69 " "

View file

@ -1,15 +1,16 @@
SOURCE_FILE@0..27
APPLY@0..27
SELECT@0..25
REF@0..1
NAME@0..1
IDENT@0..1 "a"
DOT@1..2 "."
ATTR_PATH@2..13
IDENT@2..3 "b"
NAME@2..3
IDENT@2..3 "b"
DOT@3..4 "."
DYNAMIC@4..8
DOLLAR_L_CURLY@4..6 "${"
REF@6..7
NAME@6..7
IDENT@6..7 "c"
R_CURLY@7..8 "}"
DOT@8..9 "."
@ -21,17 +22,18 @@ SOURCE_FILE@0..27
KW_OR@13..15 "or"
SELECT@15..25
SPACE@15..16 " "
REF@16..17
NAME@16..17
IDENT@16..17 "e"
DOT@17..18 "."
ATTR_PATH@18..20
IDENT@18..19 "f"
NAME@18..19
IDENT@18..19 "f"
SPACE@19..20 " "
KW_OR@20..22 "or"
SPACE@22..23 " "
REF@23..24
NAME@23..24
IDENT@23..24 "g"
SPACE@24..25 " "
REF@25..26
NAME@25..26
IDENT@25..26 "h"
SPACE@26..27 "\n"

View file

@ -2,7 +2,7 @@ SOURCE_FILE@0..121
LIST@0..120
L_BRACK@0..1 "["
SPACE@1..4 "\n "
REF@4..5
NAME@4..5
IDENT@4..5 "a"
SPACE@5..8 "\n "
LITERAL@8..9
@ -28,7 +28,7 @@ SOURCE_FILE@0..121
STRING_FRAGMENT@42..44 "fo"
DYNAMIC@44..50
DOLLAR_L_CURLY@44..46 "${"
REF@46..49
NAME@46..49
IDENT@46..49 "bar"
R_CURLY@49..50 "}"
STRING_FRAGMENT@50..51 "o"
@ -39,7 +39,7 @@ SOURCE_FILE@0..121
STRING_FRAGMENT@57..59 "fo"
DYNAMIC@59..65
DOLLAR_L_CURLY@59..61 "${"
REF@61..64
NAME@61..64
IDENT@61..64 "bar"
R_CURLY@64..65 "}"
STRING_FRAGMENT@65..66 "o"
@ -65,32 +65,35 @@ SOURCE_FILE@0..121
R_CURLY@93..94 "}"
SPACE@94..97 "\n "
SELECT@97..115
REF@97..98
NAME@97..98
IDENT@97..98 "a"
DOT@98..99 "."
ATTR_PATH@99..101
IDENT@99..100 "b"
NAME@99..100
IDENT@99..100 "b"
SPACE@100..101 " "
KW_OR@101..103 "or"
SELECT@103..115
SPACE@103..104 " "
REF@104..105
NAME@104..105
IDENT@104..105 "c"
DOT@105..106 "."
ATTR_PATH@106..108
IDENT@106..107 "d"
NAME@106..107
IDENT@106..107 "d"
SPACE@107..108 " "
KW_OR@108..110 "or"
SPACE@110..111 " "
REF@111..112
NAME@111..112
IDENT@111..112 "e"
SPACE@112..115 "\n "
SELECT@115..119
REF@115..116
NAME@115..116
IDENT@115..116 "f"
DOT@116..117 "."
ATTR_PATH@117..119
IDENT@117..118 "g"
NAME@117..118
IDENT@117..118 "g"
SPACE@118..119 "\n"
R_BRACK@119..120 "]"
SPACE@120..121 "\n"

View file

@ -4,13 +4,15 @@ SOURCE_FILE@0..160
SPACE@3..6 "\n "
ATTR_PATH_VALUE@6..27
ATTR_PATH@6..23
IDENT@6..7 "a"
NAME@6..7
IDENT@6..7 "a"
DOT@7..8 "."
IDENT@8..9 "b"
NAME@8..9
IDENT@8..9 "b"
DOT@9..10 "."
DYNAMIC@10..14
DOLLAR_L_CURLY@10..12 "${"
REF@12..13
NAME@12..13
IDENT@12..13 "c"
R_CURLY@13..14 "}"
DOT@14..15 "."
@ -19,7 +21,7 @@ SOURCE_FILE@0..160
STRING_FRAGMENT@16..17 "d"
DYNAMIC@17..21
DOLLAR_L_CURLY@17..19 "${"
REF@19..20
NAME@19..20
IDENT@19..20 "e"
R_CURLY@20..21 "}"
DQUOTE@21..22 "\""
@ -33,11 +35,12 @@ SOURCE_FILE@0..160
INHERIT@30..49
KW_INHERIT@30..37 "inherit"
SPACE@37..38 " "
IDENT@38..39 "a"
NAME@38..39
IDENT@38..39 "a"
SPACE@39..40 " "
DYNAMIC@40..44
DOLLAR_L_CURLY@40..42 "${"
REF@42..43
NAME@42..43
IDENT@42..43 "b"
R_CURLY@43..44 "}"
SPACE@44..45 " "
@ -51,11 +54,12 @@ SOURCE_FILE@0..160
ATTR_PATH@52..61
DYNAMIC@52..58
DOLLAR_L_CURLY@52..54 "${"
REF@54..57
NAME@54..57
IDENT@54..57 "dyn"
R_CURLY@57..58 "}"
DOT@58..59 "."
IDENT@59..60 "a"
NAME@59..60
IDENT@59..60 "a"
SPACE@60..61 " "
EQ@61..62 "="
SPACE@62..63 " "
@ -69,16 +73,17 @@ SOURCE_FILE@0..160
PAREN@76..83
L_PAREN@76..77 "("
BINARY_OP@77..82
REF@77..78
NAME@77..78
IDENT@77..78 "a"
SPACE@78..79 " "
PLUS@79..80 "+"
SPACE@80..81 " "
REF@81..82
NAME@81..82
IDENT@81..82 "b"
R_PAREN@82..83 ")"
SPACE@83..84 " "
IDENT@84..85 "c"
NAME@84..85
IDENT@84..85 "c"
SEMICOLON@85..86 ";"
SPACE@86..87 "\n"
KW_IN@87..89 "in"
@ -89,14 +94,17 @@ SOURCE_FILE@0..160
INHERIT@94..104
KW_INHERIT@94..101 "inherit"
SPACE@101..102 " "
IDENT@102..103 "c"
NAME@102..103
IDENT@102..103 "c"
SEMICOLON@103..104 ";"
SPACE@104..107 "\n "
ATTR_PATH_VALUE@107..128
ATTR_PATH@107..111
IDENT@107..108 "d"
NAME@107..108
IDENT@107..108 "d"
DOT@108..109 "."
IDENT@109..110 "e"
NAME@109..110
IDENT@109..110 "e"
SPACE@110..111 " "
EQ@111..112 "="
SPACE@112..113 " "
@ -107,7 +115,8 @@ SOURCE_FILE@0..160
SPACE@118..119 " "
ATTR_PATH_VALUE@119..125
ATTR_PATH@119..121
IDENT@119..120 "f"
NAME@119..120
IDENT@119..120 "f"
SPACE@120..121 " "
EQ@121..122 "="
SPACE@122..123 " "
@ -122,7 +131,7 @@ SOURCE_FILE@0..160
ATTR_PATH@131..136
DYNAMIC@131..135
DOLLAR_L_CURLY@131..133 "${"
REF@133..134
NAME@133..134
IDENT@133..134 "f"
R_CURLY@134..135 "}"
SPACE@135..136 " "
@ -135,7 +144,8 @@ SOURCE_FILE@0..160
SPACE@143..144 " "
ATTR_PATH_VALUE@144..154
ATTR_PATH@144..149
IDENT@144..148 "body"
NAME@144..148
IDENT@144..148 "body"
SPACE@148..149 " "
EQ@149..150 "="
SPACE@150..151 " "

View file

@ -1,10 +1,11 @@
SOURCE_FILE@0..45
LET_IN@0..45
SOURCE_FILE@0..42
LET_IN@0..42
KW_LET@0..3 "let"
SPACE@3..4 " "
ATTR_PATH_VALUE@4..11
ATTR_PATH@4..7
IDENT@4..6 "or"
NAME@4..6
KW_OR@4..6 "or"
SPACE@6..7 " "
EQ@7..8 "="
SPACE@8..9 " "
@ -14,7 +15,7 @@ SOURCE_FILE@0..45
SPACE@11..12 " "
KW_IN@12..14 "in"
SPACE@14..15 " "
BINARY_OP@15..45
BINARY_OP@15..42
LIST@15..30
L_BRACK@15..16 "["
SPACE@16..17 " "
@ -25,7 +26,8 @@ SOURCE_FILE@0..45
R_CURLY@19..20 "}"
DOT@20..21 "."
ATTR_PATH@21..24
IDENT@21..23 "or"
NAME@21..23
KW_OR@21..23 "or"
SPACE@23..24 " "
KW_OR@24..26 "or"
SPACE@26..27 " "
@ -36,15 +38,18 @@ SOURCE_FILE@0..45
SPACE@30..31 " "
PLUS@31..32 "+"
SPACE@32..33 " "
APPLY@33..45
APPLY@33..42
REF@33..38
IDENT@33..38 "foldr"
SPACE@38..39 " "
REF@39..41
IDENT@39..41 "or"
SPACE@41..42 " "
ATTR_SET@42..44
L_CURLY@42..43 "{"
R_CURLY@43..44 "}"
SPACE@44..45 "\n"
APPLY@33..42
APPLY@33..39
NAME@33..34
IDENT@33..34 "f"
SPACE@34..35 " "
APPLY@35..39
NAME@35..36
IDENT@35..36 "a"
SPACE@36..37 " "
NAME@37..39
KW_OR@37..39 "or"
SPACE@39..40 " "
NAME@40..41
IDENT@40..41 "b"
SPACE@41..42 "\n"

View file

@ -1 +1 @@
let or = 1; in [ { }.or or 1 ] + foldr or {}
let or = 1; in [ { }.or or 1 ] + f a or b