#include<iostream>
using namespace std;
int Atomic(char c)//判断是否为原子命题
{
if((c>='a'&&c<='z')||(c>='A'||c<='Z'))
return 1;
else
return 0;
}
int Connect(char c)//判断联结词
{
if(c=='!'||c=='&'||c=='|'||c=='%'||c=='>'||c=='$')
return 1;
else
return 0;
}
int iConnect(char c)//判断联结词
{
if(c=='&'||c=='|'||c=='%'||c=='>'||c=='$')
return 1;
else
return 0;
}
int judge(string str)//判断合法性
{
int len,i,j;
if(str.length()<1)return 0; //无字符为不合法
int left=0,right=0,count=0;
for(i=0;i<str.length();i++)
{
if(str[i]=='(')left=i;
else continue;
for(;i<str.length();++i)
{
if(str[i]=='(')
count++;
if(str[i]==')')
{
count--;
if(count==0)//count==0 代表左右括号数相等
{
right=i;
if(judge(str.substr(left + 1, right - left - 1)) == 0) //递归判断
return 0;
else //将'('变为a,删除')'和括号里的内容
{
str[left] = 'a';
str.erase(str.begin() + left + 1, str.begin() + right + 1);
i = left; //i变为left
break;
}
}
}
}
if(count!=0)return 0;
}
for(i=0;i<str.length();i++)
{ //分析和去掉非!
if(str[i]=='!')
{
if(i==str.length()-1)return 0;//最后一位为!,不合法
if(iConnect(str[i+1]))return 0;//!后面为联接词(除了!),不合法
else
{
str.erase(str.begin()+i);//删除!
i--;//少一个
}
}
}
for(i=0;i<str.length();i++)//最后奇数位应该是原子命题,偶数为应该为联接词
{
if(i%2==1&&!Connect(str[i]))return 0;
if(i%2==0&&!Atomic(str[i]))return 0;
}
return 1;
}
int main()
{
string str;
cout<<"!代表非,&代表合取,|代表析取,%代表排斥或,>代表蕴含,$代表等价:";
cout<<"输入公式:\n";
cin>>str;
if(judge(str)==0)
printf("不合法\n");
else
printf("合法\n");
return 0;
}