数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 2810|回复: 0

简单词法分析程序(编译课作业一)

[复制链接]
发表于 2004-5-7 18:42:51 | 显示全部楼层 |阅读模式

<FONT size=+0><!-- 固定文字颜色 -->题:
分析一句子,分解出该句中的各类符号
1 标识符  2  整常数  3  IF  4 THEN   5  ELSE
6 +           7 -    8 *     9 /  10  :=  11  &lt;  12  &gt;  13  =
14 &lt;&gt;  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 &lt;= 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&lt;= 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&lt;&gt;=B();';
  cat := Pos(s,signs) + 5;
  if cat = 10 then begin
    s := ':=';
  end else if cat = 14 then begin
    s := '&lt;&gt;';
  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 &lt;= len do begin
    if s in ['+','-','*','/','A','&lt;','&gt;','=','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,'&lt;&gt;','B',[rfreplaceall]);//将双字符的&lt;&gt;以单个B替代
  expr := trim(expr);

  total := 0;

  i := 1;j := 1;len := Length(expr);
  while i &lt;= 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>
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-11-27 10:25 , Processed in 0.051311 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表