aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.ron3
-rw-r--r--src/bin/gen.rs1
-rw-r--r--src/parser/event_parser/grammar.rs38
-rw-r--r--src/parser/event_parser/mod.rs3
-rw-r--r--src/parser/event_parser/parser.rs27
-rw-r--r--src/syntax_kinds.rs4
-rw-r--r--tests/data/parser/0002_struct_item_field.rs3
-rw-r--r--tests/data/parser/0002_struct_item_field.txt15
-rw-r--r--tests/parser.rs3
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;
6extern crate file; 6extern crate file;
7 7
8use std::path::PathBuf; 8use std::path::PathBuf;
9use std::ascii::AsciiExt;
10use std::fmt::Write; 9use std::fmt::Write;
11 10
12fn main() { 11fn 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 @@
1use super::Event;
2use super::parser::Parser; 1use super::parser::Parser;
3 2
4use syntax_kinds::*; 3use syntax_kinds::*;
@@ -50,10 +49,26 @@ fn item(p: &mut Parser) -> Result {
50 ERR 49 ERR
51} 50}
52 51
53fn struct_item(p: &mut Parser) -> Result{ 52fn 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
59fn 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
98fn ignore_errors<F: FnOnce() -> Result>(f: F) {
99 drop(f());
100}
101
102fn 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 @@
1use {Token, TextUnit, SyntaxKind}; 1use {Token, SyntaxKind};
2 2
3use syntax_kinds::*;
4mod grammar; 3mod grammar;
5mod parser; 4mod 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 @@
1use {Token, SyntaxKind, TextUnit}; 1use {Token, SyntaxKind, TextUnit};
2use super::{Event}; 2use super::{Event};
3use super::super::is_insignificant; 3use super::super::is_insignificant;
4use syntax_kinds::{WHITESPACE, COMMENT}; 4use syntax_kinds::{L_CURLY, R_CURLY, ERROR};
5 5
6pub struct Parser<'t> { 6pub 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
15impl<'t> Parser<'t> { 16impl<'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);
60pub const SHEBANG: SyntaxKind = SyntaxKind(56); 60pub const SHEBANG: SyntaxKind = SyntaxKind(56);
61pub const FILE: SyntaxKind = SyntaxKind(57); 61pub const FILE: SyntaxKind = SyntaxKind(57);
62pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58); 62pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58);
63pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59);
63 64
64static INFOS: [SyntaxInfo; 59] = [ 65static 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
126pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { 128pub(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 @@
1struct 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 @@
1FILE@[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 }