2013-04-26 6 views
-1

Я реализовал рекурсивный парсер спуска на C++, основанный на грамматике EBNF и его псевдокоде. Вот код:Рекурсивная реализация парсера спуска в C++, основанная на грамматике EBNF

#include<iostream.h> 
#include<conio.h> 
#include<string.h> 
#include<stdlib.h> 
char s[100]; 
int pos=-1,len; 

void asignstmt(); 
void variable(); 
void expression(); 
void term(); 
void primary(); 
void subscriptlist(); 
void identifier(); 
void letter(); 
void digit(); 
void error(); 

void main() 
{ 
clrscr(); 
cout<<"Enter the String "; 
cin>>s; 
len=strlen(s); 
s[len]='$'; 
asignstmt(); 
if (len==pos) 
cout<<"string Accepted"; 
else 
cout<<"Strig not Accepted"; 

getch(); 
} 
void asignstmt() 
{ 
    pos++; 
    cout<<pos<<" "<<s[pos]<<endl; 
    if(pos<len) 
    { 
     variable(); 

     if(s[pos]== '=') 
    { 
     pos++;cout<<pos<<" "<<s[pos]<<endl; 
     expression(); 
    } 
    else 
     error(); 
    } 
} 

void variable() 
{ 
    identifier(); 
    if(s[pos]=='[') 
    { 
    pos++;cout<<pos<<" "<<s[pos]<<endl; 
    subscriptlist(); 
    if(s[pos]==']') 
    pos++; 
    } 
} 

void expression() 
{ 
    term(); 
    while (s[pos]=='+' || s[pos]=='-') 
    { 
     pos++; cout<<pos<<" "<<s[pos]<<endl; 
     term(); 
    } 
} 

void term() 
{ 
    primary(); 
    while (s[pos]=='*' || s[pos]=='/') 
    { 
     pos++; cout<<pos<<" "<<s[pos]<<endl; 
     primary(); 
    } 
} 


void primary() 
{ 
if ((s[pos]>='A'|| s[pos]>='a') &&(s[pos]<='Z'|| s[pos]<='z')) 
    variable(); 
else if (s[pos]>='0' && s[pos]<='9') 
    digit(); 
else if (s[pos]=='(') 
    { pos++; cout<<pos<<" "<<s[pos]<<endl; 
    expression(); 
    if(s[pos]==')') 
    pos++; cout<<pos<<" "<<s[pos]<<endl; 
    } 
    else 
    error(); 
} 

void subscriptlist() 
{ 
expression(); 
    if(s[pos]==',') 
     pos++; cout<<pos<<" "<<s[pos]<<endl; 
    expression(); 

} 

void identifier() 
{ 
int fl=pos; 
letter(); 
if(pos==fl) 
error(); 
while ((s[pos]>='A'&& s[pos]<='Z') ||(s[pos]>='a'&& s[pos]<='z')||(s[pos]>='0'&& s[pos]<='9')) 
{ letter(); 
    digit(); 
} 
} 
void letter() 
{ 
if((s[pos]>='A'&& s[pos]<='Z') ||(s[pos]>='a'&& s[pos]<='z')) 
    pos++; 
    cout<<pos<<" "<<s[pos]<<endl; 
} 

void digit() 
{ 
if(s[pos]>='0' && s[pos]<='9') 
pos++; 
cout<<pos<<" "<<s[pos]<<endl; 
} 

void error() 
{ 
cout<<"Error Due to grammar Mismatch"<<endl; 
getch(); 
exit(0); 
} 

Эта программа просто берет вход (вход будет действительным оператором присваивания без пробелов) от пользователя. Проверяет, правильно ли используется оператор присваивания suntax-ed или нет. Затем выводится сообщение о принятии или отклонении входной строки.

Моя цель этой реализации - дать парсер. У меня есть этот код, который работает/распознает правильную инструкцию присваивания. Но я не могу реализовать это как синтаксический анализатор, в котором: он будет принимать .cpp-файл в качестве аргумента, проверять его по символу и видеть, имеет ли он правильную инструкцию присваивания или нет.

Например, если имя моего парсера - userParser.cpp, а файл кода пользователя, содержащий оператор присваивания, - sample.cpp, тогда команда Like: userParser sample.cpp должна анализировать и проверять файл для правильного синтаксиса оператор присваивания. Пожалуйста, направляйте меня для реализации реализации C++ в качестве синтаксического анализатора. Спасибо.

+0

Итак, этот вопрос в основном о том, как открыть и прочитать из файла? И как читать аргументы командной строки? – john

+0

Да, с точки зрения синтаксического анализа :( – sana

ответ

2

Прежде всего, на самом деле это не C++. <iostream.h> никогда не был частью стандарта C++ и поэтому устарел не менее 15 лет. И помимо части cout, C++ не осталось. Процедурный подход, использование фиксированного массива символов вместо динамической строки , заголовки, которые вы включаете, и отсутствие классов делают остальную часть вашей программы чистым кодом C.

Чтобы разобрать входные данные из файла вместо консоли, просто откройте соответствующий файл, введите его и проанализируйте его. Возможно, вам захочется сначала реорганизовать вашу программу, например. используя строку вместо ошибки склонными char[], может быть сгенерировано исключение вместо того, чтобы просто выхода из приложения в случае ошибок, а затем обернуть синтаксический анализатор логики в класса.

Я выделил несколько слов, которые, читая ваш код, я думаю, вы, возможно, не знакомы. Посмотрите их в учебнике на C++ по вашему выбору. Это поможет вам, если вы хотите создать более сложные программы.

1

Что-то вроде этого

#include <fstream.h> 
#include <iostream.h> 

int main(int argc, char** argv) 
{ 
    if (argc != 2) 
    { 
     cerr << "Wrong number of arguments\n"; 
     return 1; 
    } 
    ifstream file(argv[1]); 
    file >> s; 
    ... 
} 

Кажется проще, чем код, который вы уже написали.

+0

Итак, все символы файла будут перенесены в массив «S», правильно? – sana

+0

Также, пожалуйста, помогите мне: я использую turbo C++, как я буду компилировать парсер и файлы примеров в командной строке? – sana

+0

'' и '' не являются C++, по крайней мере, они никогда не были стандартными C++. Они использовались только некоторыми поставщиками компилятора в прошлом веке. –

 Смежные вопросы

  • Нет связанных вопросов^_^