------
type
TRuleList=class(TStringList)
private
//确定需要添加项的列数,例:(a+b)*c 中添加 c 时为2 。
addcount:integer;
public
Constructor Create();
procedure addColumn(); //加列
procedure addItem(const item:string); //为account列加新行
procedure addList(const childlist:TRuleList); //加新表
function getRule():string;
Destructor Destroy();override;
end;
-----------
//主函数
function getResult(const source:string):string;
var
ipos:integer; //原始字符串遍历下标
bracketcount:integer; //括号记数
wordflag:0..2; //0-未开始读词;1-已开始读词;2-括号结束
aword:string; //词
//err:string; //出错信息
rulelist:TRuleList; //规则
function getRule(const source:string):TRuleList; //解析函数
var
rlist,childlist:TRuleList;
begin
result:=nil;
rlist:=TRuleList.Create();
try
while ipos<=length(source) do
begin
case source[ipos] of
AnsiChar('*'):
begin
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 * 号附近');
end;
if wordflag=1 then
begin
rlist.addItem(aword);
end;
wordflag:=0;
aword:='';
ipos:=ipos+1;
end; //'*'
AnsiChar('+'):
begin
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 + 号附近');
end;
if wordflag=1 then
rlist.addItem(aword);
rlist.addColumn();
wordflag:=0;
aword:='';
ipos:=ipos+1;
end; // '+'
AnsiChar('('):
begin
bracketcount:=bracketcount+1;
ipos:=ipos+1;
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=0;
aword:='';
end;
childlist:=getRule(source);//递归
if childlist<>nil then
begin
rlist.addlist(childlist);
childlist.Free();
end
else
begin
break;
end
end; // '('
AnsiChar(')'):
begin
bracketcount:=bracketcount-1;
ipos:=ipos+1;
if(bracketcount<0) then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,括号不匹配');
end;
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=2;
aword:='';
end;
if wordflag=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近');
end;
if rlist.Count=0 then
begin
raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,空括号');
end;
result:=rlist;
break;
end; // ')'
else
begin
aword:=aword+source[ipos];
wordflag:=1;
ipos:=ipos+1;
end; //else
end; //case
end; //while
//showMessage(inttostr(bracketcount)+' '+rlist.getRule()); //调试信息
if (bracketcount<>0) and (ipos>=length(source)) then
begin
raise Exception.Create('语法错误:结束时括号不匹配');
end;
if (bracketcount=0) and (ipos>length(source)) then //遍历完成,正常返回
begin
if wordflag=1 then
begin
rlist.addItem(aword);
wordflag:=0;
end;
result:=rlist;
end;
//else 未完成(出错,或是递归返回)
except
on Exception do
begin
if rlist<>nil then
begin
rlist.Free();
end;
raise; //重发
end;
end;//except
end; //function getRule
begin
ipos:=1;
rulelist:=nil;
wordflag:=0;
aword:='';
bracketcount:=0;
try
rulelist:=getRule(source); //获得规则
if rulelist<>nil then
begin
result:=rulelist.getRule();
rulelist.Free();
end
except
on e:Exception do
showMessage(e.Message);
end;
end; //function getResult
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text:=getResult(Edit1.Text);
end;