我想创建一种形式的解析器:
#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
bool isValid(istringstream& is)
{
char ch;
is.get(ch); //I know get(ch) is a good start but this is as for as I got :)
.......
....
}
int main()
{
string s;
while(getline(cin,s))
{
istringstream is(s);
cout<<(isValid(is)? "Expression OK" : "Not OK")<<endl;
}
}
布尔函数,如果 char 的序列的格式为&#34; 5&#34;则返回TRUE。或&#34;(5 + 3)&#34;或&#34;((5 + 3)+6)&#34;或&#34;(((4 + 2)+1)+6)&#34; ......等等,对任何其他案件都是假的
基本上,如果表达式是单个数字或形式为&#34;打开括号 - 单个数字加号 - 单个数字 - 关闭括号&#34;
,则表达式将被视为有效。有效表达式= 单个数字
和
有效表达式=(有效表达式 + 有效表达式)
鉴于上述形式的大小没有限制(开括号和右括号的数量等等),我希望使用递归来做到这一点
成为我的新手..感谢您提供任何有用的信息!
答案 0 :(得分:0)
要做一个递归解决方案,你首先想要将字符串读入缓冲区,然后执行以下操作:
int expression(char* str) {
if (*str == '(') {
int e1 = expression(str + 1);
if (e1 == -1 || *(str + 1 + e) != '+') {
return -1;
}
int e2 = expression(str + 1 + e + 1);
if (e2 == -1 || *(str + 1 + e + 1 + e2) != ')') {
return -1;
}
return 1 + e1 + 1 + e2 + 1;
}
if (*str >= '0' || *str <= '9') {
return 1;
}
return -1;
}
bool isvalid(char* str) {
int e1 = expression(str);
if (e1 < 0) {
return false;
}
if (e1 == strlen(str)) {
return true;
}
if (*(str + e1) != '+') {
return false;
}
int e2 = expression(str + e1 + 1);
if (e2 < 0) {
return false;
}
return (e1 + 1 + e2 == strlen(str));
}
基本上,表达式函数在其参数处返回有效表达式的长度。如果它的参数以括号开头,则在此之后获取表达式的长度,在此之后验证加号,然后在下一个表达式之后验证右括号。如果参数以数字开头,则返回1.如果某些内容搞砸了,则返回-1。然后使用该函数,我们可以通过一些总和和字符串的长度来判断字符串是否有效。
我根本没有测试过这个函数,但是我可以想到的唯一可能失败的情况就是括号过多:((5))。
递归的替代方法可能是某种词法解析,例如:
enum {
ExpectingLeftExpression,
ExpectingRightExpression,
ExpectingPlus,
ExpectingEnd,
} ParseState;
// returns true if str is valid
bool check(char* str) {
ParseState state = ExpectingLeftExpression;
do {
switch (state) {
case ExpectingLeftExpression:
if (*str == '(') {
} else if (*str >= '0' && *str <= '9') {
state = ExpectingPlus;
} else {
printf("Error: Expected left hand expression.");
return false;
}
break;
case ExpectingPlus:
if (*str == '+') {
state = ExpectingRightExpression;
} else {
printf("Error: Expected plus.");
return false;
}
break;
case ExpectingRightExpression:
if (*str == '(') {
state = ExpectingLeftExpression;
} else if (*str >= '0' && *str <= '9') {
state = ExpectingEnd;
} else {
printf("Error: Expected right hand expression.");
return false;
}
break;
}
} while (*(++str));
return true;
}
该功能根本不完整,但您应该能够看到它的发展方向。我认为在这种情况下递归效果更好。