因为前段时间太忙,所以没有再进行下去。现在补上。窗体:
object Form2: TForm2
  Left = 171
  Top = 75
  Width = 696
  Height = 480
  Caption = 'Form2'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsMDIChild
  OldCreateOrder = False
  Position = poDefault
  Visible = True
  PixelsPerInch = 96
  TextHeight = 13
  object RichEdit1: TRichEdit
    Left = 0
    Top = 0
    Width = 688
    Height = 347
    Align = alTop
    Font.Charset = GB2312_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    Lines.Strings = (
      'Function Add(I , J : Integer);'
      'begin'
      '  Result := I + J;//。。'
      'end;')
    ParentFont = False
    TabOrder = 0
  end
  object Panel1: TPanel
    Left = 0
    Top = 347
    Width = 688
    Height = 106
    Align = alClient
    TabOrder = 1
    object Label1: TLabel
      Left = 440
      Top = 8
      Width = 60
      Height = 13
      Caption = '参数列表:'
    end
    object Label2: TLabel
      Left = 112
      Top = 8
      Width = 60
      Height = 13
      Caption = '提示信息:'
    end
    object SpeedButton1: TSpeedButton
      Left = 4
      Top = 22
      Width = 107
      Height = 81
      Caption = '语法检查'
    end
    object SpeedButton2: TSpeedButton
      Left = 557
      Top = 56
      Width = 51
      Height = 22
      Caption = '->结果'
    end
    object ListBox1: TListBox
      Left = 434
      Top = 24
      Width = 121
      Height = 80
      ItemHeight = 13
      TabOrder = 0
    end
    object Memo1: TMemo
      Left = 112
      Top = 24
      Width = 321
      Height = 79
      TabOrder = 1
    end
    object Memo2: TMemo
      Left = 611
      Top = 24
      Width = 73
      Height = 79
      TabOrder = 2
    end
  end
end要求:
  可以分析用户所写的表达式的正确性(你们可以加自己的想法进行完善)。
  如果检查通过,那么需要得出其结果值。  如果感觉代码不好组织,那么就将你的具体分析过程拿出来。分析的时候,不要用如此之类的话:用正则表达式就能解决等......
    我要的是你所想的办法,而不是你仅仅知道可以用些什么没有进行验证的方式。

