From d0900b3ca7be669418e185c0eea0d92550d83d4d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 6 Jan 2018 17:16:00 +0300 Subject: G: struct fields --- src/bin/gen.rs | 1 - src/parser/event_parser/grammar.rs | 38 ++++++++++++++++++++++++++++++++++---- src/parser/event_parser/mod.rs | 3 +-- src/parser/event_parser/parser.rs | 27 ++++++++++++++++++++++++++- src/syntax_kinds.rs | 4 +++- 5 files changed, 64 insertions(+), 9 deletions(-) (limited to 'src') 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; extern crate file; use std::path::PathBuf; -use std::ascii::AsciiExt; use std::fmt::Write; 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 @@ -use super::Event; use super::parser::Parser; use syntax_kinds::*; @@ -50,10 +49,26 @@ fn item(p: &mut Parser) -> Result { ERR } -fn struct_item(p: &mut Parser) -> Result{ +fn struct_item(p: &mut Parser) -> Result { p.expect(IDENT)?; - p.expect(L_CURLY)?; - p.expect(R_CURLY) + p.curly_block(|p| { + comma_list(p, struct_field) + }) +} + +fn struct_field(p: &mut Parser) -> Result { + if !p.current_is(IDENT) { + return ERR; + } + p.start(STRUCT_FIELD); + p.bump(); + ignore_errors(|| { + p.expect(COLON)?; + p.expect(IDENT)?; + OK + }); + p.finish(); + OK } // Paths, types, attributes, and stuff // @@ -78,4 +93,19 @@ fn skip_one_token(p: &mut Parser) { p.start(ERROR); p.bump().unwrap(); p.finish(); +} + +fn ignore_errors Result>(f: F) { + drop(f()); +} + +fn comma_list Result>(p: &mut Parser, element: F) { + loop { + if element(p).is_err() { + return + } + if p.expect(COMMA).is_err() { + return + } + } } \ 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 @@ -use {Token, TextUnit, SyntaxKind}; +use {Token, SyntaxKind}; -use syntax_kinds::*; mod grammar; mod parser; 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 @@ use {Token, SyntaxKind, TextUnit}; use super::{Event}; use super::super::is_insignificant; -use syntax_kinds::{WHITESPACE, COMMENT}; +use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; pub struct Parser<'t> { text: &'t str, @@ -10,6 +10,7 @@ pub struct Parser<'t> { pos: usize, events: Vec, + curly_level: i32, } impl<'t> Parser<'t> { @@ -30,6 +31,7 @@ impl<'t> Parser<'t> { pos: 0, events: Vec::new(), + curly_level: 0, } } @@ -64,6 +66,11 @@ impl<'t> Parser<'t> { pub(crate) fn bump(&mut self) -> Option { let kind = self.current()?; + match kind { + L_CURLY => self.curly_level += 1, + R_CURLY => self.curly_level -= 1, + _ => (), + } self.pos += 1; self.event(Event::Token { kind, n_raw_tokens: 1 }); Some(kind) @@ -78,6 +85,24 @@ impl<'t> Parser<'t> { } } + pub(crate) fn curly_block(&mut self, f: F) -> Result<(), ()> { + let level = self.curly_level; + self.expect(L_CURLY)?; + f(self); + assert!(self.curly_level > level); + if self.expect(R_CURLY).is_ok() { + return Ok(()); + } + self.start(ERROR); + while self.curly_level > level { + if self.bump().is_none() { + break; + } + } + self.finish(); + Ok(()) //??? + } + fn event(&mut self, event: Event) { self.events.push(event) } 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); pub const SHEBANG: SyntaxKind = SyntaxKind(56); pub const FILE: SyntaxKind = SyntaxKind(57); pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58); +pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59); -static INFOS: [SyntaxInfo; 59] = [ +static INFOS: [SyntaxInfo; 60] = [ SyntaxInfo { name: "USE_KW" }, SyntaxInfo { name: "FN_KW" }, SyntaxInfo { name: "STRUCT_KW" }, @@ -121,6 +122,7 @@ static INFOS: [SyntaxInfo; 59] = [ SyntaxInfo { name: "SHEBANG" }, SyntaxInfo { name: "FILE" }, SyntaxInfo { name: "STRUCT_ITEM" }, + SyntaxInfo { name: "STRUCT_FIELD" }, ]; pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { -- cgit v1.2.3