1
1
use logos:: Logos ;
2
2
use std:: fmt;
3
+ use std:: ops:: Range ;
3
4
4
- /// The complete set of `LexToken `s some of which never escape the lexer.
5
- /// See Token for a list of which Tokens do and do not escape.
5
+ /// The complete set of `LexerToken `s some of which never escape the lexer.
6
+ /// See ` Token` for a list of which Tokens do and do not escape.
6
7
#[ derive( Logos ) ]
7
- enum LexToken {
8
+ enum LexerToken {
8
9
#[ end]
9
- EOF ,
10
+ Eof ,
10
11
#[ token = ":" ]
11
12
Colon ,
12
13
#[ token = "," ]
13
14
Comma ,
14
15
#[ token = "fun" ]
15
- Fun ,
16
+ FunTerm ,
16
17
#[ token = "=>" ]
17
18
DArrow ,
18
19
#[ token = "->" ]
@@ -59,19 +60,21 @@ enum LexToken {
59
60
Error ,
60
61
}
61
62
62
- /// The subset of `LexToken`s for the parser.
63
- /// The tokens in `LexToken`s which are excluded from this enum are:
64
- /// * Whitespace -- skipped.
65
- /// * EOF -- turned into None, rather than a token.
66
- /// * Error -- turned into Some(Err(...)).
63
+ /// The subset of `LexerToken`s for the parser.
64
+ ///
65
+ /// The tokens in `LexerToken`s which are excluded from this enum are:
66
+ ///
67
+ /// - `Whitespace`: skipped.
68
+ /// - `Eof`: turned into `None`, rather than a token.
69
+ /// - `Error`: turned into `Some(Err(...))`.
67
70
///
68
71
/// Comment while a valid token has been reserved but is not currently
69
72
/// emitted by the lexer.
70
73
#[ derive( Debug , Clone ) ]
71
74
pub enum Token < ' a > {
72
75
Colon ,
73
76
Comma ,
74
- Fun ,
77
+ FunTerm ,
75
78
DArrow ,
76
79
Arrow ,
77
80
LParen ,
@@ -98,7 +101,7 @@ impl<'a> fmt::Display for Token<'a> {
98
101
match self {
99
102
Token :: Colon => write ! ( f, ":" ) ,
100
103
Token :: Comma => write ! ( f, "," ) ,
101
- Token :: Fun => write ! ( f, "Fun " ) ,
104
+ Token :: FunTerm => write ! ( f, "fun " ) ,
102
105
Token :: DArrow => write ! ( f, "=>" ) ,
103
106
Token :: Arrow => write ! ( f, "->" ) ,
104
107
Token :: LParen => write ! ( f, "(" ) ,
@@ -121,72 +124,81 @@ impl<'a> fmt::Display for Token<'a> {
121
124
}
122
125
}
123
126
124
- #[ derive( Debug ) ]
125
- pub struct LexicalError ( std:: ops:: Range < usize > , & ' static str ) ;
127
+ #[ derive( Debug , Clone ) ]
128
+ pub enum LexerError {
129
+ InvalidToken ( Range < usize > ) ,
130
+ }
126
131
127
- impl fmt:: Display for LexicalError {
132
+ impl fmt:: Display for LexerError {
128
133
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
129
- write ! ( f, "Lexical error: {:?} {}" , self . 0 , self . 1 )
134
+ match self {
135
+ LexerError :: InvalidToken ( range) => write ! ( f, "Invalid token: {:?}" , range) ,
136
+ }
130
137
}
131
138
}
132
139
133
- pub struct Tokens < ' a > ( logos:: Lexer < LexToken , & ' a str > ) ;
140
+ pub struct Tokens < ' a > {
141
+ lexer : logos:: Lexer < LexerToken , & ' a str > ,
142
+ }
143
+
134
144
pub type Spanned < Tok , Loc , Error > = Result < ( Loc , Tok , Loc ) , Error > ;
135
145
136
146
impl < ' a > Tokens < ' a > {
137
147
pub fn new ( source : & ' a str ) -> Tokens < ' a > {
138
- Tokens ( LexToken :: lexer ( source) )
148
+ Tokens {
149
+ lexer : LexerToken :: lexer ( source) ,
150
+ }
139
151
}
140
152
}
141
153
142
154
impl < ' a > Iterator for Tokens < ' a > {
143
- type Item = Spanned < Token < ' a > , usize , LexicalError > ;
155
+ type Item = Spanned < Token < ' a > , usize , LexerError > ;
144
156
145
157
fn next ( & mut self ) -> Option < Self :: Item > {
146
- let lex = & mut self . 0 ;
158
+ let lexer = & mut self . lexer ;
147
159
148
160
const fn tok < ' a > (
149
- r : std :: ops :: Range < usize > ,
161
+ r : Range < usize > ,
150
162
t : Token < ' a > ,
151
- ) -> Option < Spanned < Token < ' a > , usize , LexicalError > > {
163
+ ) -> Option < Spanned < Token < ' a > , usize , LexerError > > {
152
164
Some ( Ok ( ( r. start , t, r. end ) ) )
153
165
}
154
166
155
- let range = lex . range ( ) ;
167
+ let range = lexer . range ( ) ;
156
168
157
169
let token = loop {
158
- match & lex . token {
159
- // There doesn't seem to be any harm in advancing after EOF .
170
+ match & lexer . token {
171
+ // There doesn't seem to be any harm in advancing after `Eof` .
160
172
// But we might as well return.
161
- LexToken :: EOF => return None ,
162
- LexToken :: Error => break Some ( Err ( LexicalError ( range, "Lexical error" ) ) ) ,
163
- LexToken :: Whitespace | LexToken :: Comment => {
164
- lex . advance ( ) ;
173
+ LexerToken :: Eof => return None ,
174
+ LexerToken :: Error => break Some ( Err ( LexerError :: InvalidToken ( range) ) ) ,
175
+ LexerToken :: Whitespace | LexerToken :: Comment => {
176
+ lexer . advance ( ) ;
165
177
continue ;
166
178
}
167
- LexToken :: Colon => break tok ( range, Token :: Colon ) ,
168
- LexToken :: Comma => break tok ( range, Token :: Comma ) ,
169
- LexToken :: Fun => break tok ( range, Token :: Fun ) ,
170
- LexToken :: DArrow => break tok ( range, Token :: DArrow ) ,
171
- LexToken :: Arrow => break tok ( range, Token :: Arrow ) ,
172
- LexToken :: LParen => break tok ( range, Token :: LParen ) ,
173
- LexToken :: RParen => break tok ( range, Token :: RParen ) ,
174
- LexToken :: LBrack => break tok ( range, Token :: LBrack ) ,
175
- LexToken :: RBrack => break tok ( range, Token :: RBrack ) ,
176
- LexToken :: LBrace => break tok ( range, Token :: LBrace ) ,
177
- LexToken :: RBrace => break tok ( range, Token :: RBrace ) ,
178
- LexToken :: Dot => break tok ( range, Token :: Dot ) ,
179
- LexToken :: Equal => break tok ( range, Token :: Equal ) ,
180
- LexToken :: RecordTerm => break tok ( range, Token :: RecordTerm ) ,
181
- LexToken :: RecordType => break tok ( range, Token :: RecordType ) ,
182
- LexToken :: Name => break tok ( range, Token :: Name ( lex . slice ( ) ) ) ,
183
- LexToken :: Shift => break tok ( range, Token :: Shift ( lex . slice ( ) ) ) ,
184
- LexToken :: NumLiteral => break tok ( range, Token :: NumLiteral ( lex . slice ( ) ) ) ,
185
- LexToken :: CharLiteral => break tok ( range, Token :: CharLiteral ( lex . slice ( ) ) ) ,
186
- LexToken :: StrLiteral => break tok ( range, Token :: StrLiteral ( lex . slice ( ) ) ) ,
179
+ LexerToken :: Colon => break tok ( range, Token :: Colon ) ,
180
+ LexerToken :: Comma => break tok ( range, Token :: Comma ) ,
181
+ LexerToken :: FunTerm => break tok ( range, Token :: FunTerm ) ,
182
+ LexerToken :: DArrow => break tok ( range, Token :: DArrow ) ,
183
+ LexerToken :: Arrow => break tok ( range, Token :: Arrow ) ,
184
+ LexerToken :: LParen => break tok ( range, Token :: LParen ) ,
185
+ LexerToken :: RParen => break tok ( range, Token :: RParen ) ,
186
+ LexerToken :: LBrack => break tok ( range, Token :: LBrack ) ,
187
+ LexerToken :: RBrack => break tok ( range, Token :: RBrack ) ,
188
+ LexerToken :: LBrace => break tok ( range, Token :: LBrace ) ,
189
+ LexerToken :: RBrace => break tok ( range, Token :: RBrace ) ,
190
+ LexerToken :: Dot => break tok ( range, Token :: Dot ) ,
191
+ LexerToken :: Equal => break tok ( range, Token :: Equal ) ,
192
+ LexerToken :: RecordTerm => break tok ( range, Token :: RecordTerm ) ,
193
+ LexerToken :: RecordType => break tok ( range, Token :: RecordType ) ,
194
+ LexerToken :: Name => break tok ( range, Token :: Name ( lexer . slice ( ) ) ) ,
195
+ LexerToken :: Shift => break tok ( range, Token :: Shift ( lexer . slice ( ) ) ) ,
196
+ LexerToken :: NumLiteral => break tok ( range, Token :: NumLiteral ( lexer . slice ( ) ) ) ,
197
+ LexerToken :: CharLiteral => break tok ( range, Token :: CharLiteral ( lexer . slice ( ) ) ) ,
198
+ LexerToken :: StrLiteral => break tok ( range, Token :: StrLiteral ( lexer . slice ( ) ) ) ,
187
199
}
188
200
} ;
189
- lex . advance ( ) ;
201
+ lexer . advance ( ) ;
190
202
token
191
203
}
192
204
}
@@ -195,7 +207,7 @@ impl<'a> Iterator for Tokens<'a> {
195
207
fn behavior_after_error ( ) {
196
208
let starts_with_invalid = "@." ;
197
209
// [Err(...), Some(Token::DOT)]
198
- let from_lex: Vec < Spanned < Token < ' static > , usize , LexicalError > > =
210
+ let from_lex: Vec < Spanned < Token < ' static > , usize , LexerError > > =
199
211
Tokens :: new ( starts_with_invalid) . collect ( ) ;
200
212
let result: Vec < bool > = from_lex. iter ( ) . map ( Result :: is_ok) . collect ( ) ;
201
213
assert_eq ! ( result, vec![ false , true ] ) ;
0 commit comments