2015-04-16 6 views
2

Реализация рекурсивного парсера спуска для данной грамматики с образцом ввода '(a)'.
Результат этой программы - проверить, успешно ли проанализирован ввод, прочитанный пользователем, или нет. Как того, как поток программы должны идти для этого конкретного входа ...
Рекурсивный спускный анализатор в C - ошибка при обратном отслеживании

main() называет стартовый символ E() -> T() -> T1() [который имеет значение ложь], следовательно, прослеживая назад к родительской функции T() которая теперь называет T2() (который также оценивает на значение false), следовательно T() -> T3() -> E() -> E1() -> T() -> T1() (приравнивается к true).

В конце концов E() также должен быть верным и последнее условие termial(')') в операторе return termial('(') && E() && termial(')'); от функции T3() должно быть выполнено с ')' в качестве значения для token. Тем не менее, оказывается, что token == '(' еще и, следовательно, вывод результатов программы в

разобранного Неудачно

Не совсем уверен, почему token не равное ')'

//Grammar : 
//E -> T | T + E 
//T -> a | a * T | (E) 
// 
//Input : 
//(a) 

#include <stdio.h> 

char *next; 

int E(); 
int E1(); 
int E2(); 
int T(); 
int T1(); 
int T2(); 
int T3(); 

int termial(char token){ 
    return (*next++ == token); 
} 

int E1(){ 
    return T(); 
} 

int E2(){ 
    return T() && termial('+') && E(); 
} 

int E(){ 
    char *temp = next; 
    return (next = temp, E1()) || (next = temp, E2()); 
} 

int T1(){ 
    return termial('a'); 
} 

int T2(){ 
    return termial('a') && termial('*') && T(); 
} 

int T3(){ 
    return termial('(') && E() && termial(')'); 
} 

int T(){ 
    char *temp = next; 
    return (next = temp, T1()) || (next = temp, T2()), (next = temp, T3()); 
} 


int main(int argc, const char * argv[]) { 
    char str[10]; 
    int result; 
    printf("INPUT a string to be parsed : "); 
    scanf("%s", str); 
    next = &str[0]; 
    result = E(); 
    result == 1 ? printf("Parsed Successfully") : printf("Parsed Unsuccessfully"); 
    printf("\n"); 
    return 0; 
} 
+0

Я рекомендую выполнять это с помощью отладчика, показывая 'next' и увидеть, где именно, ваши ожидания пропускаются. Если это не говорит вам, что вам нужно знать, опубликуйте результаты здесь. –

+0

Выход после печати ** ** следующего в терминале **() **: (а) (а) (а) а) а) а) а) (а) (а) (а) а) а) а) а) Parsed Неудачно – mrdoubtful

ответ

4

В T() :

int T(){ 
    char *temp = next; 
    return (next = temp, T1()) || (next = temp, T2()), (next = temp, T3()); 
} 

(next = temp, T3()) является всегда называется (нет короткого замыкания на запятая перед ним), и будет возвращать false в большинстве ваших случаев, в результате чего все виды неудач, когда T1() или T2() успеха и должен был завершиться функцию с успехом.

Изменение этой строки:

return (next = temp, T1()) || (next = temp, T2()) || (next = temp, T3()); 
+0

Эй ТНХ много .... мой плохой! : D – mrdoubtful