Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutual recursion with #[cache_left_rec] fails #359

Open
kevinmehall opened this issue Jul 30, 2023 Discussed in #358 · 0 comments
Open

Mutual recursion with #[cache_left_rec] fails #359

kevinmehall opened this issue Jul 30, 2023 Discussed in #358 · 0 comments
Labels

Comments

@kevinmehall
Copy link
Owner

Discussed in #358

Originally posted by stqcky July 30, 2023
Hi, I'm having some issues using the #[cache_left_rec] attribute.

Here's my code:

#[derive(Clone, PartialEq, Debug)]
pub enum TestExpression {
    FunctionCall {
        callee: Box<TestExpression>,
        arguments: Vec<TestExpression>
    },
    Identifier(String)
}

peg::parser! {
    grammar test() for str {
        pub rule identifier() -> TestExpression = i:$(['a'..='z']+) {
            TestExpression::Identifier(i.to_string())
        }

        #[cache_left_rec]
        pub rule expression() -> TestExpression = exp:(function_call() / identifier()) {
            exp
        }
         
        rule lparen() = "("
        rule rparen() = ")"

        #[cache_left_rec]
        pub rule function_call() -> TestExpression = callee:expression() lparen() arg:(expression() ** ",") rparen() {
            TestExpression::FunctionCall { callee: Box::new(callee), arguments: arg }
        }
    }
}


pub fn parse() {
    let input = "abc()";
    let a = test::expression(&input);
    println!("{:?}", a);
}

When I try to match the string abc() with the rule function_call it works fine, returning Ok(FunctionCall { callee: Identifier("abc"), arguments: [] }).
But when I try to match the same string with the expression rule it doesn't work.
Here's the trace:

[PEG_TRACE] Attempting to match rule `expression` at 1:1
[PEG_TRACE] Attempting to match rule `function_call` at 1:1
[PEG_TRACE] Cached fail of rule expression at 1:1
[PEG_TRACE] Failed to match rule `function_call` at 1:1
[PEG_TRACE] Attempting to match rule `identifier` at 1:1
[PEG_TRACE] Matched rule `identifier` at 1:1 to 1:4
[PEG_TRACE] Matched rule `expression` at 1:1 to 1:4
[PEG_TRACE] Attempting to match rule `expression` at 1:1
[PEG_TRACE] Cached fail of rule function_call at 1:1
[PEG_TRACE] Attempting to match rule `identifier` at 1:1
[PEG_TRACE] Matched rule `identifier` at 1:1 to 1:4
[PEG_TRACE] Matched rule `expression` at 1:1 to 1:4
[PEG_TRACE] Attempting to match rule `expression` at 1:1
[PEG_TRACE] Attempting to match rule `function_call` at 1:1
[PEG_TRACE] Cached fail of rule expression at 1:1
[PEG_TRACE] Failed to match rule `function_call` at 1:1
[PEG_TRACE] Attempting to match rule `identifier` at 1:1
[PEG_TRACE] Matched rule `identifier` at 1:1 to 1:4
[PEG_TRACE] Matched rule `expression` at 1:1 to 1:4
[PEG_TRACE] Attempting to match rule `expression` at 1:1
[PEG_TRACE] Cached fail of rule function_call at 1:1
[PEG_TRACE] Attempting to match rule `identifier` at 1:1
[PEG_TRACE] Matched rule `identifier` at 1:1 to 1:4
[PEG_TRACE] Matched rule `expression` at 1:1 to 1:4
Err(ParseError { location: LineCol { line: 1, column: 4, offset: 3 }, expected: ExpectedSet { expected: {"['a' ..= 'z']", "EOF"} } })

It looks as if it just discards the possibility of the expression being a function_call at the very beginning and just matches abc as an identifier, leaving () which then causes the error.
I would really appreciate some help, as I have banged my head against this for like 2 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant