Skip to content

Commit c700725

Browse files
Create lexer.rs
1 parent ef2b695 commit c700725

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/lexer.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
pub fn tokenize(input: &str) -> Option<Vec<String>> {
2+
let mut tokens: Vec<String> = Vec::new();
3+
let mut current_token = String::new();
4+
let mut in_parentheses: usize = 0;
5+
let mut in_quote = false;
6+
let mut is_escape = false;
7+
8+
for c in input.chars() {
9+
if is_escape {
10+
current_token.push(match c {
11+
'n' => '\n',
12+
't' => '\t',
13+
'r' => '\r',
14+
_ => c,
15+
});
16+
is_escape = false;
17+
} else {
18+
match c {
19+
'(' | '{' | '[' if !in_quote => {
20+
current_token.push(c);
21+
in_parentheses += 1;
22+
}
23+
')' | '}' | ']' if !in_quote => {
24+
current_token.push(c);
25+
in_parentheses.checked_sub(1).map(|x| in_parentheses = x);
26+
}
27+
'"' | '\'' | '`' => {
28+
in_quote = !in_quote;
29+
current_token.push(c);
30+
}
31+
'\\' if in_quote => {
32+
current_token.push(c);
33+
is_escape = true;
34+
}
35+
other => {
36+
if other.is_whitespace() && !in_quote {
37+
if in_parentheses != 0 {
38+
current_token.push(c);
39+
} else if !current_token.is_empty() {
40+
tokens.push(current_token.clone());
41+
current_token.clear();
42+
}
43+
} else {
44+
current_token.push(c);
45+
}
46+
}
47+
}
48+
}
49+
}
50+
51+
// Syntax error check
52+
if is_escape || in_quote || in_parentheses != 0 {
53+
return None;
54+
}
55+
if !current_token.is_empty() {
56+
tokens.push(current_token.clone());
57+
current_token.clear();
58+
}
59+
Some(tokens)
60+
}

0 commit comments

Comments
 (0)