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",
"FN_ITEM",
"ATTR",
"META_ITEM",
]
)

View file

@ -34,7 +34,7 @@ fn item(p: &mut Parser) {
fn struct_item(p: &mut Parser) {
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 {
@ -52,19 +52,45 @@ fn fn_item(p: &mut Parser) {
// Paths, types, attributes, and stuff //
fn inner_attributes(p: &mut Parser) {
many(p, inner_attribute)
many(p, |p| attribute(p, true))
}
fn inner_attribute(p: &mut Parser) -> bool {
if !(p.lookahead(&[EXCL, POUND])) {
fn attribute(p: &mut Parser, inner: bool) -> bool {
let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
|| !inner && p.lookahead(&[POUND, L_BRACK]);
if !attr_start {
return false;
}
node(p, ATTR, |p| {
p.bump_n(2);
p.bump_n(if inner { 3 } else { 2 });
meta_item(p) && p.expect(R_BRACK);
});
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) {
}
@ -75,7 +101,12 @@ fn visibility(_: &mut Parser) {
// 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 }
}
@ -89,10 +120,9 @@ fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
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| {
f(p);
if p.current() == EOF {
if !f(p) || p.current() == end {
false
} else {
p.expect(COMMA);
@ -157,4 +187,8 @@ impl<'p> Parser<'p> {
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 FN_ITEM: SyntaxKind = SyntaxKind(60);
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: "FN_KW" },
SyntaxInfo { name: "STRUCT_KW" },
@ -127,6 +128,7 @@ static INFOS: [SyntaxInfo; 62] = [
SyntaxInfo { name: "STRUCT_FIELD" },
SyntaxInfo { name: "FN_ITEM" },
SyntaxInfo { name: "ATTR" },
SyntaxInfo { name: "META_ITEM" },
];
pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {

View file

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