From 55891be06a1f0a051638cb59f1d15167faf5ab82 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 13 Jan 2018 13:42:19 +0300 Subject: G: use trees --- src/parser/event_parser/grammar/items.rs | 56 +++++++++++++++++++++++++++++++- src/parser/event_parser/grammar/paths.rs | 22 +++++++++---- src/parser/mod.rs | 2 +- src/syntax_kinds.rs | 14 ++++---- 4 files changed, 80 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index f7310c09a..2f64111ab 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs @@ -74,9 +74,63 @@ fn mod_item(p: &mut Parser) { p.curly_block(mod_contents); } +pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { + kind == STAR || kind == L_CURLY +} + fn use_item(p: &mut Parser) { - paths::use_path(p); + use_tree(p); p.expect(SEMI); + + fn use_tree(p: &mut Parser) -> bool{ + if node_if(p, STAR, USE_TREE, |_| ()) { + return true + } + if node_if(p, [COLONCOLON, STAR], USE_TREE, |_| ()) { + return true + } + if [COLONCOLON, L_CURLY].is_ahead(p) || L_CURLY.is_ahead(p) { + node(p, USE_TREE, |p| { + p.eat(COLONCOLON); + p.curly_block(|p| { + comma_list(p, EOF, use_tree); + }); + }); + return true; + } + if paths::is_path_start(p) { + node(p, USE_TREE, |p| { + paths::use_path(p); + match p.current() { + AS_KW => { + alias(p); + } + COLONCOLON => { + p.bump(); + match p.current() { + STAR => { + p.bump(); + } + L_CURLY => { + p.curly_block(|p| { + comma_list(p, EOF, use_tree); + }); + } + _ => { + // is this unreachable? + p.error() + .message("expected `{` or `*`") + .emit(); + } + } + } + _ => (), + } + }); + return true; + } + false + } } fn struct_field(p: &mut Parser) -> bool { diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs index d6887a9ba..62d1a3bb2 100644 --- a/src/parser/event_parser/grammar/paths.rs +++ b/src/parser/event_parser/grammar/paths.rs @@ -1,7 +1,11 @@ use super::*; +pub (crate) fn is_path_start(p: &Parser) -> bool { + AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) +} + pub(crate) fn use_path(p: &mut Parser) { - if !AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) { + if !is_path_start(p) { return; } let mut prev = p.mark(); @@ -10,11 +14,17 @@ pub(crate) fn use_path(p: &mut Parser) { }); many(p, |p| { let curr = p.mark(); - node_if(p, COLONCOLON, PATH, |p| { - path_segment(p, false); - p.forward_parent(prev, curr); - prev = curr; - }) + if p.current() == COLONCOLON && !items::is_use_tree_start(p.raw_lookahead(1)) { + node(p, PATH, |p| { + p.bump(); + path_segment(p, false); + p.forward_parent(prev, curr); + prev = curr; + }); + true + } else { + false + } }); } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index c08d32d08..0c29442f9 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -29,7 +29,7 @@ fn from_events_to_file( } match event { - &Event::Start { kind, forward_parent } => { + &Event::Start { .. } => { forward_parents.clear(); let mut idx = i; loop { diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 48f55fa97..8bc63a210 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -77,13 +77,14 @@ pub const ATTR: SyntaxKind = SyntaxKind(72); pub const META_ITEM: SyntaxKind = SyntaxKind(73); pub const MOD_ITEM: SyntaxKind = SyntaxKind(74); pub const USE_ITEM: SyntaxKind = SyntaxKind(75); -pub const PATH: SyntaxKind = SyntaxKind(76); -pub const PATH_SEGMENT: SyntaxKind = SyntaxKind(77); -pub const LITERAL: SyntaxKind = SyntaxKind(78); -pub const ALIAS: SyntaxKind = SyntaxKind(79); -pub const VISIBILITY: SyntaxKind = SyntaxKind(80); +pub const USE_TREE: SyntaxKind = SyntaxKind(76); +pub const PATH: SyntaxKind = SyntaxKind(77); +pub const PATH_SEGMENT: SyntaxKind = SyntaxKind(78); +pub const LITERAL: SyntaxKind = SyntaxKind(79); +pub const ALIAS: SyntaxKind = SyntaxKind(80); +pub const VISIBILITY: SyntaxKind = SyntaxKind(81); -static INFOS: [SyntaxInfo; 81] = [ +static INFOS: [SyntaxInfo; 82] = [ SyntaxInfo { name: "USE_KW" }, SyntaxInfo { name: "FN_KW" }, SyntaxInfo { name: "STRUCT_KW" }, @@ -160,6 +161,7 @@ static INFOS: [SyntaxInfo; 81] = [ SyntaxInfo { name: "META_ITEM" }, SyntaxInfo { name: "MOD_ITEM" }, SyntaxInfo { name: "USE_ITEM" }, + SyntaxInfo { name: "USE_TREE" }, SyntaxInfo { name: "PATH" }, SyntaxInfo { name: "PATH_SEGMENT" }, SyntaxInfo { name: "LITERAL" }, -- cgit v1.2.3