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 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 if !self.at(EOF) {118 let m = self.start();119 while !self.at(EOF) {120 self.bump();121 }122 m.complete_error(&mut self, "unexpected tokens after end");123 }124 m.complete(&mut self, SOURCE_FILE);125126 self.events127 }128129 pub(crate) fn expect(&mut self, kind: SyntaxKind) {130 self.expect_with_recovery_set(kind, TS![])131 }132133 pub(crate) fn expect_with_recovery_set(134 &mut self,135 kind: SyntaxKind,136 recovery_set: SyntaxKindSet,137 ) {138 if self.at(kind) {139 if kind != EOF {140 self.bump();141 }142 } else {143 self.error_with_recovery_set(recovery_set);144 }145 }146147 pub(crate) fn expect_with_no_skip(&mut self, kind: SyntaxKind) {148 if self.at(kind) {149 self.bump();150 } else {151 self.error_with_no_skip();152 }153 }154 pub fn error_with_no_skip(&mut self) -> CompletedMarker {155 self.error_with_recovery_set(SyntaxKindSet::ALL)156 }157158 pub fn error_with_recovery_set(&mut self, recovery_set: SyntaxKindSet) -> CompletedMarker {159 let expected = self.expected_syntax_tracking_state.get();160 self.expected_syntax_tracking_state161 .set(ExpectedSyntax::Unnamed(TS![]));162163 if self.at_end() || self.at_ts(recovery_set) {164 let m = self.start();165 return m.complete_missing(self, expected);166 }167168 let current_token = self.current();169170 self.last_error_token = self.offset;171172 let m = self.start();173 self.bump();174 let m = m.complete_unexpected(self, expected, current_token);175 self.clear_expected_syntaxes();176 m177 }178 fn bump_assert(&mut self, kind: SyntaxKind) {179 assert!(self.at(kind), "expected {:?}", kind);180 self.bump_remap(self.current());181 }182 fn bump(&mut self) {183 self.bump_remap(self.current());184 }185 fn bump_remap(&mut self, kind: SyntaxKind) {186 assert_ne!(self.offset, self.kinds.len(), "already at end");187 self.events.push(Event::Token { kind });188 self.offset += 1;189 self.clear_expected_syntaxes();190 }191 fn step(&self) {192 use std::fmt::Write;193 let steps = self.steps.get();194 if steps >= 15000000 {195 let mut out = "seems like parsing is stuck".to_owned();196 {197 let last = 20;198 write!(out, "\n\nLast {} events:", last).unwrap();199 for (i, event) in self200 .events201 .iter()202 .skip(self.events.len().saturating_sub(last))203 .enumerate()204 {205 write!(out, "\n{i}. {event:?}").unwrap();206 }207 }208 {209 let next = 20;210 write!(out, "\n\nNext {next} tokens:").unwrap();211 for (i, tok) in self.kinds.iter().skip(self.offset).take(next).enumerate() {212 write!(out, "\n{i}. {tok:?}").unwrap();213 }214 }215 panic!("{out}")216 }217 self.steps.set(steps + 1);218 }219 fn nth(&self, i: usize) -> SyntaxKind {220 self.step();221 let mut offset = self.offset;222 for _ in 0..i {223 offset += 1;224 }225 self.kinds.get(offset).copied().unwrap_or(EOF)226 }227 fn current(&self) -> SyntaxKind {228 self.nth(0)229 }230 #[must_use]231 pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {232 self.expected_syntax_tracking_state233 .set(ExpectedSyntax::Named(name));234235 ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state))236 }237 pub fn at(&mut self, kind: SyntaxKind) -> bool {238 self.nth_at(0, kind)239 }240 pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool {241 if n == 0 {242 if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {243 let kinds = kinds.with(kind);244 self.expected_syntax_tracking_state245 .set(ExpectedSyntax::Unnamed(kinds))246 }247 }248 self.nth(n) == kind249 }250 pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool {251 if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {252 let kinds = kinds.union(set);253 self.expected_syntax_tracking_state254 .set(ExpectedSyntax::Unnamed(kinds))255 }256 set.contains(self.current())257 }258 pub fn at_end(&mut self) -> bool {259 self.at(EOF)260 }261}262pub(crate) struct ExpectedSyntaxGuard {263 expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,264}265266impl ExpectedSyntaxGuard {267 fn new(expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>) -> Self {268 Self {269 expected_syntax_tracking_state,270 }271 }272}273274impl Drop for ExpectedSyntaxGuard {275 fn drop(&mut self) {276 self.expected_syntax_tracking_state277 .set(ExpectedSyntax::Unnamed(TS![]));278 }279}280281#[derive(Clone, Debug, Copy)]282pub enum ExpectedSyntax {283 Named(&'static str),284 Unnamed(SyntaxKindSet),285}286impl fmt::Display for ExpectedSyntax {287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {288 match self {289 ExpectedSyntax::Named(name) => write!(f, "{name}"),290 ExpectedSyntax::Unnamed(set) => write!(f, "{set}"),291 }292 }293}294295fn expr(p: &mut Parser) -> CompletedMarker {296 match expr_binding_power(p, 0) {297 Ok(m) => m,298 Err(m) => m,299 }300}301fn expr_binding_power(302 p: &mut Parser,303 minimum_binding_power: u8,304) -> Result<CompletedMarker, CompletedMarker> {305 let mut lhs = lhs(p)?;306307 while let Some(op) = BinaryOperatorKind::cast(p.current())308 .or_else(|| p.at(T!['{']).then_some(BinaryOperatorKind::MetaObjectApply))309 {310 let (left_binding_power, right_binding_power) = op.binding_power();311 if left_binding_power < minimum_binding_power {312 break;313 }314315 316 if op != BinaryOperatorKind::MetaObjectApply {317 p.bump();318 }319320 let m = lhs.wrap(p, LHS_EXPR).precede(p);321 let parsed_rhs = expr_binding_power(p, right_binding_power).is_ok();322 lhs = m.complete(323 p,324 if op == BinaryOperatorKind::MetaObjectApply {325 EXPR_OBJ_EXTEND326 } else {327 EXPR_BINARY328 },329 );330331 if !parsed_rhs {332 break;333 }334 }335 Ok(lhs)336}337338const COMPSPEC: SyntaxKindSet = TS![for if];339fn compspec(p: &mut Parser) -> CompletedMarker {340 assert!(p.at_ts(COMPSPEC));341 if p.at(T![for]) {342 let m = p.start();343 p.bump();344 name(p);345 p.expect(T![in]);346 expr(p);347 m.complete(p, FOR_SPEC)348 } else if p.at(T![if]) {349 let m = p.start();350 p.bump();351 expr(p);352 m.complete(p, IF_SPEC)353 } else {354 unreachable!()355 }356}357358fn comma(p: &mut Parser) -> bool {359 comma_with_alternatives(p, TS![])360}361fn comma_with_alternatives(p: &mut Parser, set: SyntaxKindSet) -> bool {362 if p.at(T![,]) {363 p.bump();364 true365 } else if p.at_ts(set) {366 let _ex = p.expected_syntax_name("comma");367 p.expect_with_recovery_set(T![,], TS![]);368 true369 } else {370 false371 }372}373374fn field_name(p: &mut Parser) {375 let _e = p.expected_syntax_name("field name");376 let m = p.start();377 if p.at(T!['[']) {378 p.bump();379 expr(p);380 p.expect(T![']']);381 m.complete(p, FIELD_NAME_DYNAMIC);382 } else if p.at(IDENT) {383 name(p);384 m.complete(p, FIELD_NAME_FIXED);385 } else if Text::can_cast(p.current()) {386 text(p);387 m.complete(p, FIELD_NAME_FIXED);388 } else {389 m.forget(p);390 p.error_with_recovery_set(TS![; : :: ::: '(']);391 }392}393fn visibility(p: &mut Parser) {394 if p.at_ts(TS![: :: :::]) {395 p.bump()396 } else {397 p.error_with_recovery_set(TS![=]);398 }399}400fn assertion(p: &mut Parser) {401 let m = p.start();402 p.bump_assert(T![assert]);403 expr(p).wrap(p, LHS_EXPR);404 if p.at(T![:]) {405 p.bump();406 expr(p);407 }408 m.complete(p, ASSERTION);409}410fn object(p: &mut Parser) -> CompletedMarker {411 let m_t = p.start();412 let m = p.start();413 p.bump_assert(T!['{']);414415 let mut elems = 0;416 let mut compspecs = Vec::new();417 let mut asserts = Vec::new();418 loop {419 if p.at(T!['}']) {420 p.bump();421 break;422 }423 if p.at_ts(COMPSPEC) {424 if elems == 0 {425 let m = p.start();426 m.complete_missing(p, ExpectedSyntax::Named("field definition"));427 }428 while p.at_ts(COMPSPEC) {429 compspecs.push(compspec(p));430 }431 if comma_with_alternatives(p, TS![;]) {432 continue;433 }434 p.expect(R_BRACE);435 break;436 }437 let m = p.start();438 if p.at(T![local]) {439 obj_local(p);440 m.complete(p, MEMBER_BIND_STMT);441 } else if p.at(T![assert]) {442 assertion(p);443 asserts.push(m.complete(p, MEMBER_ASSERT_STMT));444 } else {445 field_name(p);446 if p.at(T![+]) {447 p.bump();448 }449 let params = if p.at(T!['(']) {450 params_desc(p);451 visibility(p);452 expr(p);453 true454 } else if p.at_ts(TS![: :: :::]) && p.nth_at(1, T![function]) {455 visibility(p);456 p.bump_assert(T![function]);457 params_desc(p);458 expr(p);459 true460 } else {461 visibility(p);462 expr(p);463 false464 };465 elems += 1;466467 if params {468 m.complete(p, MEMBER_FIELD_METHOD)469 } else {470 m.complete(p, MEMBER_FIELD_NORMAL)471 };472 };473 while p.at_ts(COMPSPEC) {474 compspecs.push(compspec(p));475 }476 if comma_with_alternatives(p, TS![;]) {477 continue;478 }479 p.expect(R_BRACE);480 break;481 }482483 if elems > 1 && !compspecs.is_empty() {484 for errored in compspecs {485 errored.wrap_error(486 p,487 "compspec may only be used if there is only one array element",488 );489 }490 m.complete(p, OBJ_BODY_MEMBER_LIST);491 } else if !compspecs.is_empty() {492 for errored in asserts {493 errored.wrap_error(p, "asserts can't be used in object comprehensions");494 }495 m.complete(p, OBJ_BODY_COMP);496 } else {497 m.complete(p, OBJ_BODY_MEMBER_LIST);498 }499 m_t.complete(p, EXPR_OBJECT)500}501fn param(p: &mut Parser) {502 let m = p.start();503 destruct(p);504 if p.at(T![=]) {505 p.bump();506 expr(p);507 }508 m.complete(p, PARAM);509}510fn params_desc(p: &mut Parser) -> CompletedMarker {511 let m = p.start();512 p.bump_assert(T!['(']);513514 loop {515 if p.at(T![')']) {516 p.bump();517 break;518 }519 param(p);520 if comma(p) {521 continue;522 }523 p.expect(T![')']);524 break;525 }526527 m.complete(p, PARAMS_DESC)528}529fn args_desc(p: &mut Parser) {530 let m = p.start();531 p.bump_assert(T!['(']);532533 let started_named = Cell::new(false);534 let mut unnamed_after_named = Vec::new();535536 loop {537 if p.at(T![')']) {538 break;539 }540541 let m = p.start();542 if p.at(IDENT) && p.nth_at(1, T![=]) {543 name(p);544 p.bump();545 expr(p);546 m.complete(p, ARG);547 started_named.set(true);548 } else {549 expr(p);550 let arg = m.complete(p, ARG);551 if started_named.get() {552 unnamed_after_named.push(arg)553 }554 }555 if comma(p) {556 continue;557 }558 break;559 }560 p.expect(T![')']);561 if p.at(T![tailstrict]) {562 p.bump()563 }564565 for errored in unnamed_after_named {566 errored.wrap_error(p, "can't use positional arguments after named");567 }568569 m.complete(p, ARGS_DESC);570}571572fn array(p: &mut Parser) -> CompletedMarker {573 574 let m = p.start();575 p.bump_assert(T!['[']);576577 let mut compspecs = Vec::new();578 let mut elems = 0;579580 loop {581 if p.at(T![']']) {582 p.bump();583 break;584 }585 if elems != 0 && p.at_ts(COMPSPEC) {586 while p.at_ts(COMPSPEC) {587 compspecs.push(compspec(p));588 }589 if comma(p) {590 continue;591 }592 p.expect(T![']']);593 break;594 }595 elems += 1;596 expr(p);597 while p.at_ts(COMPSPEC) {598 compspecs.push(compspec(p));599 }600 if comma(p) {601 continue;602 }603 p.expect(T![']']);604 break;605 }606607 if elems > 1 && !compspecs.is_empty() {608 for spec in compspecs {609 spec.wrap_error(610 p,611 "compspec may only be used if there is only one array element",612 );613 }614615 m.complete(p, EXPR_ARRAY)616 } else if !compspecs.is_empty() {617 m.complete(p, EXPR_ARRAY_COMP)618 } else {619 m.complete(p, EXPR_ARRAY)620 }621}622623#[must_use]624fn slice_desc_or_index(p: &mut Parser) -> bool {625 let m = p.start();626 p.bump();627 628 629 if !p.at(T![:]) && !p.at(T![::]) {630 expr(p);631 }632 if p.at(T![:]) {633 p.bump();634 635 if !p.at(T![']']) {636 expr(p).wrap(p, SLICE_DESC_END);637 }638 if p.at(T![:]) {639 p.bump();640 641 if !p.at(T![']']) {642 expr(p).wrap(p, SLICE_DESC_STEP);643 }644 }645 } else if p.at(T![::]) {646 p.bump();647 648 if !p.at(T![']']) {649 expr(p).wrap(p, SLICE_DESC_END);650 }651 } else {652 653 p.expect(T![']']);654 m.forget(p);655 return false;656 }657 p.expect(T![']']);658 m.complete(p, SLICE_DESC);659 true660}661fn lhs(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {662 let mut lhs = lhs_basic(p)?;663664 loop {665 if p.at(T![.]) {666 let m = lhs.precede(p);667 p.bump();668 name(p);669 lhs = m.complete(p, EXPR_INDEX);670 } else if p.at(T!['[']) {671 if slice_desc_or_index(p) {672 lhs = lhs.precede(p).complete(p, EXPR_SLICE);673 } else {674 lhs = lhs675 .wrap(p, LHS_EXPR)676 .precede(p)677 .complete(p, EXPR_INDEX_EXPR);678 }679 } else if p.at(T!['(']) {680 let m = lhs.precede(p);681 args_desc(p);682 lhs = m.complete(p, EXPR_APPLY);683 } else {684 break;685 }686 }687688 Ok(lhs)689}690fn name(p: &mut Parser) {691 let m = p.start();692 p.expect(IDENT);693 m.complete(p, NAME);694}695fn destruct_rest(p: &mut Parser) {696 let m = p.start();697 p.bump_assert(T![...]);698 if p.at(IDENT) {699 p.bump()700 }701 m.complete(p, DESTRUCT_REST);702}703fn destruct_object_field(p: &mut Parser) {704 let m = p.start();705 name(p);706 if p.at(T![:]) {707 p.bump();708 destruct(p);709 };710 if p.at(T![=]) {711 p.bump();712 expr(p);713 }714 m.complete(p, DESTRUCT_OBJECT_FIELD);715}716fn obj_local(p: &mut Parser) {717 let m = p.start();718 p.bump_assert(T![local]);719 bind(p);720 m.complete(p, OBJ_LOCAL);721}722fn destruct(p: &mut Parser) -> CompletedMarker {723 let m = p.start();724 let _ex = p.expected_syntax_name("destruction specifier");725 if p.at(T![?]) {726 p.bump();727 m.complete(p, DESTRUCT_SKIP)728 } else if p.at(T!['[']) {729 p.bump();730 let mut had_rest = false;731 loop {732 if p.at(T![']']) {733 p.bump();734 break;735 } else if p.at(T![...]) {736 let m_err = p.start_ranger();737 destruct_rest(p);738 739 740 741 had_rest = true;742 } else {743 destruct(p);744 }745 if p.at(T![,]) {746 p.bump();747 continue;748 }749 p.expect(T![']']);750 break;751 }752 m.complete(p, DESTRUCT_ARRAY)753 } else if p.at(T!['{']) {754 p.bump();755 let mut had_rest = false;756 loop {757 if p.at(T!['}']) {758 p.bump();759 break;760 } else if p.at(T![...]) {761 let m_err = p.start_ranger();762 destruct_rest(p);763 764 765 766 had_rest = true;767 } else {768 if had_rest {769 p.error_with_recovery_set(TS![]);770 }771 destruct_object_field(p);772 }773 if p.at(T![,]) {774 p.bump();775 continue;776 }777 p.expect(T!['}']);778 break;779 }780 m.complete(p, DESTRUCT_OBJECT)781 } else if p.at(IDENT) {782 name(p);783 m.complete(p, DESTRUCT_FULL)784 } else {785 m.forget(p);786 p.error_with_recovery_set(TS![; , '}', '(', :])787 }788}789fn bind(p: &mut Parser) {790 let m = p.start();791 if p.at(IDENT) && p.nth_at(1, T!['(']) {792 name(p);793 params_desc(p);794 p.expect(T![=]);795 expr(p);796 m.complete(p, BIND_FUNCTION)797 } else if p.at(IDENT) && p.nth_at(1, T![=]) && p.nth_at(2, T![function]) {798 name(p);799 p.expect(T![=]);800 p.expect(T![function]);801 params_desc(p);802 expr(p);803 m.complete(p, BIND_FUNCTION)804 } else {805 destruct(p);806 p.expect(T![=]);807 expr(p);808 m.complete(p, BIND_DESTRUCT)809 };810}811fn text(p: &mut Parser) {812 assert!(Text::can_cast(p.current()));813 p.bump();814}815fn number(p: &mut Parser) {816 assert!(Number::can_cast(p.current()));817 p.bump();818}819fn literal(p: &mut Parser) {820 assert!(Literal::can_cast(p.current()));821 p.bump();822}823fn lhs_basic(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {824 let _e = p.expected_syntax_name("expression");825 Ok(if Literal::can_cast(p.current()) {826 let m = p.start();827 literal(p);828 m.complete(p, EXPR_LITERAL)829 } else if Text::can_cast(p.current()) {830 let m = p.start();831 text(p);832 m.complete(p, EXPR_STRING)833 } else if Number::can_cast(p.current()) {834 let m = p.start();835 number(p);836 m.complete(p, EXPR_NUMBER)837 } else if p.at(IDENT) {838 let m = p.start();839 name(p);840 m.complete(p, EXPR_VAR)841 } else if p.at(T![if]) {842 let m = p.start();843 p.bump();844 expr(p);845 p.expect(T![then]);846 expr(p).wrap(p, TRUE_EXPR);847 if p.at(T![else]) {848 p.bump();849 expr(p).wrap(p, FALSE_EXPR);850 }851 m.complete(p, EXPR_IF_THEN_ELSE)852 } else if p.at(T!['[']) {853 array(p)854 } else if p.at(T!['{']) {855 object(p)856 } else if p.at(T![local]) {857 let m = p.start();858 p.bump();859 loop {860 if p.at(T![;]) {861 p.bump();862 break;863 }864 bind(p);865866 if p.at(T![,]) {867 p.bump();868 continue;869 }870 p.expect(T![;]);871 break;872 }873 expr(p);874 m.complete(p, EXPR_LOCAL)875 } else if p.at(T![function]) {876 let m = p.start();877 p.bump();878 params_desc(p);879 expr(p);880 m.complete(p, EXPR_FUNCTION)881 } else if p.at(T![error]) {882 let m = p.start();883 p.bump();884 expr(p);885 m.complete(p, EXPR_ERROR)886 } else if p.at(T![assert]) {887 let m = p.start();888 assertion(p);889 p.expect(T![;]);890 expr(p);891 m.complete(p, EXPR_ASSERT)892 } else if p.at(T![import]) || p.at(T![importstr]) || p.at(T![importbin]) {893 let m = p.start();894 p.bump();895 text(p);896 m.complete(p, EXPR_IMPORT)897 } else if let Some(op) = UnaryOperatorKind::cast(p.current()) {898 let ((), right_binding_power) = op.binding_power();899900 let m = p.start();901 p.bump();902 let _ = expr_binding_power(p, right_binding_power);903 m.complete(p, EXPR_UNARY)904 } else if p.at(T!['(']) {905 let m = p.start();906 p.bump();907 expr(p);908 p.expect(T![')']);909 m.complete(p, EXPR_PARENED)910 } else {911 return Err(p.error_with_no_skip());912 })913}914915impl Parse {916 pub fn syntax(&self) -> SyntaxNode {917 SyntaxNode::new_root(self.green_node.clone())918 }919}