From 7912189ec304b28c4df0030b5282cf3d21074154 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 31 Jul 2018 23:38:19 +0300 Subject: reorganize --- src/grammar/attributes.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/grammar/attributes.rs (limited to 'src/grammar/attributes.rs') diff --git a/src/grammar/attributes.rs b/src/grammar/attributes.rs new file mode 100644 index 000000000..c411d4d7f --- /dev/null +++ b/src/grammar/attributes.rs @@ -0,0 +1,79 @@ +use super::*; + +pub(super) fn inner_attributes(p: &mut Parser) { + while p.current() == POUND && p.nth(1) == EXCL { + attribute(p, true) + } +} + +pub(super) fn outer_attributes(p: &mut Parser) { + while p.at(POUND) { + attribute(p, false) + } +} + +fn attribute(p: &mut Parser, inner: bool) { + let attr = p.start(); + assert!(p.at(POUND)); + p.bump(); + + if inner { + assert!(p.at(EXCL)); + p.bump(); + } + + if p.expect(L_BRACK) { + meta_item(p); + p.expect(R_BRACK); + } + attr.complete(p, ATTR); +} + +fn meta_item(p: &mut Parser) { + if p.at(IDENT) { + let meta_item = p.start(); + p.bump(); + match p.current() { + EQ => { + p.bump(); + if expressions::literal(p).is_none() { + p.error("expected literal"); + } + } + L_PAREN => meta_item_arg_list(p), + _ => (), + } + meta_item.complete(p, META_ITEM); + } else { + p.error("expected attribute value"); + } +} + +fn meta_item_arg_list(p: &mut Parser) { + assert!(p.at(L_PAREN)); + p.bump(); + loop { + match p.current() { + EOF | R_PAREN => break, + IDENT => meta_item(p), + c => if expressions::literal(p).is_none() { + let message = "expected attribute"; + + if items::ITEM_FIRST.contains(c) { + p.error(message); + return; + } + + let err = p.start(); + p.error(message); + p.bump(); + err.complete(p, ERROR); + continue; + }, + } + if !p.at(R_PAREN) { + p.expect(COMMA); + } + } + p.expect(R_PAREN); +} -- cgit v1.2.3