mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 20:54:13 +00:00
Generalized lookahead
This commit is contained in:
parent
bdddfc9eb8
commit
0cf2d6afee
@ -9,16 +9,15 @@ pub(super) fn outer_attributes(_: &mut Parser) {
|
||||
|
||||
|
||||
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(if inner { 3 } else { 2 });
|
||||
fn attr_tail(p: &mut Parser) {
|
||||
meta_item(p) && p.expect(R_BRACK);
|
||||
});
|
||||
true
|
||||
}
|
||||
|
||||
if inner {
|
||||
node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail)
|
||||
} else {
|
||||
node_if(p, [POUND, L_BRACK], ATTR, attr_tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn meta_item(p: &mut Parser) -> bool {
|
||||
|
@ -1,16 +1,11 @@
|
||||
use super::*;
|
||||
|
||||
pub(super) fn literal(p: &mut Parser) -> bool {
|
||||
match p.current() {
|
||||
TRUE_KW | FALSE_KW
|
||||
| INT_NUMBER | FLOAT_NUMBER
|
||||
| BYTE | CHAR
|
||||
|STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => {
|
||||
node(p, LITERAL, |p| {
|
||||
p.bump();
|
||||
});
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
let literals = [
|
||||
TRUE_KW, FALSE_KW,
|
||||
INT_NUMBER, FLOAT_NUMBER,
|
||||
BYTE, CHAR,
|
||||
STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING,
|
||||
];
|
||||
node_if(p, AnyOf(&literals), LITERAL, |_| ())
|
||||
}
|
@ -58,7 +58,7 @@ fn struct_field(p: &mut Parser) -> bool {
|
||||
|
||||
fn fn_item(p: &mut Parser) {
|
||||
p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
|
||||
&& p.curly_block(|p| ());
|
||||
&& p.curly_block(|_| ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,13 +18,13 @@ pub(crate) fn file(p: &mut Parser) {
|
||||
fn visibility(_: &mut Parser) {
|
||||
}
|
||||
|
||||
fn node_if<F: FnOnce(&mut Parser)>(
|
||||
fn node_if<F: FnOnce(&mut Parser), L: Lookahead>(
|
||||
p: &mut Parser,
|
||||
first: SyntaxKind,
|
||||
first: L,
|
||||
node_kind: SyntaxKind,
|
||||
rest: F
|
||||
) -> bool {
|
||||
p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true }
|
||||
first.is_ahead(p) && { node(p, node_kind, |p| { L::consume(p); rest(p); }); true }
|
||||
}
|
||||
|
||||
fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) {
|
||||
@ -99,13 +99,63 @@ impl<'p> Parser<'p> {
|
||||
}
|
||||
}
|
||||
|
||||
fn bump_n(&mut self, n: u8) {
|
||||
for _ in 0..n {
|
||||
self.bump();
|
||||
}
|
||||
}
|
||||
|
||||
fn eat(&mut self, kind: SyntaxKind) -> bool {
|
||||
self.current() == kind && { self.bump(); true }
|
||||
}
|
||||
}
|
||||
|
||||
trait Lookahead: Copy {
|
||||
fn is_ahead(self, p: &Parser) -> bool;
|
||||
fn consume(p: &mut Parser);
|
||||
}
|
||||
|
||||
impl Lookahead for SyntaxKind {
|
||||
fn is_ahead(self, p: &Parser) -> bool {
|
||||
p.current() == self
|
||||
}
|
||||
|
||||
fn consume(p: &mut Parser) {
|
||||
p.bump();
|
||||
}
|
||||
}
|
||||
|
||||
impl Lookahead for [SyntaxKind; 2] {
|
||||
fn is_ahead(self, p: &Parser) -> bool {
|
||||
p.current() == self[0]
|
||||
&& p.raw_lookahead(1) == self[1]
|
||||
}
|
||||
|
||||
fn consume(p: &mut Parser) {
|
||||
p.bump();
|
||||
p.bump();
|
||||
}
|
||||
}
|
||||
|
||||
impl Lookahead for [SyntaxKind; 3] {
|
||||
fn is_ahead(self, p: &Parser) -> bool {
|
||||
p.current() == self[0]
|
||||
&& p.raw_lookahead(1) == self[1]
|
||||
&& p.raw_lookahead(2) == self[2]
|
||||
}
|
||||
|
||||
fn consume(p: &mut Parser) {
|
||||
p.bump();
|
||||
p.bump();
|
||||
p.bump();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct AnyOf<'a>(&'a [SyntaxKind]);
|
||||
|
||||
impl<'a> Lookahead for AnyOf<'a> {
|
||||
fn is_ahead(self, p: &Parser) -> bool {
|
||||
let curr = p.current();
|
||||
self.0.iter().any(|&k| k == curr)
|
||||
}
|
||||
|
||||
fn consume(p: &mut Parser) {
|
||||
p.bump();
|
||||
}
|
||||
|
||||
}
|
@ -88,12 +88,8 @@ impl<'t> Parser<'t> {
|
||||
kind
|
||||
}
|
||||
|
||||
pub(crate) fn lookahead(&self, kinds: &[SyntaxKind]) -> bool {
|
||||
if self.tokens[self.pos..].len() < kinds.len() {
|
||||
return false
|
||||
}
|
||||
kinds.iter().zip(self.tokens[self.pos..].iter().map(|t| t.kind))
|
||||
.all(|(&k1, k2)| k1 == k2)
|
||||
pub(crate) fn raw_lookahead(&self, n: usize) -> SyntaxKind {
|
||||
self.tokens.get(self.pos + n).map(|t| t.kind).unwrap_or(EOF)
|
||||
}
|
||||
|
||||
pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> bool {
|
||||
|
@ -56,4 +56,4 @@ fn is_insignificant(kind: SyntaxKind) -> bool {
|
||||
WHITESPACE | COMMENT => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user