Skip to content

Commit 1687e67

Browse files
committed
init commit
Signed-off-by: Sn0rt <[email protected]>
0 parents  commit 1687e67

File tree

6 files changed

+599
-0
lines changed

6 files changed

+599
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
.idea

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "lambda-vm"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]

src/lambda_parse.rs

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
use std::rc::Rc;
2+
use std::iter::Peekable;
3+
use std::vec::IntoIter;
4+
5+
// <expression> :== <abstraction> | <application> | <variable>
6+
// <abstraction> :== λ <variable> . <expression>
7+
// <application> :== ( <expression> <expression> )
8+
// <variable> :== v1 | v2 | ...
9+
10+
#[derive(Clone, Debug)]
11+
pub enum LambdaExpression {
12+
Variable(String),
13+
Abstraction {
14+
parameter: String,
15+
body: Rc<LambdaExpression>,
16+
},
17+
Application {
18+
function: Rc<LambdaExpression>,
19+
argument: Rc<LambdaExpression>,
20+
},
21+
Number(u64), // 新增:表示自然数
22+
}
23+
24+
#[derive(Debug)]
25+
pub struct ParseError {
26+
message: String,
27+
}
28+
29+
pub fn parse_lambda(input: &str) -> Result<LambdaExpression, ParseError> {
30+
let mut tokens = tokenize(input);
31+
let result = parse_lambda_expression(&mut tokens);
32+
33+
// 确保所有的 token 都被消耗
34+
if tokens.peek().is_some() {
35+
Err(ParseError { message: "Unexpected tokens at end of input".to_string() })
36+
} else {
37+
result
38+
}
39+
}
40+
41+
fn tokenize(input: &str) -> Peekable<IntoIter<String>> {
42+
let mut tokens = Vec::new();
43+
let mut current_token = String::new();
44+
45+
for ch in input.chars() {
46+
match ch {
47+
'(' | ')' | '.' | 'λ' | '\\' => {
48+
if !current_token.is_empty() {
49+
tokens.push(current_token);
50+
current_token = String::new();
51+
}
52+
tokens.push(ch.to_string());
53+
}
54+
' ' | '\t' | '\n' => {
55+
if !current_token.is_empty() {
56+
tokens.push(current_token);
57+
current_token = String::new();
58+
}
59+
}
60+
_ => current_token.push(ch),
61+
}
62+
}
63+
64+
if !current_token.is_empty() {
65+
tokens.push(current_token);
66+
}
67+
68+
tokens.into_iter().peekable()
69+
}
70+
71+
fn parse_lambda_expression(tokens: &mut Peekable<IntoIter<String>>) -> Result<LambdaExpression, ParseError> {
72+
let mut expr = parse_atomic_expression(tokens)?;
73+
74+
while let Some(token) = tokens.peek() {
75+
if token == ")" {
76+
break;
77+
}
78+
let arg = parse_atomic_expression(tokens)?;
79+
expr = LambdaExpression::Application {
80+
function: Rc::new(expr),
81+
argument: Rc::new(arg),
82+
};
83+
}
84+
85+
Ok(expr)
86+
}
87+
88+
fn parse_atomic_expression(tokens: &mut Peekable<IntoIter<String>>) -> Result<LambdaExpression, ParseError> {
89+
match tokens.next() {
90+
Some(token) => {
91+
match token.as_str() {
92+
"λ" | "\\" => parse_abstraction(tokens),
93+
"(" => {
94+
let inner_expr = parse_lambda_expression(tokens)?;
95+
expect_token(tokens, ")")?;
96+
Ok(inner_expr)
97+
},
98+
_ => {
99+
// 尝试将 token 解析为数字
100+
if let Ok(num) = token.parse::<u64>() {
101+
Ok(LambdaExpression::Number(num))
102+
} else {
103+
Ok(LambdaExpression::Variable(token))
104+
}
105+
},
106+
}
107+
},
108+
None => Err(ParseError { message: "Unexpected end of input".to_string() }),
109+
}
110+
}
111+
112+
fn parse_abstraction(tokens: &mut Peekable<IntoIter<String>>) -> Result<LambdaExpression, ParseError> {
113+
let mut parameters = Vec::new();
114+
while let Some(token) = tokens.next() {
115+
if token == "." {
116+
break;
117+
}
118+
parameters.push(token);
119+
}
120+
if parameters.is_empty() {
121+
return Err(ParseError { message: "Expected parameter after λ".to_string() });
122+
}
123+
let body = parse_lambda_expression(tokens)?;
124+
125+
// 从最内层的抽象开始构建
126+
let mut expr = body;
127+
for param in parameters.into_iter().rev() {
128+
expr = LambdaExpression::Abstraction {
129+
parameter: param,
130+
body: Rc::new(expr),
131+
};
132+
}
133+
Ok(expr)
134+
}
135+
136+
fn expect_token(tokens: &mut Peekable<IntoIter<String>>, expected: &str) -> Result<(), ParseError> {
137+
match tokens.next() {
138+
Some(token) if token == expected => Ok(()),
139+
Some(token) => Err(ParseError { message: format!("Expected '{}', found '{}'", expected, token) }),
140+
None => Err(ParseError { message: format!("Expected '{}', found end of input", expected) }),
141+
}
142+
}
143+
144+
#[cfg(test)]
145+
mod tests {
146+
use super::*;
147+
148+
#[test]
149+
fn test_simple_application() {
150+
let input = "(λx. x) y";
151+
println!("Input: {}", input);
152+
let tokens = tokenize(input);
153+
println!("Tokens: {:?}", tokens);
154+
let result = parse_lambda(input);
155+
println!("Parsed result: {:?}", result);
156+
assert!(result.is_ok(), "Failed to parse: {:?}", result.err());
157+
let expr = result.unwrap();
158+
println!("Parsed expression: {:?}", expr);
159+
match expr {
160+
LambdaExpression::Application { function, argument } => {
161+
println!("Function: {:?}", function);
162+
println!("Argument: {:?}", argument);
163+
match &*function {
164+
LambdaExpression::Abstraction { parameter, body } => {
165+
assert_eq!(parameter, "x");
166+
assert!(matches!(&**body, LambdaExpression::Variable(name) if name == "x"));
167+
},
168+
_ => panic!("Expected Abstraction, got {:?}", function),
169+
}
170+
assert!(matches!(&*argument, LambdaExpression::Variable(name) if name == "y"));
171+
},
172+
_ => panic!("Expected Application, got {:?}", expr),
173+
}
174+
}
175+
176+
#[test]
177+
fn test_nested_application() {
178+
let input = "(λf. λx. f (f x)) (λy. y) z";
179+
let result = parse_lambda(input);
180+
assert!(result.is_ok());
181+
// 可以添加更详细的结构检查
182+
}
183+
184+
#[test]
185+
fn test_identity_function() {
186+
let input = "λx. x";
187+
let result = parse_lambda(input);
188+
assert!(result.is_ok());
189+
let expr = result.unwrap();
190+
match expr {
191+
LambdaExpression::Abstraction { parameter, body } => {
192+
assert_eq!(parameter, "x");
193+
assert!(matches!(&*body, LambdaExpression::Variable(name) if name == "x"));
194+
},
195+
_ => panic!("Expected Abstraction, got {:?}", expr),
196+
}
197+
}
198+
199+
#[test]
200+
fn test_complex_expression() {
201+
let input = "(λf. λx. f (f x)) (λy. y)";
202+
let result = parse_lambda(input);
203+
assert!(result.is_ok());
204+
// 可以添加更详细的结构检查
205+
}
206+
}

0 commit comments

Comments
 (0)