解决方案 »

  1.   

    unit CompUnt;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, Buttons, ExtCtrls;type
      TForm2 = class(TForm)
        RichEdit1: TRichEdit;
        Panel1: TPanel;
        ListBox1: TListBox;
        Label1: TLabel;
        Memo1: TMemo;
        Label2: TLabel;
        SpeedButton1: TSpeedButton;
        Memo2: TMemo;
        SpeedButton2: TSpeedButton;
        procedure SpeedButton1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form2: TForm2;implementation{$R *.dfm}procedure TForm2.SpeedButton1Click(Sender: TObject);
    begin
      //进行语法检查。
    end;end.----------------
    过河卒
      

  2.   

    To ljmanage(过客)
    欢迎一起交流。----------------
    过河卒
      

  3.   

    FormStyle = fsMDIChild
    改成FormStyle=fsNormal才能运行
    。。
    我想。。
      

  4.   

    同意 hkbarton(宁静至远||淡泊明志)
    运算符的执行顺序的判断上是要用到栈。
    还是没有思路,晚上看了正则表达式,怎么那么难来
      

  5.   

    解释器和编译器有一定的联系,但是也有很大的区别。
    楼主这样的问题,一般用解释器就能完成了,如果能作成编译器那是最好不过了。:)
    计算表达式,困难的地方有:
    第一:界限符号和运算符号的交叉使用:如 Copy('ASD()' + Copy('AVCS',1,2),4,5)
    第二:计算符号的优先权
    第三:两个计算单元的类型, 如: ('ASD' + 123 )/12
      

  6.   

    偶的一个宏解释器能执行的代码:
    Count := 10
    Str := copy('asdqweasdasd',1,Count)+ copy('asdqweasdasd',1,3)
    print cos(Length(Str))print diskfree(0)Date := datetime()
    Print date + 1 + 10
    Print Month(date + 1 + 10) + Year(date + 1 + 10)if Date<>Date() then
       if messagebox('当前时间:'+chr(13)+chr(10)+datetimetostr(Date()) ,'提示',36)<>7 then
          Print Datetimetostr(Datetime())+'--------------'
       endif
    endifa := 10
    while a>0 do
      print copy('asdqweasdasd',1,a)+'123'
      a := a-1
    enddo 
    ....
      

  7.   

    也能执行下面的宏:
    CPLBID := -1
    CPLB := '产品类别'
    Worker := '曾国发'
    AQ := TAdoQuery.Create
    AQ.Connection := MainForm.SQLConnect
    AQ.LockType := 'ltReadOnly'
    AQ.SQL.Text := 'Select ID from CPLeiBie where LeiBieName=:MC and Deleted=0 and CompanySN='+inttostr(CompanySN)
    AQ.Parameters.ParamByName('MC').Value := CPLB
    AQ.Open
    CPLBID := AQ.FieldByName('ID').AsInteger
    if CPLBID<=0 then
      AQ.Free
      Showmessage('无效的产品类别名称:'+CPLB)
      Exit
    endif
    AQ.Close
    AQ.SQL.Text := 'Select ID from KBWorker where wName=:WK and Deleted=0 and CompanySN='+inttostr(CompanySN)
    AQ.Parameters.ParamByName('WK').Value := Worker
    AQ.Open
    WorkerID := AQ.FieldByName('ID').Asinteger
    if WorkerID<=0 then
      AQ.Free
      Showmessage('无效的员工姓名:'+Worker)
      Exit
    endif
    AQ.CLose
    Workerid := Inttostr(WorkerID)
    AQ.SQL.Text := 'Select Count(*) as nCount,Sum(Syk.FeiYong) As FeiYong1 FROM Syk,CPPK,SykList,CPLeiBie where '
    AQ.SQL.Add('(Syk.MrsID1='+WorkerID+' or Syk.MrsID2='+WorkerID+' or Syk.MrsID3='+WorkerID+' or Syk.MrsID4='+WorkerID+' or Syk.MrsID5='+WorkerID+')')
    AQ.SQL.Add(' And CPLeiBie.ID='+Inttostr(CPLBID)+' And CPLeiBie.ID = CPPK.CPLeiBie AND  SykList.SykID = Syk.ID AND SykList.ID=CPPK.ID and SykList.LX=2 ')
    AQ.SQL.Add(' And Syk.SykDate>='+FloatToStr(开始时间))
    AQ.SQL.Add(' And Syk.SykDate<='+FloatToStr(结束时间+1))AQ.Open
    Result := AQ.FieldByName('FeiYong1').AsString
    if Result ='' then
      Result := '0'
    endif
    AQ.Free
    exit
      

  8.   

    to kiboisme(还是铁棒.....针)
    人家小小要大家谈谈思路,你列出了那么多无关的代码干嘛
      

  9.   

    hehe铁棒兄,说说你的思路来洗耳恭听
      

  10.   

    To :microjuz(天才弟弟) 
    呵呵,,,你为什么不让kiboisme继续说下去呢?那么你来补充
    在做字符串分析的时候,用栈应该是一个非常好的想法,而并非是装载字符串到某一个变量中进行判断,原理并不难,主要的是如何可以写成代码。每次的监测过程其实就是一个出栈判断的过程。此为问题一,另一个问题,如果将这些判断过的字符串以正规的表达式来体现出来,并且可以参加一定的运算就是效率上的问题,还希望各位更多的讨论。----------------
    过河卒
      

  11.   

    To : ihihonline我的作法恰恰是你觉得不成其为好办法那样做的。:(
    把单独的行加载成一个字符串来判断处理。
    不过我还是厚着脸皮说出来,大家一起交流。如果要编译成二进制代码,加载到内存就可以直接运行,太难了,我无法实现。所以我作成解释执行的。
    我的计算表达式的作法是:首先进入一个函数,进行表达式的计算,如计算:A+B+C*D+(E+F)/G+SIN(H)-100的值,就把这个东西用字符串的形式传到那个函数里去,我们姑且叫这个函数:ComputeExpression
    那么这个函数里面,首先折分表达式,
    如果折分结果是1,并且是一个变量或者常量,那么就返回这个变量或者常量的值。
    //如果需要包含函数计算,这个地方就需要计算函数值,对象访问也是一样
    如果折分的结果>1,那么就需要计算这些单独的值,
    单独计算的时候就再进入ComputeExpression进行计算,并保存值,供计算。
    (折分是只折分同级计算表达式)
    如上面的表达式第一次折分后的结果是:
    A,+,B,+,C*D,+,(E+F)/G,+,SIN(H),-,100
    然后逐一再用ComputeExpression计算1,3,5,7,9,..的值,并把结果保存到相应的位置,
    然后判断2处的符号,进行1,3的计算,把结果放到1处,删除2,3,
    然后重复直到只剩下一个!!
    这样整个值就计算完了.
      

  12.   

    有些例外还是得例外处理,如 只有一个运算符号直接和表达式一起,就之有折分后就只有2个,所以....,
    如  Not (AQ.Eof)