git.delta.rocks / jrsonnet / refs/commits / cf173f6ac619

difftreelog

source

crates/jrsonnet-rowan-parser/src/parser.rs19.2 KiBsourcehistory
1use std::{cell::Cell, fmt, rc::Rc};23use miette::{LabeledSpan, SourceOffset, SourceSpan};4use rowan::{GreenNode, TextRange};56use crate::{7	event::Event,8	marker::{CompletedMarker, Marker, Ranger},9	nodes::{BinaryOperatorKind, Literal, Number, Text, UnaryOperatorKind},10	token_set::SyntaxKindSet,11	AstToken, SyntaxKind,12	SyntaxKind::*,13	SyntaxNode, T, TS,14};1516pub struct Parse {17	pub green_node: GreenNode,18	pub errors: Vec<LocatedSyntaxError>,19}2021pub struct Parser {22	// TODO: remove all trivia before feeding to parser?23	kinds: Vec<SyntaxKind>,24	pub offset: usize,25	pub events: Vec<Event>,26	pub entered: u32,27	pub hints: Vec<(u32, TextRange, String)>,28	pub last_error_token: usize,29	expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,30	steps: Cell<u64>,31}3233#[derive(Clone, Debug)]34pub enum SyntaxError {35	Unexpected {36		expected: ExpectedSyntax,37		found: SyntaxKind,38	},39	Missing {40		expected: ExpectedSyntax,41	},42	Custom {43		error: String,44	},45	Hint {46		error: String,47	},48}4950#[derive(Debug)]51pub struct LocatedSyntaxError {52	pub error: SyntaxError,53	pub range: TextRange,54}5556impl From<LocatedSyntaxError> for LabeledSpan {57	fn from(val: LocatedSyntaxError) -> Self {58		let span = SourceSpan::new(59			SourceOffset::from(usize::from(val.range.start())),60			SourceOffset::from(usize::from(val.range.end() - val.range.start())),61		);62		dbg!(&val);63		match val.error {64			SyntaxError::Unexpected { expected, found } => LabeledSpan::new_with_span(65				Some(format!("expected {expected}, found {found:?}")),66				span,67			),68			SyntaxError::Missing { expected } => {69				LabeledSpan::new_with_span(Some(format!("missing {expected}")), span)70			}71			SyntaxError::Custom { error } | SyntaxError::Hint { error } => {72				LabeledSpan::new_with_span(Some(error), span)73			}74		}75	}76}7778impl Parser {79	pub fn new(kinds: Vec<SyntaxKind>) -> Self {80		Self {81			kinds,82			offset: 0,83			events: vec![],84			entered: 0,85			last_error_token: 0,86			hints: vec![],87			expected_syntax_tracking_state: Rc::new(Cell::new(ExpectedSyntax::Unnamed(TS![]))),88			steps: Cell::new(0),89		}90	}91	pub fn clear_outdated_hints(&mut self) {92		let amount = self93			.hints94			.iter()95			.rev()96			.take_while(|h| h.0 > self.entered)97			.count();98		self.hints.truncate(self.hints.len() - amount)99	}100	fn clear_expected_syntaxes(&mut self) {101		self.expected_syntax_tracking_state102			.set(ExpectedSyntax::Unnamed(TS![]));103	}104	pub fn start(&mut self) -> Marker {105		let start_event_idx = self.events.len();106		self.events.push(Event::Pending);107		self.entered += 1;108		Marker::new(start_event_idx)109	}110	pub fn start_ranger(&mut self) -> Ranger {111		let pos = self.offset;112		Ranger { pos }113	}114	pub fn parse(mut self) -> Vec<Event> {115		let m = self.start();116		expr(&mut self);117		self.expect(EOF);118		m.complete(&mut self, SOURCE_FILE);119120		self.events121	}122123	pub(crate) fn expect(&mut self, kind: SyntaxKind) {124		self.expect_with_recovery_set(kind, TS![])125	}126127	pub(crate) fn expect_with_recovery_set(128		&mut self,129		kind: SyntaxKind,130		recovery_set: SyntaxKindSet,131	) {132		if self.at(kind) {133			if kind != EOF {134				self.bump();135			}136		} else {137			self.error_with_recovery_set(recovery_set);138		}139	}140141	pub(crate) fn expect_with_no_skip(&mut self, kind: SyntaxKind) {142		if self.at(kind) {143			self.bump();144		} else {145			self.error_with_no_skip();146		}147	}148	pub fn error_with_no_skip(&mut self) -> CompletedMarker {149		self.error_with_recovery_set(SyntaxKindSet::ALL)150	}151152	pub fn error_with_recovery_set(&mut self, recovery_set: SyntaxKindSet) -> CompletedMarker {153		let expected = self.expected_syntax_tracking_state.get();154		self.expected_syntax_tracking_state155			.set(ExpectedSyntax::Unnamed(TS![]));156157		if self.at_end() || self.at_ts(recovery_set) {158			let m = self.start();159			return m.complete_missing(self, expected);160		}161162		let current_token = self.current();163164		self.last_error_token = self.offset;165166		let m = self.start();167		self.bump();168		let m = m.complete_unexpected(self, expected, current_token);169		self.clear_expected_syntaxes();170		m171	}172	fn bump_assert(&mut self, kind: SyntaxKind) {173		assert!(self.at(kind), "expected {:?}", kind);174		self.bump_remap(self.current());175	}176	fn bump(&mut self) {177		self.bump_remap(self.current());178	}179	fn bump_remap(&mut self, kind: SyntaxKind) {180		assert_ne!(self.offset, self.kinds.len(), "already at end");181		self.events.push(Event::Token { kind });182		self.offset += 1;183		self.clear_expected_syntaxes();184	}185	fn step(&self) {186		use std::fmt::Write;187		let steps = self.steps.get();188		if steps >= 15000000 {189			let mut out = "seems like parsing is stuck".to_owned();190			{191				let last = 20;192				write!(out, "\n\nLast {} events:", last).unwrap();193				for (i, event) in self194					.events195					.iter()196					.skip(self.events.len().saturating_sub(last))197					.enumerate()198				{199					write!(out, "\n{i}. {event:?}").unwrap();200				}201			}202			{203				let next = 20;204				write!(out, "\n\nNext {next} tokens:").unwrap();205				for (i, tok) in self.kinds.iter().skip(self.offset).take(next).enumerate() {206					write!(out, "\n{i}. {tok:?}").unwrap();207				}208			}209			panic!("{out}")210		}211		self.steps.set(steps + 1);212	}213	fn nth(&self, i: usize) -> SyntaxKind {214		self.step();215		let mut offset = self.offset;216		for _ in 0..i {217			offset += 1;218		}219		self.kinds.get(offset).copied().unwrap_or(EOF)220	}221	fn current(&self) -> SyntaxKind {222		self.nth(0)223	}224	#[must_use]225	pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {226		self.expected_syntax_tracking_state227			.set(ExpectedSyntax::Named(name));228229		ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state))230	}231	pub fn at(&mut self, kind: SyntaxKind) -> bool {232		self.nth_at(0, kind)233	}234	pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool {235		if n == 0 {236			if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {237				let kinds = kinds.with(kind);238				self.expected_syntax_tracking_state239					.set(ExpectedSyntax::Unnamed(kinds))240			}241		}242		self.nth(n) == kind243	}244	pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool {245		if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {246			let kinds = kinds.union(set);247			self.expected_syntax_tracking_state248				.set(ExpectedSyntax::Unnamed(kinds))249		}250		set.contains(self.current())251	}252	pub fn at_end(&mut self) -> bool {253		self.at(EOF)254	}255}256pub(crate) struct ExpectedSyntaxGuard {257	expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,258}259260impl ExpectedSyntaxGuard {261	fn new(expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>) -> Self {262		Self {263			expected_syntax_tracking_state,264		}265	}266}267268impl Drop for ExpectedSyntaxGuard {269	fn drop(&mut self) {270		self.expected_syntax_tracking_state271			.set(ExpectedSyntax::Unnamed(TS![]));272	}273}274275#[derive(Clone, Debug, Copy)]276pub enum ExpectedSyntax {277	Named(&'static str),278	Unnamed(SyntaxKindSet),279}280impl fmt::Display for ExpectedSyntax {281	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {282		match self {283			ExpectedSyntax::Named(name) => write!(f, "{name}"),284			ExpectedSyntax::Unnamed(set) => write!(f, "{set}"),285		}286	}287}288289fn expr(p: &mut Parser) -> CompletedMarker {290	match expr_binding_power(p, 0) {291		Ok(m) => m,292		Err(m) => m,293	}294}295fn expr_binding_power(296	p: &mut Parser,297	minimum_binding_power: u8,298) -> Result<CompletedMarker, CompletedMarker> {299	let mut lhs = lhs(p)?;300301	while let Some(op) = BinaryOperatorKind::cast(p.current())302		.or_else(|| p.at(T!['{']).then_some(BinaryOperatorKind::MetaObjectApply))303	{304		let (left_binding_power, right_binding_power) = op.binding_power();305		if left_binding_power < minimum_binding_power {306			break;307		}308309		// Object apply is not a real operator, we dont have something to bump310		if op != BinaryOperatorKind::MetaObjectApply {311			p.bump();312		}313314		let m = lhs.wrap(p, LHS_EXPR).precede(p);315		let parsed_rhs = expr_binding_power(p, right_binding_power).is_ok();316		lhs = m.complete(317			p,318			if op == BinaryOperatorKind::MetaObjectApply {319				EXPR_OBJ_EXTEND320			} else {321				EXPR_BINARY322			},323		);324325		if !parsed_rhs {326			break;327		}328	}329	Ok(lhs)330}331332const COMPSPEC: SyntaxKindSet = TS![for if];333fn compspec(p: &mut Parser) -> CompletedMarker {334	assert!(p.at_ts(COMPSPEC));335	if p.at(T![for]) {336		let m = p.start();337		p.bump();338		name(p);339		p.expect(T![in]);340		expr(p);341		m.complete(p, FOR_SPEC)342	} else if p.at(T![if]) {343		let m = p.start();344		p.bump();345		expr(p);346		m.complete(p, IF_SPEC)347	} else {348		unreachable!()349	}350}351352fn comma(p: &mut Parser) -> bool {353	comma_with_alternatives(p, TS![])354}355fn comma_with_alternatives(p: &mut Parser, set: SyntaxKindSet) -> bool {356	if p.at(T![,]) {357		p.bump();358		true359	} else if p.at_ts(set) {360		let _ex = p.expected_syntax_name("comma");361		p.expect_with_recovery_set(T![,], TS![]);362		true363	} else {364		false365	}366}367368fn field_name(p: &mut Parser) {369	let _e = p.expected_syntax_name("field name");370	let m = p.start();371	if p.at(T!['[']) {372		p.bump();373		expr(p);374		p.expect(T![']']);375		m.complete(p, FIELD_NAME_DYNAMIC);376	} else if p.at(IDENT) {377		name(p);378		m.complete(p, FIELD_NAME_FIXED);379	} else if Text::can_cast(p.current()) {380		text(p);381		m.complete(p, FIELD_NAME_FIXED);382	} else {383		m.forget(p);384		p.error_with_recovery_set(TS![; : :: ::: '(']);385	}386}387fn visibility(p: &mut Parser) {388	if p.at_ts(TS![: :: :::]) {389		p.bump()390	} else {391		p.error_with_recovery_set(TS![=]);392	}393}394fn assertion(p: &mut Parser) {395	let m = p.start();396	p.bump_assert(T![assert]);397	expr(p).wrap(p, LHS_EXPR);398	if p.at(T![:]) {399		p.bump();400		expr(p);401	}402	m.complete(p, ASSERTION);403}404fn object(p: &mut Parser) -> CompletedMarker {405	let m_t = p.start();406	let m = p.start();407	p.bump_assert(T!['{']);408409	let mut elems = 0;410	let mut compspecs = Vec::new();411	loop {412		if p.at(T!['}']) {413			p.bump();414			break;415		}416		if p.at_ts(COMPSPEC) {417			if elems == 0 {418				let m = p.start();419				m.complete_missing(p, ExpectedSyntax::Named("field definition"));420			}421			while p.at_ts(COMPSPEC) {422				compspecs.push(compspec(p));423			}424			if comma_with_alternatives(p, TS![;]) {425				continue;426			}427			p.expect(R_BRACE);428			break;429		}430		let m = p.start();431		if p.at(T![local]) {432			obj_local(p);433			m.complete(p, MEMBER_BIND_STMT)434		} else if p.at(T![assert]) {435			assertion(p);436			m.complete(p, MEMBER_ASSERT_STMT)437		} else {438			field_name(p);439			if p.at(T![+]) {440				p.bump();441			}442			let params = if p.at(T!['(']) {443				params_desc(p);444				visibility(p);445				expr(p);446				true447			} else if p.at_ts(TS![: :: :::]) && p.nth_at(1, T![function]) {448				visibility(p);449				p.bump_assert(T![function]);450				params_desc(p);451				expr(p);452				true453			} else {454				visibility(p);455				expr(p);456				false457			};458459			if params {460				m.complete(p, MEMBER_FIELD_METHOD)461			} else {462				m.complete(p, MEMBER_FIELD_NORMAL)463			}464		};465		elems += 1;466		while p.at_ts(COMPSPEC) {467			compspecs.push(compspec(p));468		}469		if comma_with_alternatives(p, TS![;]) {470			continue;471		}472		p.expect(R_BRACE);473		break;474	}475476	if elems > 1 && !compspecs.is_empty() {477		for errored in compspecs {478			errored.wrap_error(479				p,480				"compspec may only be used if there is only one array element",481			);482		}483		m.complete(p, OBJ_BODY_MEMBER_LIST);484	} else if !compspecs.is_empty() {485		m.complete(p, OBJ_BODY_COMP);486	} else {487		m.complete(p, OBJ_BODY_MEMBER_LIST);488	}489	m_t.complete(p, EXPR_OBJECT)490}491fn param(p: &mut Parser) {492	let m = p.start();493	destruct(p);494	if p.at(T![=]) {495		p.bump();496		expr(p);497	}498	m.complete(p, PARAM);499}500fn params_desc(p: &mut Parser) -> CompletedMarker {501	let m = p.start();502	p.bump_assert(T!['(']);503504	loop {505		if p.at(T![')']) {506			p.bump();507			break;508		}509		param(p);510		if comma(p) {511			continue;512		}513		p.expect(T![')']);514		break;515	}516517	m.complete(p, PARAMS_DESC)518}519fn args_desc(p: &mut Parser) {520	let m = p.start();521	p.bump_assert(T!['(']);522523	let started_named = Cell::new(false);524	let mut unnamed_after_named = Vec::new();525526	loop {527		if p.at(T![')']) {528			break;529		}530531		let m = p.start();532		if p.at(IDENT) && p.nth_at(1, T![=]) {533			name(p);534			p.bump();535			expr(p);536			m.complete(p, ARG);537			started_named.set(true);538		} else {539			expr(p);540			let arg = m.complete(p, ARG);541			if started_named.get() {542				unnamed_after_named.push(arg)543			}544		}545		if comma(p) {546			continue;547		}548		break;549	}550	p.expect(T![')']);551	if p.at(T![tailstrict]) {552		p.bump()553	}554555	for errored in unnamed_after_named {556		errored.wrap_error(p, "can't use positional arguments after named");557	}558559	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	let mut compspecs = Vec::new();568	let mut elems = 0;569570	loop {571		if p.at(T![']']) {572			p.bump();573			break;574		}575		if elems != 0 && p.at_ts(COMPSPEC) {576			while p.at_ts(COMPSPEC) {577				compspecs.push(compspec(p));578			}579			if comma(p) {580				continue;581			}582			p.expect(T![']']);583			break;584		}585		elems += 1;586		expr(p);587		while p.at_ts(COMPSPEC) {588			compspecs.push(compspec(p));589		}590		if comma(p) {591			continue;592		}593		p.expect(T![']']);594		break;595	}596597	if elems > 1 && !compspecs.is_empty() {598		for spec in compspecs {599			spec.wrap_error(600				p,601				"compspec may only be used if there is only one array element",602			);603		}604605		m.complete(p, EXPR_ARRAY)606	} else if !compspecs.is_empty() {607		m.complete(p, EXPR_ARRAY_COMP)608	} else {609		m.complete(p, EXPR_ARRAY)610	}611}612/// Returns true if it was slice, false if just index613#[must_use]614fn slice_desc_or_index(p: &mut Parser) -> bool {615	let m = p.start();616	p.bump();617	// TODO: do not treat :, ::, ::: as full tokens?618	// Start619	if !p.at(T![:]) && !p.at(T![::]) {620		expr(p);621	}622	if p.at(T![:]) {623		p.bump();624		// End625		if !p.at(T![']']) {626			expr(p).wrap(p, SLICE_DESC_END);627		}628		if p.at(T![:]) {629			p.bump();630			// Step631			if !p.at(T![']']) {632				expr(p).wrap(p, SLICE_DESC_STEP);633			}634		}635	} else if p.at(T![::]) {636		p.bump();637		// End638		if !p.at(T![']']) {639			expr(p).wrap(p, SLICE_DESC_END);640		}641	} else {642		// It was not a slice643		p.expect(T![']']);644		m.forget(p);645		return false;646	}647	p.expect(T![']']);648	m.complete(p, SLICE_DESC);649	true650}651fn lhs(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {652	let mut lhs = lhs_basic(p)?;653654	loop {655		if p.at(T![.]) {656			let m = lhs.precede(p);657			p.bump();658			name(p);659			lhs = m.complete(p, EXPR_INDEX);660		} else if p.at(T!['[']) {661			if slice_desc_or_index(p) {662				lhs = lhs.precede(p).complete(p, EXPR_SLICE);663			} else {664				lhs = lhs665					.wrap(p, LHS_EXPR)666					.precede(p)667					.complete(p, EXPR_INDEX_EXPR);668			}669		} else if p.at(T!['(']) {670			let m = lhs.precede(p);671			args_desc(p);672			lhs = m.complete(p, EXPR_APPLY);673		} else {674			break;675		}676	}677678	Ok(lhs)679}680fn name(p: &mut Parser) {681	let m = p.start();682	p.expect(IDENT);683	m.complete(p, NAME);684}685fn destruct_rest(p: &mut Parser) {686	let m = p.start();687	p.bump_assert(T![...]);688	if p.at(IDENT) {689		p.bump()690	}691	m.complete(p, DESTRUCT_REST);692}693fn destruct_object_field(p: &mut Parser) {694	let m = p.start();695	name(p);696	if p.at(T![:]) {697		p.bump();698		destruct(p);699	};700	if p.at(T![=]) {701		p.bump();702		expr(p);703	}704	m.complete(p, DESTRUCT_OBJECT_FIELD);705}706fn obj_local(p: &mut Parser) {707	let m = p.start();708	p.bump_assert(T![local]);709	bind(p);710	m.complete(p, OBJ_LOCAL);711}712fn destruct(p: &mut Parser) -> CompletedMarker {713	let m = p.start();714	let _ex = p.expected_syntax_name("destruction specifier");715	if p.at(T![?]) {716		p.bump();717		m.complete(p, DESTRUCT_SKIP)718	} else if p.at(T!['[']) {719		p.bump();720		let mut had_rest = false;721		loop {722			if p.at(T![']']) {723				p.bump();724				break;725			} else if p.at(T![...]) {726				let m_err = p.start_ranger();727				destruct_rest(p);728				// if had_rest {729				// 	p.custom_error(m_err.finish(p), "only one rest can be present in array");730				// }731				had_rest = true;732			} else {733				destruct(p);734			}735			if p.at(T![,]) {736				p.bump();737				continue;738			}739			p.expect(T![']']);740			break;741		}742		m.complete(p, DESTRUCT_ARRAY)743	} else if p.at(T!['{']) {744		p.bump();745		let mut had_rest = false;746		loop {747			if p.at(T!['}']) {748				p.bump();749				break;750			} else if p.at(T![...]) {751				let m_err = p.start_ranger();752				destruct_rest(p);753				// if had_rest {754				// 	p.custom_error(m_err.finish(p), "only one rest can be present in object");755				// }756				had_rest = true;757			} else {758				if had_rest {759					p.error_with_recovery_set(TS![]);760				}761				destruct_object_field(p);762			}763			if p.at(T![,]) {764				p.bump();765				continue;766			}767			p.expect(T!['}']);768			break;769		}770		m.complete(p, DESTRUCT_OBJECT)771	} else if p.at(IDENT) {772		name(p);773		m.complete(p, DESTRUCT_FULL)774	} else {775		m.forget(p);776		p.error_with_recovery_set(TS![; , '}', '(', :])777	}778}779fn bind(p: &mut Parser) {780	let m = p.start();781	if p.at(IDENT) && p.nth_at(1, T!['(']) {782		name(p);783		params_desc(p);784		p.expect(T![=]);785		expr(p);786		m.complete(p, BIND_FUNCTION)787	} else if p.at(IDENT) && p.nth_at(1, T![=]) && p.nth_at(2, T![function]) {788		name(p);789		p.expect(T![=]);790		p.expect(T![function]);791		params_desc(p);792		expr(p);793		m.complete(p, BIND_FUNCTION)794	} else {795		destruct(p);796		p.expect(T![=]);797		expr(p);798		m.complete(p, BIND_DESTRUCT)799	};800}801fn text(p: &mut Parser) {802	assert!(Text::can_cast(p.current()));803	p.bump();804}805fn number(p: &mut Parser) {806	assert!(Number::can_cast(p.current()));807	p.bump();808}809fn literal(p: &mut Parser) {810	assert!(Literal::can_cast(p.current()));811	p.bump();812}813fn lhs_basic(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {814	let _e = p.expected_syntax_name("expression");815	Ok(if Literal::can_cast(p.current()) {816		let m = p.start();817		literal(p);818		m.complete(p, EXPR_LITERAL)819	} else if Text::can_cast(p.current()) {820		let m = p.start();821		text(p);822		m.complete(p, EXPR_STRING)823	} else if Number::can_cast(p.current()) {824		let m = p.start();825		number(p);826		m.complete(p, EXPR_NUMBER)827	} else if p.at(IDENT) {828		let m = p.start();829		name(p);830		m.complete(p, EXPR_VAR)831	} else if p.at(INTRINSIC_THIS_FILE) {832		let m = p.start();833		p.bump();834		m.complete(p, EXPR_INTRINSIC_THIS_FILE)835	} else if p.at(INTRINSIC_ID) {836		let m = p.start();837		p.bump();838		m.complete(p, EXPR_INTRINSIC_ID)839	} else if p.at(INTRINSIC) {840		let m = p.start();841		p.bump();842		p.expect(T!['(']);843		name(p);844		p.expect(T![')']);845		m.complete(p, EXPR_INTRINSIC)846	} else if p.at(T![if]) {847		let m = p.start();848		p.bump();849		expr(p);850		p.expect(T![then]);851		expr(p).wrap(p, TRUE_EXPR);852		if p.at(T![else]) {853			p.bump();854			expr(p).wrap(p, FALSE_EXPR);855		}856		m.complete(p, EXPR_IF_THEN_ELSE)857	} else if p.at(T!['[']) {858		array(p)859	} else if p.at(T!['{']) {860		object(p)861	} else if p.at(T![local]) {862		let m = p.start();863		p.bump();864		loop {865			if p.at(T![;]) {866				p.bump();867				break;868			}869			bind(p);870871			if p.at(T![,]) {872				p.bump();873				continue;874			}875			p.expect(T![;]);876			break;877		}878		expr(p);879		m.complete(p, EXPR_LOCAL)880	} else if p.at(T![function]) {881		let m = p.start();882		p.bump();883		params_desc(p);884		expr(p);885		m.complete(p, EXPR_FUNCTION)886	} else if p.at(T![error]) {887		let m = p.start();888		p.bump();889		expr(p);890		m.complete(p, EXPR_ERROR)891	} else if p.at(T![assert]) {892		let m = p.start();893		assertion(p);894		p.expect(T![;]);895		expr(p);896		m.complete(p, EXPR_ASSERT)897	} else if p.at(T![import]) || p.at(T![importstr]) || p.at(T![importbin]) {898		let m = p.start();899		p.bump();900		text(p);901		m.complete(p, EXPR_IMPORT)902	} else if let Some(op) = UnaryOperatorKind::cast(p.current()) {903		let ((), right_binding_power) = op.binding_power();904905		let m = p.start();906		p.bump();907		let _ = expr_binding_power(p, right_binding_power);908		m.complete(p, EXPR_UNARY)909	} else if p.at(T!['(']) {910		let m = p.start();911		p.bump();912		expr(p);913		p.expect(T![')']);914		m.complete(p, EXPR_PARENED)915	} else {916		return Err(p.error_with_no_skip());917	})918}919920impl Parse {921	pub fn syntax(&self) -> SyntaxNode {922		SyntaxNode::new_root(self.green_node.clone())923	}924}