mirror of https://github.com/rust-lang/rust.git
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 {
|
fn attribute(p: &mut Parser, inner: bool) -> bool {
|
||||||
let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
|
fn attr_tail(p: &mut Parser) {
|
||||||
|| !inner && p.lookahead(&[POUND, L_BRACK]);
|
|
||||||
if !attr_start {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
node(p, ATTR, |p| {
|
|
||||||
p.bump_n(if inner { 3 } else { 2 });
|
|
||||||
meta_item(p) && p.expect(R_BRACK);
|
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 {
|
fn meta_item(p: &mut Parser) -> bool {
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub(super) fn literal(p: &mut Parser) -> bool {
|
pub(super) fn literal(p: &mut Parser) -> bool {
|
||||||
match p.current() {
|
let literals = [
|
||||||
TRUE_KW | FALSE_KW
|
TRUE_KW, FALSE_KW,
|
||||||
| INT_NUMBER | FLOAT_NUMBER
|
INT_NUMBER, FLOAT_NUMBER,
|
||||||
| BYTE | CHAR
|
BYTE, CHAR,
|
||||||
|STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => {
|
STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING,
|
||||||
node(p, LITERAL, |p| {
|
];
|
||||||
p.bump();
|
node_if(p, AnyOf(&literals), LITERAL, |_| ())
|
||||||
});
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -58,7 +58,7 @@ fn struct_field(p: &mut Parser) -> bool {
|
||||||
|
|
||||||
fn fn_item(p: &mut Parser) {
|
fn fn_item(p: &mut Parser) {
|
||||||
p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
|
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 visibility(_: &mut Parser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_if<F: FnOnce(&mut Parser)>(
|
fn node_if<F: FnOnce(&mut Parser), L: Lookahead>(
|
||||||
p: &mut Parser,
|
p: &mut Parser,
|
||||||
first: SyntaxKind,
|
first: L,
|
||||||
node_kind: SyntaxKind,
|
node_kind: SyntaxKind,
|
||||||
rest: F
|
rest: F
|
||||||
) -> bool {
|
) -> 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) {
|
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 {
|
fn eat(&mut self, kind: SyntaxKind) -> bool {
|
||||||
self.current() == kind && { self.bump(); true }
|
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
|
kind
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lookahead(&self, kinds: &[SyntaxKind]) -> bool {
|
pub(crate) fn raw_lookahead(&self, n: usize) -> SyntaxKind {
|
||||||
if self.tokens[self.pos..].len() < kinds.len() {
|
self.tokens.get(self.pos + n).map(|t| t.kind).unwrap_or(EOF)
|
||||||
return false
|
|
||||||
}
|
|
||||||
kinds.iter().zip(self.tokens[self.pos..].iter().map(|t| t.kind))
|
|
||||||
.all(|(&k1, k2)| k1 == k2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> bool {
|
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,
|
WHITESPACE | COMMENT => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue