我试图解析一个简单的脚本语言的表达式,但我很困惑。现在,只能将数字和字符串文字解析为表达式:
int x = 5;
double y = 3.4;
str t = "this is a string";
但是,我对解析更复杂的表达式很困惑:
int a = 5 + 9;
int x = (5 + a) - (a ^ 2);
我想我会像以下那样实现它:
do {
// no clue what I would do here?
if (current token is a semi colon) break;
}
while (true);
任何帮助都会很棒,我不知道从哪里开始。感谢。
编辑: 我的解析器是递归下降解析器
我的表达"班级"如下:
typedef struct s_Expression {
char type;
Token *value;
struct s_Expression *leftHand;
char operand;
struct s_Expression *rightHand;
} ExpressionNode;
有人提到递归下降解析器能够解析表达而不做中缀,而不是postfix。最好是,我想要一个像这样的表达式:
例如:
int x = (5 + 5) - (a / b);
将被解析为: 注意:这不是有效的C,这只是一些伪的代码来简单地说明我的观点:)
ExpressionNode lh;
lh.leftHand = new ExpressionNode(5);
lh.operand = '+'
lh.rightHand = new ExpressionNode(5);
ExpressionNode rh;
rh.leftHand = new ExpressionNode(a);
rh.operand = '/';
rh.rightHand = new ExpressionNode(b);
ExpressionNode res;
res.leftHand = lh;
res.operand = '-';
res.rightHand = rh;
我很晚才问这个问题,很抱歉,如果我不清楚,我完全忘记了我最初的目标。
答案 0 :(得分:1)
有多种方法可以做到这一点。我过去使用的是读取输入字符串(即编程语言代码)并将表达式从中缀转换为反向抛光表示法。这是一篇关于这样做的非常好的帖子:
http://andreinc.net/2010/10/05/converting-infix-to-rpn-shunting-yard-algorithm/
请注意,=
也是一个运算符,因此您的解析应该包含整个代码文件,而不仅仅是某些表达式。
一旦进行反向抛光,表达式就非常容易评估。您只需弹出堆栈,随时存储操作数,直到您遇到操作员。根据操作员的要求从堆栈中弹出尽可能多的操作数并执行操作。
答案 1 :(得分:1)
我最终使用的方法是Operator precedence parsing。
parse_expression_1 (lhs, min_precedence)
lookahead := peek next token
while lookahead is a binary operator whose precedence is >= min_precedence
op := lookahead
advance to next token
rhs := parse_primary ()
lookahead := peek next token
while lookahead is a binary operator whose precedence is greater
than op's, or a right-associative operator
whose precedence is equal to op's
rhs := parse_expression_1 (rhs, lookahead's precedence)
lookahead := peek next token
lhs := the result of applying op with operands lhs and rhs
return lhs
答案 2 :(得分:0)
如果你正在构建一个递归下降解析器,实现一个分流码是很多不必要的工作,因为递归下降完全能够自己评估表达式或输出RPN。
您还没有告诉我们您的编程语言,Token
结构,甚至是您想要实现的内容,因此很难为您提供示例代码。看看Eric White在C#中递归下降解析器的implementation。如果您提供更多详细信息,我们将提供更多帮助。