blob: 922da08b49a2e3d4b0ffa02274b082f9f4a2f974 [file] [log] [blame]
David Tolnay18c754c2018-08-21 23:26:58 -04001//! Parsing interface for parsing a token stream into a syntax tree node.
2
3use std::cell::Cell;
4use std::fmt::Display;
5use std::marker::PhantomData;
6use std::mem;
7use std::ops::Deref;
8
9use proc_macro2::{Ident, Span};
10use syn::buffer::Cursor;
11
12use error;
13
14pub use error::{Error, Result};
15pub use lookahead::{Lookahead1, Peek};
16
17/// Parsing interface implemented by all types that can be parsed in a default
18/// way from a token stream.
19pub trait Parse: Sized {
20 fn parse(input: ParseStream) -> Result<Self>;
21}
22
23/// Input to a Syn parser function.
24pub type ParseStream<'a> = &'a ParseBuffer<'a>;
25
26/// Cursor position within a buffered token stream.
27#[derive(Clone)]
28pub struct ParseBuffer<'a> {
29 scope: Span,
30 cell: Cell<Cursor<'static>>,
31 marker: PhantomData<Cursor<'a>>,
32}
33
34// Not public API.
35#[doc(hidden)]
36#[derive(Copy, Clone)]
37pub struct StepCursor<'c, 'a> {
38 scope: Span,
39 cursor: Cursor<'c>,
40 marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
41}
42
43impl<'c, 'a> Deref for StepCursor<'c, 'a> {
44 type Target = Cursor<'c>;
45
46 fn deref(&self) -> &Self::Target {
47 &self.cursor
48 }
49}
50
51impl<'c, 'a> StepCursor<'c, 'a> {
52 // Not public API.
53 #[doc(hidden)]
54 pub fn advance(self, other: Cursor<'c>) -> Cursor<'a> {
55 unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(other) }
56 }
57
58 // Not public API.
59 #[doc(hidden)]
60 pub fn error<T: Display>(self, message: T) -> Error {
61 error::new_at(self.scope, self.cursor, message)
62 }
63}
64
65impl<'a> ParseBuffer<'a> {
66 // Not public API.
67 #[doc(hidden)]
68 pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
69 let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
70 ParseBuffer {
71 scope: scope,
72 cell: Cell::new(extend),
73 marker: PhantomData,
74 }
75 }
76
77 pub fn cursor(&self) -> Cursor<'a> {
78 self.cell.get()
79 }
80
81 pub fn is_empty(&self) -> bool {
82 self.cursor().eof()
83 }
84
85 pub fn lookahead1(&self) -> Lookahead1<'a> {
86 Lookahead1::new(self.scope, self.cursor())
87 }
88
89 pub fn parse<T: Parse>(&self) -> Result<T> {
90 T::parse(self)
91 }
92
93 // Not public API.
94 #[doc(hidden)]
95 pub fn step_cursor<F, R>(&self, function: F) -> Result<R>
96 where
97 F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
98 {
99 match function(StepCursor {
100 scope: self.scope,
101 cursor: self.cell.get(),
102 marker: PhantomData,
103 }) {
104 Ok((ret, cursor)) => {
105 self.cell.set(cursor);
106 Ok(ret)
107 }
108 Err(err) => Err(err),
109 }
110 }
111}
112
113impl Parse for Ident {
114 fn parse(input: ParseStream) -> Result<Self> {
115 input.step_cursor(|cursor| {
116 if let Some((ident, rest)) = cursor.ident() {
117 Ok((ident, rest))
118 } else {
119 Err(cursor.error("expected identifier"))
120 }
121 })
122 }
123}
124
125// In reality the impl would be for Punctuated.
126impl<T: Parse> Parse for Vec<T> {
127 fn parse(input: ParseStream) -> Result<Self> {
128 let mut vec = Vec::new();
129 while !input.is_empty() {
130 let t = input.parse::<T>()?;
131 vec.push(t);
132 }
133 Ok(vec)
134 }
135}