我在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 :(得分:2)
首先,这不是真正的C ++。 <iostream.h>
从未成为C ++标准的一部分,因此已经过时至少15年。除cout
部分外,没有剩下的C ++。过程方法,使用固定的char数组而不是动态可重用的字符串,你包含的标题和缺少类使你的程序的其余部分纯C代码。
要从文件而不是控制台解析输入,只需打开相应的 filestream ,从那里获取输入并解析它。您可能希望稍微重构一下您的程序,例如使用字符串而不是容易出错的char[]
,可能会抛出异常而不是仅在出现错误时退出应用程序,然后将解析器逻辑包装到一个类。
我在那里强调了一些词,在阅读你的代码时,我认为你可能不熟悉。在您选择的C ++教科书中查找它们。如果你想创建更复杂的程序,它会对你有所帮助。
答案 1 :(得分: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;
...
}
似乎比您已编写的代码更容易。