G: struct fields

This commit is contained in:
Aleksey Kladov 2018-01-06 17:16:00 +03:00
parent 55602727c8
commit d0900b3ca7
9 changed files with 86 additions and 11 deletions

View file

@ -62,6 +62,7 @@ Grammar(
],
nodes: [
"FILE",
"STRUCT_ITEM"
"STRUCT_ITEM",
"STRUCT_FIELD",
]
)

View file

@ -6,7 +6,6 @@ extern crate ron;
extern crate file;
use std::path::PathBuf;
use std::ascii::AsciiExt;
use std::fmt::Write;
fn main() {

View file

@ -1,4 +1,3 @@
use super::Event;
use super::parser::Parser;
use syntax_kinds::*;
@ -52,8 +51,24 @@ fn 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 //
@ -79,3 +94,18 @@ fn skip_one_token(p: &mut Parser) {
p.bump().unwrap();
p.finish();
}
fn ignore_errors<F: FnOnce() -> Result>(f: F) {
drop(f());
}
fn comma_list<F: Fn(&mut Parser) -> Result>(p: &mut Parser, element: F) {
loop {
if element(p).is_err() {
return
}
if p.expect(COMMA).is_err() {
return
}
}
}

View file

@ -1,6 +1,5 @@
use {Token, TextUnit, SyntaxKind};
use {Token, SyntaxKind};
use syntax_kinds::*;
mod grammar;
mod parser;

View file

@ -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<Event>,
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<SyntaxKind> {
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<F: FnOnce(&mut Parser)>(&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)
}

View file

@ -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 {

View file

@ -0,0 +1,3 @@
struct S {
foo: u32
}

View file

@ -0,0 +1,15 @@
FILE@[0; 25)
STRUCT_ITEM@[0; 25)
STRUCT_KW@[0; 6)
WHITESPACE@[6; 7)
IDENT@[7; 8)
WHITESPACE@[8; 9)
L_CURLY@[9; 10)
STRUCT_FIELD@[10; 24)
WHITESPACE@[10; 15)
IDENT@[15; 18)
COLON@[18; 19)
WHITESPACE@[19; 20)
IDENT@[20; 23)
WHITESPACE@[23; 24)
R_CURLY@[24; 25)

View file

@ -61,7 +61,8 @@ fn dump_tree(file: &File) -> String {
fn go(node: Node, buff: &mut String, level: usize) {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "{:?}\n", node);
write!(buff, "{:?}\n", node)
.unwrap();
for child in node.children() {
go(child, buff, level + 1)
}