G: some attributes

This commit is contained in:
Aleksey Kladov 2018-01-07 21:40:18 +03:00
parent 5562931e4f
commit 7bc974ab2c
4 changed files with 83 additions and 32 deletions

View file

@ -66,5 +66,6 @@ Grammar(
"STRUCT_FIELD", "STRUCT_FIELD",
"FN_ITEM", "FN_ITEM",
"ATTR", "ATTR",
"META_ITEM",
] ]
) )

View file

@ -34,7 +34,7 @@ fn item(p: &mut Parser) {
fn struct_item(p: &mut Parser) { fn struct_item(p: &mut Parser) {
p.expect(IDENT) p.expect(IDENT)
&& p.curly_block(|p| comma_list(p, struct_field)); && p.curly_block(|p| comma_list(p, EOF, struct_field));
} }
fn struct_field(p: &mut Parser) -> bool { fn struct_field(p: &mut Parser) -> bool {
@ -52,19 +52,45 @@ fn fn_item(p: &mut Parser) {
// Paths, types, attributes, and stuff // // Paths, types, attributes, and stuff //
fn inner_attributes(p: &mut Parser) { fn inner_attributes(p: &mut Parser) {
many(p, inner_attribute) many(p, |p| attribute(p, true))
} }
fn inner_attribute(p: &mut Parser) -> bool { fn attribute(p: &mut Parser, inner: bool) -> bool {
if !(p.lookahead(&[EXCL, POUND])) { let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
|| !inner && p.lookahead(&[POUND, L_BRACK]);
if !attr_start {
return false; return false;
} }
node(p, ATTR, |p| { node(p, ATTR, |p| {
p.bump_n(2); p.bump_n(if inner { 3 } else { 2 });
meta_item(p) && p.expect(R_BRACK);
}); });
true true
} }
fn meta_item(p: &mut Parser) -> bool {
node_if(p, IDENT, META_ITEM, |p| {
if p.eat(EQ) {
if !literal(p) {
p.error()
.message("expected literal")
.emit();
}
} else if p.eat(L_PAREN) {
comma_list(p, R_PAREN, meta_item_inner);
p.expect(R_PAREN);
}
})
}
fn meta_item_inner(p: &mut Parser) -> bool {
meta_item(p) || literal(p)
}
fn literal(p: &mut Parser) -> bool {
p.eat(INT_NUMBER) || p.eat(FLOAT_NUMBER)
}
fn outer_attributes(_: &mut Parser) { fn outer_attributes(_: &mut Parser) {
} }
@ -75,7 +101,12 @@ fn visibility(_: &mut Parser) {
// Error recovery and high-order utils // // Error recovery and high-order utils //
fn node_if<F: FnOnce(&mut Parser)>(p: &mut Parser, first: SyntaxKind, node_kind: SyntaxKind, rest: F) -> bool { fn node_if<F: FnOnce(&mut Parser)>(
p: &mut Parser,
first: SyntaxKind,
node_kind: SyntaxKind,
rest: F
) -> bool {
p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true } p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true }
} }
@ -89,10 +120,9 @@ fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
while f(p) { } while f(p) { }
} }
fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) { fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) {
many(p, |p| { many(p, |p| {
f(p); if !f(p) || p.current() == end {
if p.current() == EOF {
false false
} else { } else {
p.expect(COMMA); p.expect(COMMA);
@ -157,4 +187,8 @@ impl<'p> Parser<'p> {
self.bump(); self.bump();
} }
} }
fn eat(&mut self, kind: SyntaxKind) -> bool {
self.current() == kind && { self.bump(); true }
}
} }

View file

@ -63,8 +63,9 @@ pub const STRUCT_ITEM: SyntaxKind = SyntaxKind(58);
pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59); pub const STRUCT_FIELD: SyntaxKind = SyntaxKind(59);
pub const FN_ITEM: SyntaxKind = SyntaxKind(60); pub const FN_ITEM: SyntaxKind = SyntaxKind(60);
pub const ATTR: SyntaxKind = SyntaxKind(61); pub const ATTR: SyntaxKind = SyntaxKind(61);
pub const META_ITEM: SyntaxKind = SyntaxKind(62);
static INFOS: [SyntaxInfo; 62] = [ static INFOS: [SyntaxInfo; 63] = [
SyntaxInfo { name: "USE_KW" }, SyntaxInfo { name: "USE_KW" },
SyntaxInfo { name: "FN_KW" }, SyntaxInfo { name: "FN_KW" },
SyntaxInfo { name: "STRUCT_KW" }, SyntaxInfo { name: "STRUCT_KW" },
@ -127,6 +128,7 @@ static INFOS: [SyntaxInfo; 62] = [
SyntaxInfo { name: "STRUCT_FIELD" }, SyntaxInfo { name: "STRUCT_FIELD" },
SyntaxInfo { name: "FN_ITEM" }, SyntaxInfo { name: "FN_ITEM" },
SyntaxInfo { name: "ATTR" }, SyntaxInfo { name: "ATTR" },
SyntaxInfo { name: "META_ITEM" },
]; ];
pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {

View file

@ -1,44 +1,58 @@
FILE@[0; 236) FILE@[0; 236)
ERROR@[0; 236) ATTR@[0; 9)
err: `expected item`
POUND@[0; 1) POUND@[0; 1)
EXCL@[1; 2) EXCL@[1; 2)
L_BRACK@[2; 3) L_BRACK@[2; 3)
IDENT@[3; 7) META_ITEM@[3; 7)
IDENT@[3; 7)
R_BRACK@[7; 8) R_BRACK@[7; 8)
WHITESPACE@[8; 9) WHITESPACE@[8; 9)
ATTR@[9; 24)
POUND@[9; 10) POUND@[9; 10)
EXCL@[10; 11) EXCL@[10; 11)
L_BRACK@[11; 12) L_BRACK@[11; 12)
IDENT@[12; 16) META_ITEM@[12; 22)
L_PAREN@[16; 17) IDENT@[12; 16)
IDENT@[17; 21) L_PAREN@[16; 17)
R_PAREN@[21; 22) META_ITEM@[17; 21)
IDENT@[17; 21)
R_PAREN@[21; 22)
R_BRACK@[22; 23) R_BRACK@[22; 23)
WHITESPACE@[23; 24) WHITESPACE@[23; 24)
ATTR@[24; 40)
POUND@[24; 25) POUND@[24; 25)
EXCL@[25; 26) EXCL@[25; 26)
L_BRACK@[26; 27) L_BRACK@[26; 27)
IDENT@[27; 31) META_ITEM@[27; 38)
L_PAREN@[31; 32) IDENT@[27; 31)
IDENT@[32; 37) L_PAREN@[31; 32)
R_PAREN@[37; 38) META_ITEM@[32; 37)
IDENT@[32; 37)
R_PAREN@[37; 38)
R_BRACK@[38; 39) R_BRACK@[38; 39)
WHITESPACE@[39; 40) WHITESPACE@[39; 40)
ATTR@[40; 66)
POUND@[40; 41) POUND@[40; 41)
EXCL@[41; 42) EXCL@[41; 42)
L_BRACK@[42; 43) L_BRACK@[42; 43)
IDENT@[43; 47) META_ITEM@[43; 66)
L_PAREN@[47; 48) IDENT@[43; 47)
IDENT@[48; 53) L_PAREN@[47; 48)
COMMA@[53; 54) META_ITEM@[48; 53)
WHITESPACE@[54; 55) IDENT@[48; 53)
INT_NUMBER@[55; 58) COMMA@[53; 54)
COMMA@[58; 59) WHITESPACE@[54; 55)
WHITESPACE@[59; 60) INT_NUMBER@[55; 58)
IDENT@[60; 64) COMMA@[58; 59)
COMMA@[64; 65) META_ITEM@[59; 64)
WHITESPACE@[65; 66) WHITESPACE@[59; 60)
IDENT@[60; 64)
COMMA@[64; 65)
err: `expected R_PAREN`
WHITESPACE@[65; 66)
err: `expected R_BRACK`
ERROR@[66; 236)
err: `expected item`
STRING@[66; 72) STRING@[66; 72)
COMMA@[72; 73) COMMA@[72; 73)
WHITESPACE@[73; 74) WHITESPACE@[73; 74)