mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 10:13:54 +00:00
compound ops
This commit is contained in:
parent
5691da4c84
commit
1e1e2e83c4
@ -37,6 +37,10 @@ Grammar(
|
||||
["!=", "NEQ"],
|
||||
["-", "MINUS"],
|
||||
["->", "THIN_ARROW"],
|
||||
["<=", "LTEQ"],
|
||||
[">=", "GTEQ"],
|
||||
["+=", "PLUSEQ"],
|
||||
["-=", "MINUSEQ"],
|
||||
],
|
||||
keywords: [
|
||||
"use",
|
||||
|
@ -33,19 +33,45 @@ struct Restrictions {
|
||||
forbid_structs: bool
|
||||
}
|
||||
|
||||
enum Op {
|
||||
Simple,
|
||||
Composite(SyntaxKind, u8)
|
||||
}
|
||||
|
||||
// test expr_binding_power
|
||||
// fn foo() {
|
||||
// 1 + 2 * 3 == 1 * 2 + 3;
|
||||
// *x = 1 + 1;
|
||||
// }
|
||||
fn bp_of(op: SyntaxKind) -> u8 {
|
||||
match op {
|
||||
|
||||
// test compound_ops
|
||||
// fn foo() {
|
||||
// x += 1;
|
||||
// 1 + 1 <= 2 * 3;
|
||||
// z -= 3 >= 0;
|
||||
// }
|
||||
fn current_op(p: &Parser) -> (u8, Op) {
|
||||
if p.at_compound2(L_ANGLE, EQ) {
|
||||
return (2, Op::Composite(LTEQ, 2))
|
||||
}
|
||||
if p.at_compound2(R_ANGLE, EQ) {
|
||||
return (2, Op::Composite(GTEQ, 2))
|
||||
}
|
||||
if p.at_compound2(PLUS, EQ) {
|
||||
return (1, Op::Composite(PLUSEQ, 2))
|
||||
}
|
||||
if p.at_compound2(MINUS, EQ) {
|
||||
return (1, Op::Composite(MINUSEQ, 2))
|
||||
}
|
||||
|
||||
let bp = match p.current() {
|
||||
EQ => 1,
|
||||
EQEQ | NEQ => 2,
|
||||
MINUS | PLUS => 3,
|
||||
STAR | SLASH => 4,
|
||||
_ => 0
|
||||
}
|
||||
_ => 0,
|
||||
};
|
||||
(bp, Op::Simple)
|
||||
}
|
||||
|
||||
// Parses expression with binding power of at least bp.
|
||||
@ -56,10 +82,16 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
|
||||
};
|
||||
|
||||
loop {
|
||||
let op_bp = bp_of(p.current());
|
||||
let (op_bp, op) = current_op(p);
|
||||
if op_bp < bp {
|
||||
break;
|
||||
}
|
||||
match op {
|
||||
Op::Simple => p.bump(),
|
||||
Op::Composite(kind, n) => {
|
||||
p.bump_compound(kind, n);
|
||||
},
|
||||
}
|
||||
lhs = bin_expr(p, r, lhs, op_bp);
|
||||
}
|
||||
}
|
||||
@ -254,12 +286,7 @@ fn struct_lit(p: &mut Parser) {
|
||||
}
|
||||
|
||||
fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
|
||||
assert!(match p.current() {
|
||||
MINUS | PLUS | STAR | SLASH | EQEQ | NEQ | EQ => true,
|
||||
_ => false,
|
||||
});
|
||||
let m = lhs.precede(p);
|
||||
p.bump();
|
||||
expr_bp(p, r, bp);
|
||||
m.complete(p, BIN_EXPR)
|
||||
}
|
||||
|
@ -58,6 +58,10 @@ impl<'t> Parser<'t> {
|
||||
self.current() == kind
|
||||
}
|
||||
|
||||
pub(crate) fn at_compound2(&self, c1: SyntaxKind, c2: SyntaxKind) -> bool {
|
||||
self.0.at_compound2(c1, c2)
|
||||
}
|
||||
|
||||
/// Checks if the current token is contextual keyword with text `t`.
|
||||
pub(crate) fn at_contextual_kw(&self, t: &str) -> bool {
|
||||
self.0.at_kw(t)
|
||||
@ -85,6 +89,13 @@ impl<'t> Parser<'t> {
|
||||
self.0.bump_remap(kind);
|
||||
}
|
||||
|
||||
/// Advances the parser by `n` tokens, remapping its kind.
|
||||
/// This is useful to create compound tokens from parts. For
|
||||
/// example, an `<<` token is two consecutive remapped `<` tokens
|
||||
pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
|
||||
self.0.bump_compound(kind, n);
|
||||
}
|
||||
|
||||
/// Emit error with the `message`
|
||||
/// TODO: this should be much more fancy and support
|
||||
/// structured errors with spans and notes, like rustc
|
||||
|
@ -36,7 +36,22 @@ impl<'t> ParserInput<'t> {
|
||||
self.tokens[idx].kind
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn len(&self, pos: InputPosition) -> TextUnit {
|
||||
let idx = pos.0 as usize;
|
||||
if !(idx < self.tokens.len()) {
|
||||
return 0.into();
|
||||
}
|
||||
self.tokens[idx].len
|
||||
}
|
||||
|
||||
pub fn start(&self, pos: InputPosition) -> TextUnit {
|
||||
let idx = pos.0 as usize;
|
||||
if !(idx < self.tokens.len()) {
|
||||
return 0.into();
|
||||
}
|
||||
self.start_offsets[idx]
|
||||
}
|
||||
|
||||
pub fn text(&self, pos: InputPosition) -> &'t str {
|
||||
let idx = pos.0 as usize;
|
||||
if !(idx < self.tokens.len()) {
|
||||
|
@ -65,6 +65,11 @@ impl<'t> ParserImpl<'t> {
|
||||
self.events
|
||||
}
|
||||
|
||||
pub(super) fn at_compound2(&self, c1: SyntaxKind, c2: SyntaxKind) -> bool {
|
||||
self.inp.kind(self.pos) == c1 && self.inp.kind(self.pos + 1) == c2
|
||||
&& self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos)
|
||||
}
|
||||
|
||||
pub(super) fn nth(&self, n: u32) -> SyntaxKind {
|
||||
self.inp.kind(self.pos + n)
|
||||
}
|
||||
@ -87,7 +92,7 @@ impl<'t> ParserImpl<'t> {
|
||||
if kind == EOF {
|
||||
return;
|
||||
}
|
||||
self.do_bump(kind);
|
||||
self.do_bump(kind, 1);
|
||||
}
|
||||
|
||||
pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
|
||||
@ -95,14 +100,18 @@ impl<'t> ParserImpl<'t> {
|
||||
// TODO: panic!?
|
||||
return;
|
||||
}
|
||||
self.do_bump(kind);
|
||||
self.do_bump(kind, 1);
|
||||
}
|
||||
|
||||
fn do_bump(&mut self, kind: SyntaxKind) {
|
||||
self.pos += 1;
|
||||
pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
|
||||
self.do_bump(kind, n);
|
||||
}
|
||||
|
||||
fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
|
||||
self.pos += u32::from(n_raw_tokens);
|
||||
self.event(Event::Token {
|
||||
kind,
|
||||
n_raw_tokens: 1,
|
||||
n_raw_tokens,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,10 @@ pub enum SyntaxKind {
|
||||
NEQ,
|
||||
MINUS,
|
||||
THIN_ARROW,
|
||||
LTEQ,
|
||||
GTEQ,
|
||||
PLUSEQ,
|
||||
MINUSEQ,
|
||||
USE_KW,
|
||||
FN_KW,
|
||||
STRUCT_KW,
|
||||
@ -261,6 +265,10 @@ impl SyntaxKind {
|
||||
NEQ => &SyntaxInfo { name: "NEQ" },
|
||||
MINUS => &SyntaxInfo { name: "MINUS" },
|
||||
THIN_ARROW => &SyntaxInfo { name: "THIN_ARROW" },
|
||||
LTEQ => &SyntaxInfo { name: "LTEQ" },
|
||||
GTEQ => &SyntaxInfo { name: "GTEQ" },
|
||||
PLUSEQ => &SyntaxInfo { name: "PLUSEQ" },
|
||||
MINUSEQ => &SyntaxInfo { name: "MINUSEQ" },
|
||||
USE_KW => &SyntaxInfo { name: "USE_KW" },
|
||||
FN_KW => &SyntaxInfo { name: "FN_KW" },
|
||||
STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" },
|
||||
@ -502,6 +510,10 @@ impl SyntaxKind {
|
||||
NEQ => "!=",
|
||||
MINUS => "-",
|
||||
THIN_ARROW => "->",
|
||||
LTEQ => "<=",
|
||||
GTEQ => ">=",
|
||||
PLUSEQ => "+=",
|
||||
MINUSEQ => "-=",
|
||||
|
||||
USE_KW => "use",
|
||||
FN_KW => "fn",
|
||||
|
5
tests/data/parser/inline/0079_compound_ops.rs
Normal file
5
tests/data/parser/inline/0079_compound_ops.rs
Normal file
@ -0,0 +1,5 @@
|
||||
fn foo() {
|
||||
x += 1;
|
||||
1 + 1 <= 2 * 3;
|
||||
z -= 3 >= 0;
|
||||
}
|
72
tests/data/parser/inline/0079_compound_ops.txt
Normal file
72
tests/data/parser/inline/0079_compound_ops.txt
Normal file
@ -0,0 +1,72 @@
|
||||
FILE@[0; 62)
|
||||
FN_ITEM@[0; 62)
|
||||
FN_KW@[0; 2)
|
||||
NAME@[2; 6)
|
||||
WHITESPACE@[2; 3)
|
||||
IDENT@[3; 6) "foo"
|
||||
PARAM_LIST@[6; 9)
|
||||
L_PAREN@[6; 7)
|
||||
R_PAREN@[7; 8)
|
||||
WHITESPACE@[8; 9)
|
||||
BLOCK_EXPR@[9; 62)
|
||||
L_CURLY@[9; 10)
|
||||
EXPR_STMT@[10; 27)
|
||||
BIN_EXPR@[10; 21)
|
||||
PATH_EXPR@[10; 17)
|
||||
PATH@[10; 17)
|
||||
PATH_SEGMENT@[10; 17)
|
||||
NAME_REF@[10; 17)
|
||||
WHITESPACE@[10; 15)
|
||||
IDENT@[15; 16) "x"
|
||||
WHITESPACE@[16; 17)
|
||||
PLUSEQ@[17; 19)
|
||||
LITERAL@[19; 21)
|
||||
WHITESPACE@[19; 20)
|
||||
INT_NUMBER@[20; 21) "1"
|
||||
SEMI@[21; 22)
|
||||
WHITESPACE@[22; 27)
|
||||
EXPR_STMT@[27; 47)
|
||||
BIN_EXPR@[27; 41)
|
||||
BIN_EXPR@[27; 33)
|
||||
LITERAL@[27; 29)
|
||||
INT_NUMBER@[27; 28) "1"
|
||||
WHITESPACE@[28; 29)
|
||||
PLUS@[29; 30)
|
||||
LITERAL@[30; 33)
|
||||
WHITESPACE@[30; 31)
|
||||
INT_NUMBER@[31; 32) "1"
|
||||
WHITESPACE@[32; 33)
|
||||
LTEQ@[33; 35)
|
||||
BIN_EXPR@[35; 41)
|
||||
LITERAL@[35; 38)
|
||||
WHITESPACE@[35; 36)
|
||||
INT_NUMBER@[36; 37) "2"
|
||||
WHITESPACE@[37; 38)
|
||||
STAR@[38; 39)
|
||||
LITERAL@[39; 41)
|
||||
WHITESPACE@[39; 40)
|
||||
INT_NUMBER@[40; 41) "3"
|
||||
SEMI@[41; 42)
|
||||
WHITESPACE@[42; 47)
|
||||
EXPR_STMT@[47; 60)
|
||||
BIN_EXPR@[47; 58)
|
||||
PATH_EXPR@[47; 49)
|
||||
PATH@[47; 49)
|
||||
PATH_SEGMENT@[47; 49)
|
||||
NAME_REF@[47; 49)
|
||||
IDENT@[47; 48) "z"
|
||||
WHITESPACE@[48; 49)
|
||||
MINUSEQ@[49; 51)
|
||||
BIN_EXPR@[51; 58)
|
||||
LITERAL@[51; 54)
|
||||
WHITESPACE@[51; 52)
|
||||
INT_NUMBER@[52; 53) "3"
|
||||
WHITESPACE@[53; 54)
|
||||
GTEQ@[54; 56)
|
||||
LITERAL@[56; 58)
|
||||
WHITESPACE@[56; 57)
|
||||
INT_NUMBER@[57; 58) "0"
|
||||
SEMI@[58; 59)
|
||||
WHITESPACE@[59; 60)
|
||||
R_CURLY@[60; 61)
|
||||
WHITESPACE@[61; 62)
|
Loading…
Reference in New Issue
Block a user