Fix parser bugs

This commit is contained in:
Shunsuke Shibayama 2022-09-08 00:55:25 +09:00
parent 0199adc2d0
commit fe552e23b1
3 changed files with 89 additions and 78 deletions

View file

@ -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();
self.skip();
while self.cur_is(Newline) {
self.skip();
}
} else if self.cur_is(Dedent) {
self.skip();
break;
} else if t.is(EOF) {
break;
}
match self.try_reduce_chunk(true) {
Ok(expr) => {
block.push(expr);
if self.cur_is(Dedent) {
self.skip();
break;
}
}
Err(_) => {}
}
} }
Some(t) if t.is(Dedent) => {
self.skip();
break;
}
Some(t) if t.is(EOF) => {
break;
}
Some(_) => match self.try_reduce_chunk(true) {
Ok(expr) => {
block.push(expr);
}
Err(_) => {}
},
_ => switch_unreachable!(), _ => switch_unreachable!(),
} }
} }
@ -852,13 +842,22 @@ 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) { }
self.skip(); Some(t) if t.is(Dedent) => {
break; self.skip();
} 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 {
defs.push(def); Expr::Def(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,20 +1491,17 @@ 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) { }
self.skip(); Some(t) if t.is(Dedent) => {
if self.cur_is(RBrace) { self.skip();
let r_brace = self.lpop(); if self.cur_is(RBrace) {
self.level -= 1; let r_brace = self.lpop();
let attrs = RecordAttrs::from(attrs); self.level -= 1;
return Ok(NormalRecord::new(l_brace, r_brace, attrs)); let attrs = RecordAttrs::from(attrs);
} else { return Ok(NormalRecord::new(l_brace, r_brace, attrs));
todo!() } else {
} 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();
@ -1502,6 +1509,11 @@ impl Parser {
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,16 +1537,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) { }
self.skip(); Some(t) if t.is(Dedent) => {
if self.cur_is(RBrace) { self.skip();
let r_brace = self.lpop(); if self.cur_is(RBrace) {
self.level -= 1; let r_brace = self.lpop();
return Ok(ShortenedRecord::new(l_brace, r_brace, idents)); self.level -= 1;
} else { return Ok(ShortenedRecord::new(l_brace, r_brace, idents));
todo!() } else {
} 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(())
} }

View file

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

View file

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