以下代码应该生成输入表达式的解析树,但问题是输出E,T,F,S(代码中使用的函数)。我希望它像:
a + b * c => E * c => E + b * c => A + B * C
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char next;
void E(void);void T(void);
void S(void);void F(void);
void error(int);void scan(void);
void enter(char);
void leave(char);
void spaces(int);
int level = 0;
//The main should always be very simple
//First scan the string
//second check for end of string reached , if yes success and if not error.
//P ---> E '#'
int main(void){
printf("Input:");
scan(); E();
if (next != '#') error(1);
else printf("***** Successful parse *****\n");
}
//E ---> T {('+'|'-') T}
void E(void){
enter('E');
T();
while (next == '+' || next == '-') {
scan();
T();
}
leave('E');
}
//T ---> S {('*'|'/') S}
void T(void)
{
enter('T'); S();
while (next == '*' || next == '/') {
scan(); S();
}
leave('T');
}
//S ---> F '^' S | F
void S(void)
{
enter('S'); F();
if (next == '^') {
scan(); S();
}
leave('S');
}
//F ---> char | '(' E ')'
void F(void)
{
enter('F');
if (isalpha(next))
{
scan();
}
else if (next == '(') {
scan(); E();
if (next == ')')
scan();
else
error(2);
}
else {
error(3);
}
leave('F');
}
//Scan the entire input
void scan(void){
while (isspace(next = getchar()));
}
void error(int n)
{
printf("\n*** ERROR: %i\n", n);
exit(1);
}
void enter(char name)
{
spaces(level++);
printf("+-%c\n", name);
}
void leave(char name)
{
spaces(--level);
printf("+-%c\n", name);
}
//TO display the parse tree
void spaces(int local_level)
{
while (local_level-- > 0)
printf("| ");
}
答案 0 :(得分:0)
您无法选择解析树。我猜你不理解输出,但(再次)我猜你想要
a+b*c => F+b*c => S+b*c => T+b*c => T+F*c => T+S*c => T+S*F => T+S*S => T+T => E
所以这里有几个问题需要帮助。
E
或T
时处于什么状态?如果您回答第一个问题的自下而上,E,T,S,F,F表示什么(输入E,输入T,输入S,输入F,离开F)?当你离开F时,这意味着解析器成功识别出非终端。
尝试输入字符串1+b*c
。你得到了什么?为什么在E,T,S,F之后出现错误?
如果您了解当前生产的产品,则可以轻松生成您似乎需要的输出。希望这会有所帮助。
答案 1 :(得分:0)
看起来像递归下降解析器。首先,手工制定你的语法。你期待的不是你的语法所说的。从你的评论中你已经得到了
E ---> T {('+'|'-') T} expression
T ---> S {('*'|'/') S} term
S ---> F '^' S | F subexpression?
F ---> char | '(' E ')' factor
E和T的定义使*的优先级高于+,因此无法获得E * c。如果你想要,你必须将语法切换到
E ---> T {('*'|'/') T} expression
T ---> S {('+'|'-') S} term
如果您只想让输出包含表达式的其余部分,