diff options
-rw-r--r-- | grammar.ron | 3 | ||||
-rw-r--r-- | src/bin/gen.rs | 1 | ||||
-rw-r--r-- | src/parser/event_parser/grammar.rs | 38 | ||||
-rw-r--r-- | src/parser/event_parser/mod.rs | 3 | ||||
-rw-r--r-- | src/parser/event_parser/parser.rs | 27 | ||||
-rw-r--r-- | src/syntax_kinds.rs | 4 | ||||
-rw-r--r-- | tests/data/parser/0002_struct_item_field.rs | 3 | ||||
-rw-r--r-- | tests/data/parser/0002_struct_item_field.txt | 15 | ||||
-rw-r--r-- | tests/parser.rs | 3 |
9 files changed, 86 insertions, 11 deletions
diff --git a/grammar.ron b/grammar.ron index c4f6283e6..18af8d123 100644 --- a/grammar.ron +++ b/grammar.ron | |||
@@ -62,6 +62,7 @@ Grammar( | |||
62 | ], | 62 | ], |
63 | nodes: [ | 63 | nodes: [ |
64 | "FILE", | 64 | "FILE", |
65 | "STRUCT_ITEM" | 65 | "STRUCT_ITEM", |
66 | "STRUCT_FIELD", | ||
66 | ] | 67 | ] |
67 | ) \ No newline at end of file | 68 | ) \ No newline at end of file |
diff --git a/src/bin/gen.rs b/src/bin/gen.rs index 9d7f7e389..5ebf3e2e8 100644 --- a/src/bin/gen.rs +++ b/src/bin/gen.rs | |||
@@ -6,7 +6,6 @@ extern crate ron; | |||
6 | extern crate file; | 6 | extern crate file; |
7 | 7 | ||
8 | use std::path::PathBuf; | 8 | use std::path::PathBuf; |
9 | use std::ascii::AsciiExt; | ||
10 | use std::fmt::Write; | 9 | use std::fmt::Write; |
11 | 10 | ||
12 | fn main() { | 11 | fn main() { |
diff --git a/src/parser/event_parser/grammar.rs b/src/parser/event_parser/grammar.rs index be61483ec..77596fea6 100644 --- a/src/parser/event_parser/grammar.rs +++ b/src/parser/event_parser/grammar.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use super::Event; | ||
2 | use super::parser::Parser; | 1 | use super::parser::Parser; |
3 | 2 | ||
4 | use syntax_kinds::*; | 3 | use syntax_kinds::*; |
@@ -50,10 +49,26 @@ fn item(p: &mut Parser) -> Result { | |||
50 | ERR | 49 | ERR |
51 | } | 50 | } |
52 | 51 | ||
53 | fn struct_item(p: &mut Parser) -> Result{ | 52 | fn struct_item(p: &mut Parser) -> Result { |
54 | p.expect(IDENT)?; | 53 | p.expect(IDENT)?; |
55 | p.expect(L_CURLY)?; | 54 | p.curly_block(|p| { |
56 | p.expect(R_CURLY) | 55 | comma_list(p, struct_field) |
56 | }) | ||
57 | } | ||
58 | |||
59 | fn struct_field(p: &mut Parser) -> Result { | ||
60 | if !p.current_is(IDENT) { | ||
61 | return ERR; | ||
62 | } | ||
63 | p.start(STRUCT_FIELD); | ||
64 | p.bump(); | ||
65 | ignore_errors(|| { | ||
66 | p.expect(COLON)?; | ||
67 | p.expect(IDENT)?; | ||
68 | OK | ||
69 | }); | ||
70 | p.finish(); | ||
71 | OK | ||
57 | } | 72 | } |
58 | 73 | ||
59 | // Paths, types, attributes, and stuff // | 74 | // Paths, types, attributes, and stuff // |
@@ -78,4 +93,19 @@ fn skip_one_token(p: &mut Parser) { | |||
78 | p.start(ERROR); | 93 | p.start(ERROR); |
79 | p.bump().unwrap(); | 94 | p.bump().unwrap(); |
80 | p.finish(); | 95 | p.finish(); |
96 | } | ||
97 | |||
98 | fn ignore_errors<F: FnOnce() -> Result>(f: F) { | ||
99 | drop(f()); | ||
100 | } | ||
101 | |||
102 | fn comma_list<F: Fn(&mut Parser) -> Result>(p: &mut Parser, element: F) { | ||
103 | loop { | ||
104 | if element(p).is_err() { | ||
105 | return | ||
106 | } | ||
107 | if p.expect(COMMA).is_err() { | ||
108 | return | ||
109 | } | ||
110 | } | ||
81 | } \ No newline at end of file | 111 | } \ No newline at end of file |
diff --git a/src/parser/event_parser/mod.rs b/src/parser/event_parser/mod.rs index 1228236a9..3c3654b6b 100644 --- a/src/parser/event_parser/mod.rs +++ b/src/parser/event_parser/mod.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use {Token, TextUnit, SyntaxKind}; | 1 | use {Token, SyntaxKind}; |
2 | 2 | ||
3 | use syntax_kinds::*; | ||
4 | mod grammar; | 3 | mod grammar; |
5 | mod parser; | 4 | mod parser; |
6 | 5 | ||
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index 36452ef67..04ef4fb28 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use {Token, SyntaxKind, TextUnit}; | 1 | use {Token, SyntaxKind, TextUnit}; |
2 | use super::{Event}; | 2 | use super::{Event}; |
3 | use super::super::is_insignificant; | 3 | use super::super::is_insignificant; |
4 | use syntax_kinds::{WHITESPACE, COMMENT}; | 4 | use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; |
5 | 5 | ||
6 | pub struct Parser<'t> { | 6 | pub struct Parser<'t> { |
7 | text: &'t str, | 7 | text: &'t str, |
@@ -10,6 +10,7 @@ pub struct Parser<'t> { | |||
10 | 10 | ||
11 | pos: usize, | 11 | pos: usize, |
12 | events: Vec<Event>, | 12 | events: Vec<Event>, |
13 | curly_level: i32, | ||
13 | } | 14 | } |
14 | 15 | ||
15 | impl<'t> Parser<'t> { | 16 | impl<'t> Parser<'t> { |
@@ -30,6 +31,7 @@ impl<'t> Parser<'t> { | |||
30 | 31 | ||
31 | pos: 0, | 32 | pos: 0, |
32 | events: Vec::new(), | 33 | events: Vec::new(), |
34 | curly_level: 0, | ||
33 | } | 35 | } |
34 | } | 36 | } |
35 | 37 | ||
@@ -64,6 +66,11 @@ impl<'t> Parser<'t> { | |||
64 | 66 | ||
65 | pub(crate) fn bump(&mut self) -> Option<SyntaxKind> { | 67 | pub(crate) fn bump(&mut self) -> Option<SyntaxKind> { |
66 | let kind = self.current()?; | 68 | let kind = self.current()?; |
69 | match kind { | ||
70 | L_CURLY => self.curly_level += 1, | ||
71 | R_CURLY => self.curly_level -= 1, | ||
72 | _ => (), | ||
73 | } | ||
67 | self.pos += 1; | 74 | self.pos += 1; |
68 | self.event(Event::Token { kind, n_raw_tokens: 1 }); | 75 | self.event(Event::Token { kind, n_raw_tokens: 1 }); |
69 | Some(kind) | 76 | Some(kind) |
@@ -78,6 +85,24 @@ impl<'t> Parser<'t> { | |||
78 | } | 85 | } |
79 | } | 86 | } |
80 | 87 | ||
88 | pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> Result<(), ()> { | ||
89 | let level = self.curly_level; | ||
90 | self.expect(L_CURLY)?; | ||
91 | f(self); | ||
92 | assert!(self.curly_level > level); | ||
93 | if self.expect(R_CURLY).is_ok() { | ||
94 | return Ok(()); | ||
95 | } | ||
96 | self.start(ERROR); | ||
97 | while self.curly_level > level { | ||
98 | if self.bump().is_none() { | ||
99 | break; | ||
100 | } | ||
101 | } | ||
102 | self.finish(); | ||
103 | Ok(()) //??? | ||
104 | } | ||
105 | |||
81 | fn event(&mut self, event: Event) { | 106 | fn event(&mut self, event: Event) { |
82 | self.events.push(event) | 107 | self.events.push(event) |
83 | } | 108 | } |
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index d9b1462a7..4a27b0eae 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs | |||
@@ -60,8 +60,9 @@ pub const DOC_COMMENT: SyntaxKind = SyntaxKind(55); | |||
60 | pub const SHEBANG: SyntaxKind = SyntaxKind(56); | 60 | pub const SHEBANG: SyntaxKind = SyntaxKind(56); |
61 | pub const FILE: SyntaxKind = SyntaxKind(57); | 61 | pub const FILE: SyntaxKind = SyntaxKind(57); |
62 | pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58); | 62 | pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58); |
63 | pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59); | ||
63 | 64 | ||
64 | static INFOS: [SyntaxInfo; 59] = [ | 65 | static INFOS: [SyntaxInfo; 60] = [ |
65 | SyntaxInfo { name: "USE_KW" }, | 66 | SyntaxInfo { name: "USE_KW" }, |
66 | SyntaxInfo { name: "FN_KW" }, | 67 | SyntaxInfo { name: "FN_KW" }, |
67 | SyntaxInfo { name: "STRUCT_KW" }, | 68 | SyntaxInfo { name: "STRUCT_KW" }, |
@@ -121,6 +122,7 @@ static INFOS: [SyntaxInfo; 59] = [ | |||
121 | SyntaxInfo { name: "SHEBANG" }, | 122 | SyntaxInfo { name: "SHEBANG" }, |
122 | SyntaxInfo { name: "FILE" }, | 123 | SyntaxInfo { name: "FILE" }, |
123 | SyntaxInfo { name: "STRUCT_ITEM" }, | 124 | SyntaxInfo { name: "STRUCT_ITEM" }, |
125 | SyntaxInfo { name: "STRUCT_FIELD" }, | ||
124 | ]; | 126 | ]; |
125 | 127 | ||
126 | pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { | 128 | pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { |
diff --git a/tests/data/parser/0002_struct_item_field.rs b/tests/data/parser/0002_struct_item_field.rs new file mode 100644 index 000000000..cc3866d25 --- /dev/null +++ b/tests/data/parser/0002_struct_item_field.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct S { | ||
2 | foo: u32 | ||
3 | } \ No newline at end of file | ||
diff --git a/tests/data/parser/0002_struct_item_field.txt b/tests/data/parser/0002_struct_item_field.txt new file mode 100644 index 000000000..b1673ade3 --- /dev/null +++ b/tests/data/parser/0002_struct_item_field.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | FILE@[0; 25) | ||
2 | STRUCT_ITEM@[0; 25) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | IDENT@[7; 8) | ||
6 | WHITESPACE@[8; 9) | ||
7 | L_CURLY@[9; 10) | ||
8 | STRUCT_FIELD@[10; 24) | ||
9 | WHITESPACE@[10; 15) | ||
10 | IDENT@[15; 18) | ||
11 | COLON@[18; 19) | ||
12 | WHITESPACE@[19; 20) | ||
13 | IDENT@[20; 23) | ||
14 | WHITESPACE@[23; 24) | ||
15 | R_CURLY@[24; 25) \ No newline at end of file | ||
diff --git a/tests/parser.rs b/tests/parser.rs index e71b48852..5c63be3be 100644 --- a/tests/parser.rs +++ b/tests/parser.rs | |||
@@ -61,7 +61,8 @@ fn dump_tree(file: &File) -> String { | |||
61 | 61 | ||
62 | fn go(node: Node, buff: &mut String, level: usize) { | 62 | fn go(node: Node, buff: &mut String, level: usize) { |
63 | buff.push_str(&String::from(" ").repeat(level)); | 63 | buff.push_str(&String::from(" ").repeat(level)); |
64 | write!(buff, "{:?}\n", node); | 64 | write!(buff, "{:?}\n", node) |
65 | .unwrap(); | ||
65 | for child in node.children() { | 66 | for child in node.children() { |
66 | go(child, buff, level + 1) | 67 | go(child, buff, level + 1) |
67 | } | 68 | } |