gpt4 book ai didi

parsing - PEG:我的 if 语句语法有什么问题?

转载 作者:行者123 更新时间:2023-12-03 11:29:46 24 4
gpt4 key购买 nike

我正在使用 rust-peg 实现类似 OCaml 的语言我的解析器有一个错误。
我定义了 if 语句语法,但它不起作用。
我猜测试用例输入被解析为 Apply(Apply(Apply(Apply(f, then), 2) else), 4) .我的意思是 "then"被解析为 Ident,而不是关键字。
我不知道修复这个应用表达式语法。你有什么想法?

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Expression {
Number(i64),
If {
cond: Box<Expression>,
conseq: Box<Expression>,
alt: Box<Expression>,
},
Ident(String),
Apply(Box<Expression>, Box<Expression>),
}

use peg::parser;
use toplevel::expression;
use Expression::*;

parser! {
pub grammar toplevel() for str {

rule _() = [' ' | '\n']*

pub rule expression() -> Expression
= expr()

rule expr() -> Expression
= if_expr()
/ apply_expr()

rule if_expr() -> Expression
= "if" _ cond:expr() _ "then" _ conseq:expr() _ "else" _ alt:expr() {
Expression::If {
cond: Box::new(cond),
conseq: Box::new(conseq),
alt: Box::new(alt)
}
}

rule apply_expr() -> Expression
= e1:atom() _ e2:atom() { Apply(Box::new(e1), Box::new(e2)) }
/ atom()

rule atom() -> Expression
= number()
/ id:ident() { Ident(id) }

rule number() -> Expression
= n:$(['0'..='9']+) { Expression::Number(n.parse().unwrap()) }

rule ident() -> String
= id:$(['a'..='z' | 'A'..='Z']['a'..='z' | 'A'..='Z' | '0'..='9']*) { id.to_string() }
}}

fn main() {
assert_eq!(expression("1"), Ok(Number(1)));
assert_eq!(
expression("myFunc 10"),
Ok(Apply(
Box::new(Ident("myFunc".to_string())),
Box::new(Number(10))
))
);

// failed
assert_eq!(
expression("if f then 2 else 3"),
Ok(If {
cond: Box::new(Ident("f".to_string())),
conseq: Box::new(Number(2)),
alt: Box::new(Number(3))
})
);
}
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `Err(ParseError { location: LineCol { line: 1, column: 11, offset: 10 }, expected: ExpectedSet { expected: {"\"then\"", "\' \' | \'\\n\'"} } })`,
right: `Ok(If { cond: Ident("f"), conseq: Number(2), alt: Number(3) })`', src/main.rs:64:5

最佳答案

PEG 使用有序选择。这意味着当你写 R = A / B对于某些规则 R , 如果在一个位置 A成功解析,它将 从不 试试 B ,即使选择A导致以后出现问题。这是与上下文无关文法的核心区别,并且经常被忽视。
特别是当你写 apply = atom atom / atom , 如果可以连续解析两个原子,则 从不 尝试只解析一个,即使这意味着其余的在以后没有意义。
将此与事实相结合 thenelse在你的语法中是非常好的标识符,你会看到你看到的问题。

关于parsing - PEG:我的 if 语句语法有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63544801/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com