正文

[TOJ]1203程序分析器2005-06-07 18:50:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/rickone/1545.html

分享到:

程序分析器 Time Limit:2s Memory Limit:2000k Total Submit:26 Accepted:4 -------------------------------------------------------------------------------- Problem Tiny Basm语言(简称为TB语言)的巴科斯-瑙尔范式(BNF)为: <程序>      ::= <语句> &iquest; { <语句> &iquest; } <语句>      ::= <行号> &yuml; <语句体> <语句体>    ::= <累加语句> | <输出语句> | <转移语句> | <条件语句> | <结束语句> <累加语句>    ::= <变量> + <整数> <输出语句>    ::= <变量> ? <转移语句>    ::= GO &yuml; <行号> <条件语句>    ::= IF &yuml; <变量> = <整数> &yuml; <转移语句> <结束语句>    ::= END <变量>      ::= <字母> <行号>      ::= <整数> <整数>      ::= <数字> { <数字> } <字母>      ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z <数字>      ::= 0|1|2|3|4|5|6|7|8|9 注:其中“::=”表示定义为,“|”表示或,{}内的项可以重复任意多次或不出现,“&yuml;”表示空格(一个字符,ASCII码为32),“&iquest;”表示回车/换行(两个字符,ASCII码分别为13和10)。    错误语句示例(在输入文件中不会出现任何错误语句): 10&yuml;A+1.5                    (不符合累加语句的定义,所加的不是整数) 20&yuml;A&yuml;?                      (不符合输出语句的定义,多加了一个空格) 30&yuml;IF&yuml;A=B&yuml;GO&yuml;10             (不符合条件语句的定义,不应变量=变量)    TB程序的执行: l         程序从行号最小的一条语句开始执行,在未遇到条件语句时按行号由小至大顺序执行。 l         所有变量在程序执行前被自动初始化为0。 l         累加语句将语句中变量的值加上语句中的整数送回该变量。 l         输出语句将语句中变量的值在监视器上显示出来。 l         执行条件语句时,当且仅当该语句中的变量与紧跟在等号后面的整数值相等,后面的转移语句才被执行。该语句中的所有整数值至多为4位。 l         转移语句被执行后,程序将转去执行GO后面指定的行号的语句。 l         当程序执行结束语句后,结束整个程序的执行。 l         假设该系统能处理任意大小的整数,而不会发生溢出。    请编程,对于给定的TB语言程序P,求该程序所执行的语句数(执行条件语句不论是否成功转移,仅记为执行一条语句)。 Input l         输入为一个TB语言程序P,语句数不超过100行。 l         P中每条语句的长度不超过20个字符。 l         P中转移语句里GO后面的行号一定有对应的语句。 l         P中可能有多个不同行号的结束语句。 l         P中行号最大的语句一定是结束语句。 l         P中的行号都不大于3000。 输入文件不一定是按行号递增顺序给出P的。 当一行只有一个数-1时,表示一组数据输入结束 Output 输出文件有且仅有一行: 如果程序能够正常结束,输出该程序所执行的语句数; 如果程序不能正常结束,输出-1 Sample Input 10 A+1 20 IF A=5 GO 60 60 END 30 A+2 40 A? 50 GO 20 -1 Sample Output 11 Source NOI2000 #include<iostream.h> #include<stdio.h> enum opn{add,compare,end,print,go}; struct stc {     int line;     opn tag;     int op[3];     stc *next; }; class clspgm { public:     clspgm();     ~clspgm();     void display();     void run(); protected:     stc *head,*pc;     int v[26]; }; int getline(char *str) {     char c;     while(1)     {         c=getc(stdin);         if(c==EOF)return 0;         if(c=='\n')break;         *str++=c;     }     *str='\0';     return 1; } clspgm::clspgm() {     char str[20];     stc *p,*sp,*prep;     head=pc=NULL;     int t,i;     for(i=0;i<26;++i)v[i]=0;     while(1)     {         getline(str);         if(str[0]=='-')break;         p=new stc;         for(t=0,i=0;str[i]!=' ';++i)t=t*10+str[i]-'0';         p->line=t;//line number         ++i;         if(str[i]=='I')         {             p->tag=compare;             i+=3;             p->op[0]=str[i]-'A';             for(t=0,i+=2;str[i]!=' ';++i)t=t*10+str[i]-'0';             p->op[1]=t;             for(t=0,i+=4;str[i]!='\0';++i)t=t*10+str[i]-'0';             p->op[2]=t;         }         else if(str[i]=='E')         {             p->tag=end;         }         else if(str[i]=='G')         {             p->tag=go;             for(t=0,i+=3;str[i]!='\0';++i)t=t*10+str[i]-'0';             p->op[0]=t;         }         else if(str[i+1]=='+')         {             p->tag=add;             p->op[0]=str[i]-'A';             for(t=0,i+=2;str[i]!='\0';++i)t=t*10+str[i]-'0';             p->op[1]=t;         }         else         {             p->tag=print;             p->op[0]=str[i]-'A';         }         if(head==NULL)         {             p->next=NULL;             head=p;         }         else         {             for(prep=NULL,sp=head;sp&&sp->line<p->line;prep=sp,sp=sp->next);             if(prep==NULL)             {                 p->next=head;                 head=p;             }             else             {                 p->next=sp;                 prep->next=p;             }         }     } } clspgm::~clspgm() {     stc *p,*prep;     for(prep=head,p=head->next;!p;prep=p,p=p->next)delete prep;     delete prep; } void clspgm::display() {     stc *p=head;     while(p)     {         cout<<p->line<<":";         switch(p->tag)         {         case add:cout<<"Add "<<(char)('A'+p->op[0])<<" "<<p->op[1]<<endl;break;         case compare:cout<<"If "<<(char)('A'+p->op[0])<<"="<<p->op[1]<<" Go "<<p->op[2]<<endl;break;         case end:cout<<"End."<<endl;break;         case print:cout<<"Print "<<(char)('A'+p->op[0])<<endl;break;         case go:cout<<"Go "<<p->op[0]<<endl;break;         }         p=p->next;     } } void clspgm::run() {     stc *p;     int count=1;     pc=head;     while(pc->tag!=end)     {         switch(pc->tag)         {         case add:v[pc->op[0]]+=pc->op[1];pc=pc->next;break;         case go:for(p=head;p->line!=pc->op[0];p=p->next);pc=p;break;         case compare:             if(v[pc->op[0]]==pc->op[1])             {                 for(p=head;p->line!=pc->op[2];p=p->next);pc=p;             }             else pc=pc->next;             break;         default:pc=pc->next;         }         if(++count>30000)         {             cout<<(-1)<<endl;             return;         }     }     cout<<count<<endl; } int main() {     clspgm program;     program.display();     program.run();     return 0; }

阅读(38370) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册