git.delta.rocks / jrsonnet / refs/commits / 6beafa85136f

difftreelog

source

crates/jrsonnet-rowan-parser/src/parser.rs19.2 KiBsourcehistory
1use std::{cell::Cell, fmt::Display, rc::Rc};23use miette::{LabeledSpan, SourceOffset, SourceSpan};4use rowan::{GreenNode, TextRange, TextSize};56use crate::{7	event::Event,8	lex::Lexeme,9	marker::{CompletedMarker, Marker, Ranger},10	nodes::{BinaryOperatorKind, Literal, Number, Text, Trivia, UnaryOperatorKind},11	token_set::SyntaxKindSet,12	AstToken, SyntaxKind,13	SyntaxKind::*,14	SyntaxNode, T, TS,15};1617pub struct Parse {18	pub green_node: GreenNode,19	pub errors: Vec<LocatedSyntaxError>,20}2122#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]23pub enum ExpectedSyntax {24	Named(&'static str),25	Unnamed(SyntaxKind),26}27impl Display for ExpectedSyntax {28	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {29		match self {30			ExpectedSyntax::Named(n) => write!(f, "{}", n),31			ExpectedSyntax::Unnamed(u) => write!(f, "{:?}", u),32		}33	}34}3536pub struct Parser {37	// TODO: remove all trivia before feeding to parser?38	kinds: Vec<SyntaxKind>,39	pub offset: usize,40	pub events: Vec<Event>,41	pub entered: u32,42	pub hints: Vec<(u32, TextRange, String)>,43	pub last_error_token: usize,44	expected_syntax: Option<ExpectedSyntax>,45	expected_syntax_tracking_state: Rc<Cell<ExpectedSyntaxTrackingState>>,46	steps: Cell<u64>,47}4849const DEFAULT_RECOVERY_SET: SyntaxKindSet = TS![];5051#[derive(Clone, Debug, PartialEq, Eq)]52pub enum SyntaxError {53	Unexpected {54		expected: ExpectedSyntax,55		found: SyntaxKind,56	},57	Missing {58		expected: ExpectedSyntax,59	},60	Custom {61		error: String,62	},63	Hint {64		error: String,65	},66}6768#[derive(Debug)]69pub struct LocatedSyntaxError {70	pub error: SyntaxError,71	pub range: TextRange,72}7374impl From<LocatedSyntaxError> for LabeledSpan {75	fn from(val: LocatedSyntaxError) -> Self {76		let span = SourceSpan::new(77			SourceOffset::from(usize::from(val.range.start())),78			SourceOffset::from(usize::from(val.range.end() - val.range.start())),79		);80		dbg!(&val);81		match val.error {82			SyntaxError::Unexpected { expected, found } => LabeledSpan::new_with_span(83				Some(format!("expected {}, found {:?}", expected, found)),84				span,85			),86			SyntaxError::Missing { expected } => {87				LabeledSpan::new_with_span(Some(format!("missing {}", expected)), span)88			}89			SyntaxError::Custom { error } | SyntaxError::Hint { error } => {90				LabeledSpan::new_with_span(Some(error), span)91			}92		}93	}94}9596impl Parser {97	pub fn new(kinds: Vec<SyntaxKind>) -> Self {98		Self {99			kinds,100			offset: 0,101			events: vec![],102			entered: 0,103			last_error_token: 0,104			hints: vec![],105			expected_syntax: None,106			expected_syntax_tracking_state: Rc::new(Cell::new(107				ExpectedSyntaxTrackingState::Unnamed,108			)),109			steps: Cell::new(0),110		}111	}112	pub fn clear_outdated_hints(&mut self) {113		let amount = self114			.hints115			.iter()116			.rev()117			.take_while(|h| h.0 > self.entered)118			.count();119		self.hints.truncate(self.hints.len() - amount)120	}121	fn clear_expected_syntaxes(&mut self) {122		self.expected_syntax = None;123		self.expected_syntax_tracking_state124			.set(ExpectedSyntaxTrackingState::Unnamed);125	}126	pub fn start(&mut self) -> Marker {127		let start_event_idx = self.events.len();128		self.events.push(Event::Pending);129		self.entered += 1;130		Marker::new(start_event_idx)131	}132	pub fn start_ranger(&mut self) -> Ranger {133		let pos = self.offset;134		Ranger { pos }135	}136	pub fn parse(mut self) -> Vec<Event> {137		let m = self.start();138		expr(&mut self);139		self.expect(EOF);140		m.complete(&mut self, SOURCE_FILE);141142		self.events143	}144145	pub(crate) fn expect(&mut self, kind: SyntaxKind) {146		self.expect_with_recovery_set(kind, TS![])147	}148149	pub(crate) fn expect_with_recovery_set(150		&mut self,151		kind: SyntaxKind,152		recovery_set: SyntaxKindSet,153	) {154		if self.at(kind) {155			if kind != EOF {156				self.bump();157			}158		} else {159			self.error_with_recovery_set(recovery_set);160		}161	}162163	pub(crate) fn expect_with_no_skip(&mut self, kind: SyntaxKind) {164		if self.at(kind) {165			self.bump();166		} else {167			self.error_with_no_skip();168		}169	}170	pub(crate) fn error_with_recovery_set(171		&mut self,172		recovery_set: SyntaxKindSet,173	) -> CompletedMarker {174		self.error_with_recovery_set_no_default(recovery_set.union(DEFAULT_RECOVERY_SET))175	}176	pub fn error_with_no_skip(&mut self) -> CompletedMarker {177		self.error_with_recovery_set_no_default(SyntaxKindSet::ALL)178	}179180	pub fn error_with_recovery_set_no_default(181		&mut self,182		recovery_set: SyntaxKindSet,183	) -> CompletedMarker {184		let expected_syntax = self185			.expected_syntax186			.take()187			.unwrap_or(ExpectedSyntax::Named("unknown"));188		self.expected_syntax_tracking_state189			.set(ExpectedSyntaxTrackingState::Unnamed);190191		if self.at_end() || self.at_ts(recovery_set) {192			// let range = self193			// 	.offset194			// 	.unwrap_or_else(|| TextRange::at(TextSize::from(0), TextSize::from(0)));195			let m = self.start();196			let m = m.complete(self, ERROR_MISSING_TOKEN);197			self.events.push(Event::Error(SyntaxError::Missing {198				expected: expected_syntax,199			}));200			return m;201		}202203		let current_token = self.current();204205		self.last_error_token = self.offset;206207		let m = self.start();208		self.bump();209		let m = m.complete(self, ERROR_UNEXPECTED_TOKEN);210		self.events.push(Event::Error(SyntaxError::Unexpected {211			expected: expected_syntax,212			found: current_token,213		}));214		self.clear_expected_syntaxes();215		m216	}217	fn bump_assert(&mut self, kind: SyntaxKind) {218		assert!(self.at(kind), "expected {:?}", kind);219		self.bump_remap(self.current());220	}221	fn bump(&mut self) {222		self.bump_remap(self.current());223	}224	fn bump_remap(&mut self, kind: SyntaxKind) {225		assert_ne!(self.offset, self.kinds.len(), "already at end");226		self.events.push(Event::Token { kind });227		self.offset += 1;228		self.clear_expected_syntaxes();229	}230	fn step(&self) {231		use std::fmt::Write;232		let steps = self.steps.get();233		if steps >= 15000000 {234			let mut out = "seems like parsing is stuck".to_owned();235			{236				let last = 20;237				write!(out, "\n\nLast {} events:", last).unwrap();238				for (i, event) in self239					.events240					.iter()241					.skip(self.events.len().saturating_sub(last))242					.enumerate()243				{244					write!(out, "\n{i}. {event:?}").unwrap();245				}246			}247			{248				let next = 20;249				write!(out, "\n\nNext {next} tokens:").unwrap();250				for (i, tok) in self.kinds.iter().skip(self.offset).take(next).enumerate() {251					write!(out, "\n{i}. {tok:?}").unwrap();252				}253			}254			panic!("{out}")255		}256		self.steps.set(steps + 1);257	}258	fn nth(&self, i: usize) -> SyntaxKind {259		self.step();260		let mut offset = self.offset;261		for _ in 0..i {262			offset += 1;263		}264		self.kinds.get(offset).copied().unwrap_or(EOF)265	}266	fn current(&self) -> SyntaxKind {267		self.nth(0)268	}269	#[must_use]270	pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {271		self.expected_syntax_tracking_state272			.set(ExpectedSyntaxTrackingState::Named);273		self.expected_syntax = Some(ExpectedSyntax::Named(name));274275		ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state))276	}277	pub fn at(&mut self, kind: SyntaxKind) -> bool {278		self.nth_at(0, kind)279	}280	pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool {281		if let ExpectedSyntaxTrackingState::Unnamed = self.expected_syntax_tracking_state.get() {282			self.expected_syntax = Some(ExpectedSyntax::Unnamed(kind));283		}284		self.nth(n) == kind285	}286	pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool {287		set.contains(self.current())288	}289	pub fn at_end(&mut self) -> bool {290		self.at(EOF)291	}292}293pub(crate) struct ExpectedSyntaxGuard {294	expected_syntax_tracking_state: Rc<Cell<ExpectedSyntaxTrackingState>>,295}296297impl ExpectedSyntaxGuard {298	fn new(expected_syntax_tracking_state: Rc<Cell<ExpectedSyntaxTrackingState>>) -> Self {299		Self {300			expected_syntax_tracking_state,301		}302	}303}304305impl Drop for ExpectedSyntaxGuard {306	fn drop(&mut self) {307		self.expected_syntax_tracking_state308			.set(ExpectedSyntaxTrackingState::Unnamed);309	}310}311312#[derive(Debug, Clone, Copy)]313enum ExpectedSyntaxTrackingState {314	Named,315	Unnamed,316}317318fn expr(p: &mut Parser) -> CompletedMarker {319	match expr_binding_power(p, 0) {320		Ok(m) => m,321		Err(m) => m,322	}323}324fn expr_binding_power(325	p: &mut Parser,326	minimum_binding_power: u8,327) -> Result<CompletedMarker, CompletedMarker> {328	let mut lhs = lhs(p)?;329330	while let Some(op) = BinaryOperatorKind::cast(p.current())331		.or_else(|| p.at(T!['{']).then_some(BinaryOperatorKind::MetaObjectApply))332	{333		let (left_binding_power, right_binding_power) = op.binding_power();334		if left_binding_power < minimum_binding_power {335			break;336		}337338		// Object apply is not a real operator, we dont have something to bump339		if op != BinaryOperatorKind::MetaObjectApply {340			p.bump();341		}342343		let m = lhs.wrap(p, LHS_EXPR).precede(p);344		let parsed_rhs = expr_binding_power(p, right_binding_power).is_ok();345		lhs = m.complete(346			p,347			if op == BinaryOperatorKind::MetaObjectApply {348				EXPR_OBJ_EXTEND349			} else {350				EXPR_BINARY351			},352		);353354		if !parsed_rhs {355			break;356		}357	}358	Ok(lhs)359}360fn compspec(p: &mut Parser) {361	assert!(p.at(T![for]) || p.at(T![if]));362	if p.at(T![for]) {363		let m = p.start();364		p.bump();365		name(p);366		p.expect(T![in]);367		expr(p);368		m.complete(p, FOR_SPEC);369	} else if p.at(T![if]) {370		let m = p.start();371		p.bump();372		expr(p);373		m.complete(p, IF_SPEC);374	} else {375		unreachable!()376	}377}378fn comma(p: &mut Parser) -> bool {379	if p.at(T![,]) {380		p.bump();381		true382	} else {383		false384	}385}386fn comma_with_alternatives(p: &mut Parser, set: SyntaxKindSet) -> bool {387	if p.at(T![,]) {388		p.bump();389		true390	} else if p.at_ts(set) {391		p.expect_with_no_skip(T![,]);392		p.bump();393		true394	} else {395		false396	}397}398fn field_name(p: &mut Parser) {399	let _e = p.expected_syntax_name("field name");400	let m = p.start();401	if p.at(T!['[']) {402		p.bump();403		expr(p);404		p.expect(T![']']);405		m.complete(p, FIELD_NAME_DYNAMIC);406	} else if p.at(IDENT) {407		name(p);408		m.complete(p, FIELD_NAME_FIXED);409	} else if Text::can_cast(p.current()) {410		text(p);411		m.complete(p, FIELD_NAME_FIXED);412	} else {413		p.error_with_recovery_set(TS![;]);414	}415}416fn visibility(p: &mut Parser) {417	if p.at_ts(TS![: :: :::]) {418		p.bump()419	} else {420		p.error_with_recovery_set(TS![]);421	}422}423fn field(p: &mut Parser) {424	let m = p.start();425	field_name(p);426	let plus = if p.at(T![+]) {427		let r = p.start_ranger();428		p.bump();429		Some(r.finish(p))430	} else {431		None432	};433	let params = if p.at(T!['(']) {434		// if let Some(plus) = plus {435		// 	p.custom_error(plus, "can't extend with method");436		// }437		params_desc(p);438		// if p.at(T![+]) {439		// 	let r = p.start_ranger();440		// 	p.bump();441		// 	p.custom_error(r.finish(p), "can't extend with method");442		// }443		true444	} else {445		false446	};447	visibility(p);448	expr(p);449450	if params {451		m.complete(p, FIELD_METHOD)452	} else {453		m.complete(p, FIELD_NORMAL)454	};455}456fn assertion(p: &mut Parser) {457	let m = p.start();458	p.bump_assert(T![assert]);459	expr(p).wrap(p, LHS_EXPR);460	if p.at(T![:]) {461		p.bump();462		expr(p);463	}464	m.complete(p, ASSERTION);465}466fn object(p: &mut Parser) -> CompletedMarker {467	let m_t = p.start();468	let m = p.start();469	p.bump_assert(T!['{']);470471	loop {472		if p.at(T!['}']) {473			p.bump();474			break;475		}476		let m = p.start();477		if p.at(T![local]) {478			obj_local(p);479			m.complete(p, MEMBER_BIND_STMT)480		} else if p.at(T![assert]) {481			assertion(p);482			m.complete(p, MEMBER_ASSERT_STMT)483		} else {484			field(p);485			while p.at(T![for]) || p.at(T![if]) {486				compspec(p)487			}488			m.complete(p, MEMBER_FIELD)489		};490		if comma_with_alternatives(p, SyntaxKindSet::new(&[T![=]])) {491			continue;492		}493		p.expect(R_BRACE);494		break;495	}496497	m.complete(p, OBJ_BODY_MEMBER_LIST);498	m_t.complete(p, EXPR_OBJECT)499}500fn param(p: &mut Parser) {501	let m = p.start();502	destruct(p);503	if p.at(T![=]) {504		p.bump();505		expr(p);506	}507	m.complete(p, PARAM);508}509fn params_desc(p: &mut Parser) -> CompletedMarker {510	let m = p.start();511	p.bump_assert(T!['(']);512513	loop {514		if p.at(T![')']) {515			p.bump();516			break;517		}518		param(p);519		if comma(p) {520			continue;521		}522		p.expect(T![')']);523		break;524	}525526	m.complete(p, PARAMS_DESC)527}528fn args_desc(p: &mut Parser) {529	let m = p.start();530	p.bump_assert(T!['(']);531532	let started_named = Cell::new(false);533534	loop {535		if p.at(T![')']) {536			break;537		}538539		let m = p.start();540		if p.at(IDENT) && p.nth_at(1, T![=]) {541			name(p);542			p.bump();543			expr(p);544			m.complete(p, ARG);545			started_named.set(true);546		} else {547			expr(p);548			m.complete(p, ARG);549		}550		if comma(p) {551			continue;552		}553		break;554	}555	p.expect(T![')']);556	if p.at(T![tailstrict]) {557		p.bump()558	}559	m.complete(p, ARGS_DESC);560}561562fn array(p: &mut Parser) -> CompletedMarker {563	// Start the list node564	let m = p.start();565	p.bump_assert(T!['[']);566567	// This vec will have at most one element in case of correct input568	let mut compspecs = Vec::with_capacity(1);569	let mut elems = 0;570571	loop {572		if p.at(T![']']) {573			p.bump();574			break;575		}576		elems += 1;577		expr(p);578		let c = p.start_ranger();579		let mut had_spec = false;580		while p.at(T![for]) || p.at(T![if]) {581			had_spec = true;582			compspec(p)583		}584		if had_spec {585			compspecs.push(c.finish(p));586		}587		if comma(p) {588			continue;589		}590		p.expect(T![']']);591		break;592	}593594	if elems > 1 && !compspecs.is_empty() {595		for spec in compspecs {596			// p.custom_error(597			// 	spec,598			// 	"compspec may only be used if there is only one array element",599			// )600		}601602		m.complete(p, EXPR_ARRAY)603	} else if !compspecs.is_empty() {604		m.complete(p, EXPR_ARRAY_COMP)605	} else {606		m.complete(p, EXPR_ARRAY)607	}608}609/// Returns true if it was slice, false if just index610#[must_use]611fn slice_desc_or_index(p: &mut Parser) -> bool {612	let m = p.start();613	p.bump();614	// TODO: do not treat :, ::, ::: as full tokens?615	// Start616	if !p.at(T![:]) && !p.at(T![::]) {617		expr(p);618	}619	if p.at(T![:]) {620		p.bump();621		// End622		if !p.at(T![']']) {623			expr(p).wrap(p, SLICE_DESC_END);624		}625		if p.at(T![:]) {626			p.bump();627			// Step628			if !p.at(T![']']) {629				expr(p).wrap(p, SLICE_DESC_STEP);630			}631		}632	} else if p.at(T![::]) {633		p.bump();634		// End635		if !p.at(T![']']) {636			expr(p).wrap(p, SLICE_DESC_END);637		}638	} else {639		// It was not a slice640		p.expect(T![']']);641		m.forget(p);642		return false;643	}644	p.expect(T![']']);645	m.complete(p, SLICE_DESC);646	true647}648fn lhs(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {649	let mut lhs = lhs_basic(p)?;650651	loop {652		if p.at(T![.]) {653			let m = lhs.precede(p);654			p.bump();655			name(p);656			lhs = m.complete(p, EXPR_INDEX);657		} else if p.at(T!['[']) {658			if slice_desc_or_index(p) {659				lhs = lhs.precede(p).complete(p, EXPR_SLICE);660			} else {661				lhs = lhs662					.wrap(p, LHS_EXPR)663					.precede(p)664					.complete(p, EXPR_INDEX_EXPR);665			}666		} else if p.at(T!['(']) {667			let m = lhs.precede(p);668			args_desc(p);669			lhs = m.complete(p, EXPR_APPLY);670		} else {671			break;672		}673	}674675	Ok(lhs)676}677fn name(p: &mut Parser) {678	let m = p.start();679	p.expect(IDENT);680	m.complete(p, NAME);681}682fn destruct_rest(p: &mut Parser) {683	let m = p.start();684	p.bump_assert(T![...]);685	if p.at(IDENT) {686		p.bump()687	}688	m.complete(p, DESTRUCT_REST);689}690fn destruct_object_field(p: &mut Parser) {691	let m = p.start();692	name(p);693	if p.at(T![:]) {694		p.bump();695		destruct(p);696	};697	if p.at(T![=]) {698		p.bump();699		expr(p);700	}701	m.complete(p, DESTRUCT_OBJECT_FIELD);702}703fn obj_local(p: &mut Parser) {704	let m = p.start();705	p.bump_assert(T![local]);706	bind(p);707	m.complete(p, OBJ_LOCAL);708}709fn destruct(p: &mut Parser) -> CompletedMarker {710	let m = p.start();711	let _ex = p.expected_syntax_name("destruction specifier");712	if p.at(T![?]) {713		p.bump();714		m.complete(p, DESTRUCT_SKIP)715	} else if p.at(T!['[']) {716		p.bump();717		let mut had_rest = false;718		loop {719			if p.at(T![']']) {720				p.bump();721				break;722			} else if p.at(T![...]) {723				let m_err = p.start_ranger();724				destruct_rest(p);725				// if had_rest {726				// 	p.custom_error(m_err.finish(p), "only one rest can be present in array");727				// }728				had_rest = true;729			} else {730				destruct(p);731			}732			if p.at(T![,]) {733				p.bump();734				continue;735			}736			p.expect(T![']']);737			break;738		}739		m.complete(p, DESTRUCT_ARRAY)740	} else if p.at(T!['{']) {741		p.bump();742		let mut had_rest = false;743		loop {744			if p.at(T!['}']) {745				p.bump();746				break;747			} else if p.at(T![...]) {748				let m_err = p.start_ranger();749				destruct_rest(p);750				// if had_rest {751				// 	p.custom_error(m_err.finish(p), "only one rest can be present in object");752				// }753				had_rest = true;754			} else {755				if had_rest {756					p.error_with_recovery_set(TS![]);757				}758				destruct_object_field(p);759			}760			if p.at(T![,]) {761				p.bump();762				continue;763			}764			p.expect(T!['}']);765			break;766		}767		m.complete(p, DESTRUCT_OBJECT)768	} else if p.at(IDENT) {769		name(p);770		m.complete(p, DESTRUCT_FULL)771	} else {772		m.forget(p);773		p.error_with_recovery_set(TS![; , '}', '(', :])774	}775}776fn bind(p: &mut Parser) {777	let m = p.start();778	if p.at(IDENT) && p.nth_at(1, T!['(']) {779		name(p);780		params_desc(p);781		p.expect(T![=]);782		expr(p);783		m.complete(p, BIND_FUNCTION)784	} else if p.at(IDENT) && p.nth_at(1, T![=]) && p.nth_at(2, T![function]) {785		name(p);786		p.expect(T![=]);787		p.expect(T![function]);788		params_desc(p);789		expr(p);790		m.complete(p, BIND_FUNCTION)791	} else {792		destruct(p);793		p.expect(T![=]);794		expr(p);795		m.complete(p, BIND_DESTRUCT)796	};797}798fn text(p: &mut Parser) {799	assert!(Text::can_cast(p.current()));800	p.bump();801}802fn number(p: &mut Parser) {803	assert!(Number::can_cast(p.current()));804	p.bump();805}806fn literal(p: &mut Parser) {807	assert!(Literal::can_cast(p.current()));808	p.bump();809}810fn lhs_basic(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {811	let _e = p.expected_syntax_name("expression");812	Ok(if Literal::can_cast(p.current()) {813		let m = p.start();814		literal(p);815		m.complete(p, EXPR_LITERAL)816	} else if Text::can_cast(p.current()) {817		let m = p.start();818		text(p);819		m.complete(p, EXPR_STRING)820	} else if Number::can_cast(p.current()) {821		let m = p.start();822		number(p);823		m.complete(p, EXPR_NUMBER)824	} else if p.at(IDENT) {825		let m = p.start();826		name(p);827		m.complete(p, EXPR_VAR)828	} else if p.at(INTRINSIC_THIS_FILE) {829		let m = p.start();830		p.bump();831		m.complete(p, EXPR_INTRINSIC_THIS_FILE)832	} else if p.at(INTRINSIC_ID) {833		let m = p.start();834		p.bump();835		m.complete(p, EXPR_INTRINSIC_ID)836	} else if p.at(INTRINSIC) {837		let m = p.start();838		p.bump();839		p.expect(T!['(']);840		name(p);841		p.expect(T![')']);842		m.complete(p, EXPR_INTRINSIC)843	} else if p.at(T![if]) {844		let m = p.start();845		p.bump();846		expr(p);847		p.expect(T![then]);848		expr(p).wrap(p, TRUE_EXPR);849		if p.at(T![else]) {850			p.bump();851			expr(p).wrap(p, FALSE_EXPR);852		}853		m.complete(p, EXPR_IF_THEN_ELSE)854	} else if p.at(T!['[']) {855		array(p)856	} else if p.at(T!['{']) {857		object(p)858	} else if p.at(T![local]) {859		let m = p.start();860		p.bump();861		loop {862			if p.at(T![;]) {863				p.bump();864				break;865			}866			bind(p);867868			if p.at(T![,]) {869				p.bump();870				continue;871			}872			p.expect(T![;]);873			break;874		}875		expr(p);876		m.complete(p, EXPR_LOCAL)877	} else if p.at(T![function]) {878		let m = p.start();879		p.bump();880		params_desc(p);881		expr(p);882		m.complete(p, EXPR_FUNCTION)883	} else if p.at(T![error]) {884		let m = p.start();885		p.bump();886		expr(p);887		m.complete(p, EXPR_ERROR)888	} else if p.at(T![assert]) {889		let m = p.start();890		assertion(p);891		p.expect(T![;]);892		expr(p);893		m.complete(p, EXPR_ASSERT)894	} else if p.at(T![import]) || p.at(T![importstr]) || p.at(T![importbin]) {895		let m = p.start();896		p.bump();897		text(p);898		m.complete(p, EXPR_IMPORT)899	} else if let Some(op) = UnaryOperatorKind::cast(p.current()) {900		let ((), right_binding_power) = op.binding_power();901902		let m = p.start();903		p.bump();904		let _ = expr_binding_power(p, right_binding_power);905		m.complete(p, EXPR_UNARY)906	} else if p.at(T!['(']) {907		let m = p.start();908		p.bump();909		expr(p);910		p.expect(T![')']);911		m.complete(p, EXPR_PARENED)912	} else {913		return Err(p.error_with_no_skip());914	})915}916917impl Parse {918	pub fn syntax(&self) -> SyntaxNode {919		SyntaxNode::new_root(self.green_node.clone())920	}921}