diff options
Diffstat (limited to 'src/parser/grammar')
-rw-r--r-- | src/parser/grammar/attributes.rs | 4 | ||||
-rw-r--r-- | src/parser/grammar/expressions.rs | 61 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 2 |
3 files changed, 50 insertions, 17 deletions
diff --git a/src/parser/grammar/attributes.rs b/src/parser/grammar/attributes.rs index 7f1c0401a..c411d4d7f 100644 --- a/src/parser/grammar/attributes.rs +++ b/src/parser/grammar/attributes.rs | |||
@@ -36,7 +36,7 @@ fn meta_item(p: &mut Parser) { | |||
36 | match p.current() { | 36 | match p.current() { |
37 | EQ => { | 37 | EQ => { |
38 | p.bump(); | 38 | p.bump(); |
39 | if !expressions::literal(p) { | 39 | if expressions::literal(p).is_none() { |
40 | p.error("expected literal"); | 40 | p.error("expected literal"); |
41 | } | 41 | } |
42 | } | 42 | } |
@@ -56,7 +56,7 @@ fn meta_item_arg_list(p: &mut Parser) { | |||
56 | match p.current() { | 56 | match p.current() { |
57 | EOF | R_PAREN => break, | 57 | EOF | R_PAREN => break, |
58 | IDENT => meta_item(p), | 58 | IDENT => meta_item(p), |
59 | c => if !expressions::literal(p) { | 59 | c => if expressions::literal(p).is_none() { |
60 | let message = "expected attribute"; | 60 | let message = "expected attribute"; |
61 | 61 | ||
62 | if items::ITEM_FIRST.contains(c) { | 62 | if items::ITEM_FIRST.contains(c) { |
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs index ece698248..92aaafa3d 100644 --- a/src/parser/grammar/expressions.rs +++ b/src/parser/grammar/expressions.rs | |||
@@ -13,39 +13,72 @@ use super::*; | |||
13 | // let _ = b"e"; | 13 | // let _ = b"e"; |
14 | // let _ = br"f"; | 14 | // let _ = br"f"; |
15 | // } | 15 | // } |
16 | pub(super) fn literal(p: &mut Parser) -> bool { | 16 | pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { |
17 | match p.current() { | 17 | match p.current() { |
18 | TRUE_KW | FALSE_KW | INT_NUMBER | FLOAT_NUMBER | BYTE | CHAR | STRING | RAW_STRING | 18 | TRUE_KW | FALSE_KW | INT_NUMBER | FLOAT_NUMBER | BYTE | CHAR | STRING | RAW_STRING |
19 | | BYTE_STRING | RAW_BYTE_STRING => { | 19 | | BYTE_STRING | RAW_BYTE_STRING => { |
20 | let lit = p.start(); | 20 | let m = p.start(); |
21 | p.bump(); | 21 | p.bump(); |
22 | lit.complete(p, LITERAL); | 22 | Some(m.complete(p, LITERAL)) |
23 | true | ||
24 | } | 23 | } |
25 | _ => false, | 24 | _ => None, |
26 | } | 25 | } |
27 | } | 26 | } |
28 | 27 | ||
29 | pub(super) fn expr(p: &mut Parser) { | 28 | pub(super) fn expr(p: &mut Parser) { |
30 | if literal(p) { | 29 | let mut lhs = atom_expr(p); |
31 | return; | 30 | |
31 | while let Some(m) = lhs { | ||
32 | match p.current() { | ||
33 | L_PAREN => lhs = Some(call_expr(p, m)), | ||
34 | _ => break, | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | |||
39 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | ||
40 | match literal(p) { | ||
41 | Some(m) => return Some(m), | ||
42 | None => (), | ||
32 | } | 43 | } |
33 | if paths::is_path_start(p) { | 44 | if paths::is_path_start(p) { |
34 | return path_expr(p); | 45 | return Some(path_expr(p)); |
35 | } | 46 | } |
36 | 47 | ||
37 | match p.current() { | 48 | match p.current() { |
38 | L_PAREN => tuple_expr(p), | 49 | L_PAREN => Some(tuple_expr(p)), |
39 | _ => p.error("expected expression"), | 50 | _ => { |
51 | p.error("expected expression"); | ||
52 | None | ||
53 | } | ||
40 | } | 54 | } |
41 | } | 55 | } |
42 | 56 | ||
43 | fn tuple_expr(p: &mut Parser) { | 57 | fn tuple_expr(p: &mut Parser) -> CompletedMarker { |
44 | assert!(p.at(L_PAREN)); | 58 | assert!(p.at(L_PAREN)); |
45 | let m = p.start(); | 59 | let m = p.start(); |
46 | p.expect(L_PAREN); | 60 | p.expect(L_PAREN); |
47 | p.expect(R_PAREN); | 61 | p.expect(R_PAREN); |
48 | m.complete(p, TUPLE_EXPR); | 62 | m.complete(p, TUPLE_EXPR) |
63 | } | ||
64 | |||
65 | // test call_expr | ||
66 | // fn foo() { | ||
67 | // let _ = f(); | ||
68 | // let _ = f()(1)(1, 2,); | ||
69 | // } | ||
70 | fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
71 | assert!(p.at(L_PAREN)); | ||
72 | let m = lhs.precede(p); | ||
73 | p.bump(); | ||
74 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
75 | expr(p); | ||
76 | if !p.at(R_PAREN) && !p.expect(COMMA) { | ||
77 | break; | ||
78 | } | ||
79 | } | ||
80 | p.eat(R_PAREN); | ||
81 | m.complete(p, CALL_EXPR) | ||
49 | } | 82 | } |
50 | 83 | ||
51 | // test path_expr | 84 | // test path_expr |
@@ -54,9 +87,9 @@ fn tuple_expr(p: &mut Parser) { | |||
54 | // let _ = a::b; | 87 | // let _ = a::b; |
55 | // let _ = ::a::<b>; | 88 | // let _ = ::a::<b>; |
56 | // } | 89 | // } |
57 | fn path_expr(p: &mut Parser) { | 90 | fn path_expr(p: &mut Parser) -> CompletedMarker { |
58 | assert!(paths::is_path_start(p)); | 91 | assert!(paths::is_path_start(p)); |
59 | let m = p.start(); | 92 | let m = p.start(); |
60 | paths::expr_path(p); | 93 | paths::expr_path(p); |
61 | m.complete(p, PATH_EXPR); | 94 | m.complete(p, PATH_EXPR) |
62 | } | 95 | } |
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index e4823eadb..63ad2782e 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs | |||
@@ -31,7 +31,7 @@ mod type_args; | |||
31 | mod types; | 31 | mod types; |
32 | 32 | ||
33 | use { | 33 | use { |
34 | parser::{parser::Parser, token_set::TokenSet}, | 34 | parser::{parser::{Parser, CompletedMarker}, token_set::TokenSet}, |
35 | SyntaxKind::{self, *}, | 35 | SyntaxKind::{self, *}, |
36 | }; | 36 | }; |
37 | 37 | ||