mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Fix parser bugs
This commit is contained in:
parent
0199adc2d0
commit
fe552e23b1
3 changed files with 89 additions and 78 deletions
|
@ -145,12 +145,6 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw_syntax_err<L: Locational>(&mut self, l: &L, caused_by: &str) -> ParseError {
|
|
||||||
log!(err "error caused by: {caused_by}");
|
|
||||||
self.next_expr();
|
|
||||||
ParseError::simple_syntax_error(0, l.loc())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn skip_and_throw_syntax_err(&mut self, caused_by: &str) -> ParseError {
|
fn skip_and_throw_syntax_err(&mut self, caused_by: &str) -> ParseError {
|
||||||
let loc = self.peek().unwrap().loc();
|
let loc = self.peek().unwrap().loc();
|
||||||
log!(err "error caused by: {caused_by}");
|
log!(err "error caused by: {caused_by}");
|
||||||
|
@ -275,7 +269,10 @@ impl Parser {
|
||||||
Some(t) if t.is(EOF) => {
|
Some(t) if t.is(EOF) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Some(t) if t.is(Indent) || t.is(Dedent) => {
|
Some(t) if t.is(Indent) => {
|
||||||
|
switch_unreachable!()
|
||||||
|
}
|
||||||
|
Some(t) if t.is(Dedent) => {
|
||||||
switch_unreachable!()
|
switch_unreachable!()
|
||||||
}
|
}
|
||||||
Some(_) => match self.try_reduce_chunk(true) {
|
Some(_) => match self.try_reduce_chunk(true) {
|
||||||
|
@ -284,7 +281,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
},
|
},
|
||||||
_ => switch_unreachable!(),
|
None => switch_unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
|
@ -306,29 +303,22 @@ impl Parser {
|
||||||
Some(t) if t.category_is(TC::Separator) => {
|
Some(t) if t.category_is(TC::Separator) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
Some(t) => {
|
Some(t) if t.is(Indent) => {
|
||||||
if t.is(Indent) {
|
|
||||||
self.skip();
|
|
||||||
while self.cur_is(Newline) {
|
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
} else if self.cur_is(Dedent) {
|
Some(t) if t.is(Dedent) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
break;
|
break;
|
||||||
} else if t.is(EOF) {
|
}
|
||||||
|
Some(t) if t.is(EOF) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match self.try_reduce_chunk(true) {
|
Some(_) => match self.try_reduce_chunk(true) {
|
||||||
Ok(expr) => {
|
Ok(expr) => {
|
||||||
block.push(expr);
|
block.push(expr);
|
||||||
if self.cur_is(Dedent) {
|
|
||||||
self.skip();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => switch_unreachable!(),
|
_ => switch_unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -852,14 +842,23 @@ impl Parser {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(t) if t.category_is(TC::Separator) => {
|
Some(t) if t.category_is(TC::Separator) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
if self.cur_is(Dedent) {
|
}
|
||||||
|
Some(t) if t.is(Dedent) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Some(_) => {
|
||||||
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
||||||
let def = option_enum_unwrap!(def, Expr::Def).unwrap_or_else(|| todo!());
|
match def {
|
||||||
|
Expr::Def(def) => {
|
||||||
defs.push(def);
|
defs.push(def);
|
||||||
}
|
}
|
||||||
|
other => {
|
||||||
|
self.errs
|
||||||
|
.push(ParseError::simple_syntax_error(0, other.loc()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1066,6 +1065,11 @@ impl Parser {
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
stack.push(ExprOrOp::Expr(Expr::Tuple(tup)));
|
stack.push(ExprOrOp::Expr(Expr::Tuple(tup)));
|
||||||
}
|
}
|
||||||
|
Some(t) if t.category_is(TC::Reserved) => {
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if stack.len() <= 1 {
|
if stack.len() <= 1 {
|
||||||
break;
|
break;
|
||||||
|
@ -1208,6 +1212,12 @@ impl Parser {
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
stack.push(ExprOrOp::Expr(Expr::Tuple(tup)));
|
stack.push(ExprOrOp::Expr(Expr::Tuple(tup)));
|
||||||
}
|
}
|
||||||
|
Some(t) if t.category_is(TC::Reserved) => {
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if stack.len() <= 1 {
|
if stack.len() <= 1 {
|
||||||
break;
|
break;
|
||||||
|
@ -1481,7 +1491,8 @@ impl Parser {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(t) if t.category_is(TC::Separator) => {
|
Some(t) if t.category_is(TC::Separator) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
if self.cur_is(Dedent) {
|
}
|
||||||
|
Some(t) if t.is(Dedent) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
if self.cur_is(RBrace) {
|
if self.cur_is(RBrace) {
|
||||||
let r_brace = self.lpop();
|
let r_brace = self.lpop();
|
||||||
|
@ -1492,16 +1503,17 @@ impl Parser {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
|
||||||
let def = option_enum_unwrap!(def, Expr::Def).unwrap_or_else(|| todo!());
|
|
||||||
attrs.push(def);
|
|
||||||
}
|
|
||||||
Some(term) if term.is(RBrace) => {
|
Some(term) if term.is(RBrace) => {
|
||||||
let r_brace = self.lpop();
|
let r_brace = self.lpop();
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let attrs = RecordAttrs::from(attrs);
|
let attrs = RecordAttrs::from(attrs);
|
||||||
return Ok(NormalRecord::new(l_brace, r_brace, attrs));
|
return Ok(NormalRecord::new(l_brace, r_brace, attrs));
|
||||||
}
|
}
|
||||||
|
Some(_) => {
|
||||||
|
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
||||||
|
let def = option_enum_unwrap!(def, Expr::Def).unwrap_or_else(|| todo!());
|
||||||
|
attrs.push(def);
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1525,7 +1537,8 @@ impl Parser {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(t) if t.category_is(TC::Separator) => {
|
Some(t) if t.category_is(TC::Separator) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
if self.cur_is(Dedent) {
|
}
|
||||||
|
Some(t) if t.is(Dedent) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
if self.cur_is(RBrace) {
|
if self.cur_is(RBrace) {
|
||||||
let r_brace = self.lpop();
|
let r_brace = self.lpop();
|
||||||
|
@ -1535,6 +1548,12 @@ impl Parser {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(term) if term.is(RBrace) => {
|
||||||
|
let r_brace = self.lpop();
|
||||||
|
self.level -= 1;
|
||||||
|
return Ok(ShortenedRecord::new(l_brace, r_brace, idents));
|
||||||
|
}
|
||||||
|
Some(_) => {
|
||||||
let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?;
|
let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?;
|
||||||
let acc = match acc {
|
let acc = match acc {
|
||||||
Accessor::Local(local) => Identifier::new(None, VarName::new(local.symbol)),
|
Accessor::Local(local) => Identifier::new(None, VarName::new(local.symbol)),
|
||||||
|
@ -1545,11 +1564,6 @@ impl Parser {
|
||||||
};
|
};
|
||||||
idents.push(acc);
|
idents.push(acc);
|
||||||
}
|
}
|
||||||
Some(term) if term.is(RBrace) => {
|
|
||||||
let r_brace = self.lpop();
|
|
||||||
self.level -= 1;
|
|
||||||
return Ok(ShortenedRecord::new(l_brace, r_brace, idents));
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1671,7 +1685,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
@ -1696,7 +1710,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
@ -1815,7 +1829,7 @@ impl Parser {
|
||||||
.map_err(|_| self.stack_dec())?,
|
.map_err(|_| self.stack_dec())?,
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -1837,7 +1851,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -1890,7 +1904,7 @@ impl Parser {
|
||||||
Expr::Accessor(Accessor::Local(local)) => {
|
Expr::Accessor(Accessor::Local(local)) => {
|
||||||
if &local.inspect()[..] == "self" && !allow_self {
|
if &local.inspect()[..] == "self" && !allow_self {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&local, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, local.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -1962,14 +1976,14 @@ impl Parser {
|
||||||
// TODO: Spread
|
// TODO: Spread
|
||||||
_other => {
|
_other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&unary, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, unary.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
@ -2068,7 +2082,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = self.throw_syntax_err(&other, caused_by!());
|
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,10 +187,8 @@ pub enum TokenCategory {
|
||||||
LambdaOp,
|
LambdaOp,
|
||||||
/// \n ;
|
/// \n ;
|
||||||
Separator,
|
Separator,
|
||||||
/// ^ (reserved)
|
/// ^ &
|
||||||
Caret,
|
Reserved,
|
||||||
/// &
|
|
||||||
Amper,
|
|
||||||
/// @
|
/// @
|
||||||
AtSign,
|
AtSign,
|
||||||
/// |
|
/// |
|
||||||
|
@ -224,8 +222,7 @@ impl TokenKind {
|
||||||
Semi | Newline => TokenCategory::Separator,
|
Semi | Newline => TokenCategory::Separator,
|
||||||
LParen | LBrace | LSqBr | Indent => TokenCategory::LEnclosure,
|
LParen | LBrace | LSqBr | Indent => TokenCategory::LEnclosure,
|
||||||
RParen | RBrace | RSqBr | Dedent => TokenCategory::REnclosure,
|
RParen | RBrace | RSqBr | Dedent => TokenCategory::REnclosure,
|
||||||
Caret => TokenCategory::Caret,
|
Caret | Amper => TokenCategory::Reserved,
|
||||||
Amper => TokenCategory::Amper,
|
|
||||||
AtSign => TokenCategory::AtSign,
|
AtSign => TokenCategory::AtSign,
|
||||||
VBar => TokenCategory::VBar,
|
VBar => TokenCategory::VBar,
|
||||||
UBar => TokenCategory::UBar,
|
UBar => TokenCategory::UBar,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Point = Class {x = Int; y = Int}, Impl := Add() and Eq()
|
Point = Class {x = Int; y = Int}, Impl := Add() and Eq()
|
||||||
Point.
|
Point.
|
||||||
new x, y = Self::__new__ {x; y}
|
new x, y = Self::__new__ {x; y}
|
||||||
norm &self = self::x**2 + self::y**2
|
norm self = self::x**2 + self::y**2
|
||||||
@Impl Add()
|
@Impl Add()
|
||||||
`+` self, other =
|
`+` self, other =
|
||||||
Self.new(self::x + other::x, self::y + other::y)
|
Self.new(self::x + other::x, self::y + other::y)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue