|
<FONT size=+0><!-- 固定文字颜色 -->题:
分析一句子,分解出该句中的各类符号
1 标识符 2 整常数 3 IF 4 THEN 5 ELSE
6 + 7 - 8 * 9 / 10 := 11 < 12 > 13 =
14 <> 15 ( 16 ) 17 ;
如输入:
if ab =3 then
var1 := 5;
输出为:
1 类3 值为 if
2 类1 值为 ab
3 类13 值为 =
4 类 2 值为 3
....
....
我的思路大至为:先将输入字符串中的\n\r转化为空格,再将整个字串以空格为界,分成若干子字串;在子字串中,再以各符号(如,*,-,+,/,;等等)为界,分成若干分, 此时,将分成的各分送去分析,判断这一分属于哪一类。
以下为DELPHI代码:
{author: Wu Zhijian}
unit input;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TFlatMemoUnit,
ExtCtrls, dxfShapedForm, dxfColorButton;
type
Tfrm_trans = class(TForm)
memExpr: TFlatMemo;
OpenDialog1: TOpenDialog;
dxfShapedForm1: TdxfShapedForm;
dxfColorButton1: TdxfColorButton;
btnLoad: TdxfColorButton;
btnDone: TdxfColorButton;
btnAboutMe: TdxfColorButton;
procedure btnDoneClick(Sender: TObject);
procedure btnLoadClick(Sender: TObject);
procedure btnAboutMeClick(Sender: TObject);
procedure dxfColorButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frm_trans: Tfrm_trans;
total:Integer;
implementation
uses aboutMe;
{$R *.dfm}
procedure ClassifyA(s:string);
var
i,len:Integer;
begin
i:=2; len:=Length(s);
if len = 0 then begin
exit
end else if s[1] in ['0'..'9'] then begin
while i <= len do begin
if not (s in ['0'..'9']) then begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 非法字串 '+s) ;
exit;
end;
inc(i);
end;
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 整数 '+s) ;
end else if s[1] in ['a'..'z'] then begin
while i<= len do begin
if CompareStr(s,'if') = 0 then begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 保留字 '+s) ;
exit;
end else if CompareStr(s,'then') =0 then begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 保留字 '+s) ;
exit;
end else if CompareStr(s,'else') = 0 then begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 保留字 '+s) ;
exit;
end else if not (s in ['0'..'9','a'..'z']) then begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 非法字串 '+s) ;
exit;
end;
Inc(i);
end;
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 标识符 '+s) ;
end else begin
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 非法字串 '+s) ;
end;
end;
procedure ClassifyB(s:string);
var
signs:string;
cat:Integer;
begin
signs := '+-*/A<>=B();';
cat := Pos(s,signs) + 5;
if cat = 10 then begin
s := ':=';
end else if cat = 14 then begin
s := '<>';
end;
Inc(total);
frm_trans.memExpr.Lines.Add(IntToStr(total)+' 类'+IntToStr(cat)+' '+s) ;
end;
procedure ManagePieceOfExpr(s:string);
var
i,j,len:Integer;
begin
i:=1;j:=1;len:=Length(s);
while i <= len do begin
if s in ['+','-','*','/','A','<','>','=','B','(',')',';'] then begin //以各分隔符为界再次划分字串
ClassifyA(Copy(s,j,i-j));
ClassifyB(s);
j := i+1;
end else begin
if i = len then begin
ClassifyA(Copy(s,j,i+1-j));
end;
end;
Inc(i);
end;
end;
procedure Tfrm_trans.btnDoneClick(Sender: TObject);//<FONT color=red>从这个函数看起啊!!!!!</FONT>
var
expr:string;
i,j,len:Integer;
begin
expr := LowerCase(memExpr.Text);//全小写
expr := stringreplace(expr,chr(13) + chr(10),' ',[rfreplaceall]);//将\n\r全以空格替代
expr := stringreplace(expr,':=','A',[rfreplaceall]);//将双字符的:=以单个A替代
expr := stringreplace(expr,'<>','B',[rfreplaceall]);//将双字符的<>以单个B替代
expr := trim(expr);
total := 0;
i := 1;j := 1;len := Length(expr);
while i <= len do begin
if expr in [' '] then begin //以空格为界划分字串
ManagePieceOfExpr(trim(Copy(expr,j,i-j)));
while expr[i+1] in [' '] do begin
inc(i);
end;
j := i+1;
end else begin
if i = len then begin
ManagePieceOfExpr(trim(Copy(expr,j,i+1-j)));
end;
end;
inc(i);
end;
end;
procedure Tfrm_trans.btnLoadClick(Sender: TObject);
begin
if OpenDialog1.Execute then begin
memExpr.Lines.LoadFromFile(OpenDialog1.FileName);
end;
end;
procedure Tfrm_trans.btnAboutMeClick(Sender: TObject);
begin
frmAboutBox.ShowModal;
end;
procedure Tfrm_trans.dxfColorButton1Click(Sender: TObject);
begin
Close;
end;
end.
</FONT> |
|