Could not evaluate DW_OP_entry_value

Hi,

I am a newcomer to Rust and crafted an abstract syntax tree(AST) yesterday. However, I encountered the error message "Could not evaluate DW_OP_entry_value" while attempting to invoke the AST::new() function. I totally have no idea how to figure it out. Here are the codes

use std::rc::Rc;
use crate::lex::{Proto, Token};

#[derive(PartialEq, Debug)]
pub enum NodeKind {
    Num,
    Op,
}

#[derive(Debug)]
pub struct Node {
    pub node_kind: NodeKind,
    pub value: Option<Token>,
    pub op: Option<Token>,
    pub left: Option<Rc<Node>>,
    pub right: Option<Rc<Node>>,
}

pub struct AST(pub Node, pub Vec<String>);

impl AST {
    pub fn new(proto: Proto) -> Self {
        let (node, var) = Node::parse_rpn(proto);
        AST(node, var)
    }
}

impl Node {
    fn new_value_node(value: Token) -> Result<Node, String> {
        match value {
            Token::Expression(_) | Token::Function(_, _, _) => {
                let node = Node {
                    node_kind: NodeKind::Num,
                    value: Some(value),
                    op: None,
                    left: None,
                    right: None,
                };

                Ok(node)
            }
            _ => Err(format!("Token {value:?} can not be value of AST!")),
        }
    }

    fn new_op_node(op: Token, left: Node, right: Node) -> Result<Node, String> {
        match op {
            Token::Add | Token::Sub | Token::Div | Token::Times | Token::Superscript(_) => {
                let node = Node {
                    node_kind: NodeKind::Op,
                    value: None,
                    op: Some(op),
                    left: Some(Rc::new(left)),
                    right: Some(Rc::new(right)),
                };

                Ok(node)
            }
            _ => Err(format!("Token {op:?} can not be a operator!")),
        }
    }

    fn parse_rpn(expr: Proto) -> (Node, Vec<String>) {
        let mut stack = Vec::new();
        let mut var = Vec::new();

        for e in expr.into_iter() {
            match e {
                Token::Expression(_) | Token::Function(_, _, _) => {
                    stack.push(Node::new_value_node(e).unwrap());
                }
                Token::Superscript(content) => {
                    let op2 = Node::new_value_node(Token::Expression(content)).unwrap();
                    let op1 = stack.pop().unwrap();

                    // the content of superscript will no longer be used
                    stack.push(Node::new_op_node(
                        Token::Superscript(String::new()), op1, op2).unwrap())
                }
                Token::Var(s) => var.push(s),
                Token::Eos => break,
                _ => {
                    let op2 = stack.pop().unwrap();
                    let op1 = stack.pop().unwrap();

                    stack.push(Node::new_op_node(e, op1, op2).unwrap());
                }
            }
        }

        (stack.pop().unwrap(), var)
    }
}

The implementation for Node is derived from a recursive descent parser written in C by me. When I execute AST::new(), the output from Node::parse_rpn() contains some "invalid value" flagged by debugger(screenshots as followed). Then when I attempt to debug and step into the expression let (node, var) = Node::parse_rpn(proto);, the error "Could not evaluate DW_OP_entry_value" occurred.

As I step into let (node, var) = Node::parse_rpn(proto);, problem occurres:

Is it caused by ownership or something else? I am really confused.

By the way, the code of Token as followed:

#[derive(PartialEq, Debug, Clone)]
pub enum Token {
    // Expression only contains letters, numbers and decimal
    Expression(String),
    // Function`s name, optional arguments and required arguments
    // For example, \sqrt[3]{2} will be parsed as 'Function("sqrt", ["3"], ["2"])'
    Function(String, Vec<String>, Vec<String>),
    // symbol "="
    Equal,
    // symbol "+"
    Add,
    // symbol "/"
    Div,
    // symbol "-"
    Sub,
    // symbol "*"
    Times,
    // The string representing superscripts and subscripts follows the syntax of a carat (^) for superscripts and
    // an underscore (_) for subscripts.
    // For superscripts, "^2" should be translated to Superscript("2"), and "^{2}" should be handled in the same manner too.
    // For subscripts, "_{22}" is converted to Subscript("22").
    // ^
    Superscript(String),
    // See [Landau LaTeX standard] for explanation
    Var(String),
    // \n or \0
    Eos,
    //////// Some other tokens which will never appeared in AST /////////
}

PS: I find something strange: In my situation, the expr for parse_rpn is

But when the function comes to the end, the expr is changed to

As expr is immutable, I wonder why it is changed and who changed it. Is this could be connected to the issue Iā€™m experiencing?

Sorry for my poor English expression :slight_smile:

This is a debugger problem, not a problem in your code.

2 Likes

... and/or how rustrover communicates with the debugger.

Anyway, you can try to swotch to a different debugger at

Settings > Build, execution and deployment > debugger > the dropdown under the rust section

Also try selecting a different data view under

Settings > Build, execution and deployment > Debugger > Data Views > Rust

If all of that doesn't work, you can also try CLion, which has more options of debuggers IIRC. And also try VsCode, I know that debugging is possible but I've never done it myself.

1 Like

Thank you guys! After adding a println!("{:?}", node); statement at the line where I use Node, I observed the expected output :smiley::

Node { node_kind: Op, value: None, op: Some(Add), left: Some(Node { node_kind: Num, value: Some(Expression("a")), op: None, left: None, right: None }), right: Some(Node { node_kind: Num, value: Some(Expression("1")), op: None, left: None, right: None }) }
Node { node_kind: Num, value: Some(Expression("a")), op: None, left: None, right: None }
Node { node_kind: Num, value: Some(Expression("1")), op: None, left: None, right: None }

Perhaps I should report this bug in the JetBrains community.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.