本人思考良久,想做一个如上所示的公式计算,一直没有好的简明的算法去做,大家一起来想想看,给一个好的方法.得到好的办法再赠高分.
令
F = x + y + z计算x=10,y=20,z=30时,F=?
当 x=40,y=23,z=56时,F=?注
F是可以自已定义的(如F=x*y/z),
参数个数可以变动,
能进行各种数学运算,包括自已定义的函数(如;F=a+sqr(b)+max(x,y,z);a=1,b=9,x=12,y=78,z=67)请大家代为想一想本人先谢,再赠高分
令
F = x + y + z计算x=10,y=20,z=30时,F=?
当 x=40,y=23,z=56时,F=?注
F是可以自已定义的(如F=x*y/z),
参数个数可以变动,
能进行各种数学运算,包括自已定义的函数(如;F=a+sqr(b)+max(x,y,z);a=1,b=9,x=12,y=78,z=67)请大家代为想一想本人先谢,再赠高分
var
ss: string;
begin
ss := '2 + 4 + 6*44*(44-2)';
query1.close;
query1.sql.text := 'select ' + ss + ' as Result';
try
query1.Open;
except
showmessage('你的公式非法!');
exit;
end;
Showmessage(query1.FieldByName('Result').Asstring);
query1.close;
end;//以上方法不但计算得准确,而且还可以校对公式的合法性 :)
办法值得考虑一下
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls;const
zProgram = 3;
zprocedure = 5;
zVar = 4;
zBegin = 6;
zEnd = 7;
zIf = 8;
zThen = 9;
zElse = 10;
zWhile = 11;
zDo = 12;
zInteger = 13;
zReal =14;
zPlus = 15;
zMinus = 16;
zMultiply = 17;
zDiv = 18;
zNot = 19;
zAnd = 20;
zOr = 21;
zLT = 22;
zLE = 23;
zGT = 24;
zGE = 25;
zEQ = 26;
zNE = 27;
zComma = 28; //逗号
zSemi = 29; //分号
zPoint = 30; //点号
zColon = 31; //冒号
zAssign = 32; //赋值
zLPare = 33; //左括号
zRPare = 34; //右括号
zFunction = 35;type
TForm1 = class(TForm)
Button1: TButton;
ComboBox1: TComboBox;
Panel1: TPanel;
Memo2: TMemo;
ListView1: TListView;
Splitter1: TSplitter;
Button2: TButton;
Memo3: TMemo;
Button3: TButton;
Memo1: TRichEdit;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure WordAnalyse(Word: String; Line: Integer);
procedure AddIdentify(Word: String; Line: Integer);
procedure AddNumber(Word: String; Line: Integer);
procedure AddError(Line: Integer);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Changecolor(Word: String);
procedure ChangeNoteColor;
procedure ShowPos;
procedure Memo1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure Memo1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
s: string; //读取Memo中的字符串
p: PChar; //字符扫描的指针
iError: Integer = 0; //错误计数
iTag: Integer = 0; //标志符计数
Tag: Integer ; //计指针位置
line, col: integer;
NoteStart, NoteEnd: Integer;
DelStartLine, DelEndLine: Integer;
CanAdd: Boolean = true; //判断是否可以增加错误计数或者添加为标识符implementation
uses unit2;
{$R *.dfm}//逐个字符进行扫描
function GetNextChar: Char;
begin
if p^ = #0 then
begin
Result := #0;
end else
begin
Result := p^;
Inc(p);
end;
end;
//判断所得字符或字符串是非法的
procedure TForm1.AddError;
begin
if CanAdd then
begin
Inc(iError);
Memo2.Lines.Add('** Error ('+IntToStr(iError)+') **');
end;
end;//判断所得字符或字符串是标志符
procedure TForm1.AddIdentify(Word: String; Line: Integer);
var
NewItem: TListItem;
i: integer;
IsExist: Boolean ; //标志符重复出现
begin
IsExist:= false;
for i:= 0 to ListView1.Items.Count-1 do
begin
if CompareText(ListView1.Items[i].SubItems.Strings[0], Word)= 0 then
begin
IsExist:= true;
break;
end;
end; if not IsExist then
begin
Inc(iTag);
NewItem:= ListView1.Items.Add;
NewItem.Caption:= IntToStr(iTag);
NewItem.SubItems.Add(Word);
Memo2.Lines.Add(Word+' ( 1, '+IntToStr(iTag)+' ) --> '+IntToStr(Line));
end
else
begin
Memo2.Lines.Add(Word+' ( 1, '+IntToStr(i+1)+' ) --> '+IntToStr(Line));
end;
end;//判断所得字符或字符串是数字
procedure TForm1.AddNumber(Word: String; Line: Integer);
var
Temp: Integer;
begin
try
Temp:= StrToInt(Word);
Memo2.Lines.Add(Word+' ( 1, '+Word+' ) --> '+IntToStr(Line));
except
AddError(Line);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
NextChar: Char;
NewString: string[7];
CurLine: Integer;
begin
Memo2.Clear;
Memo3.Clear;
ListView1.Clear;
if Memo1.Text<> '' then
begin
s := Memo1.Text;
Button2.Enabled:= true;
end
else Exit;
p := @s[1];
NewString:= '';
iError:= 0;
iTag:= 0;
CurLine:= 1;
Tag:= 0; NextChar := GetNextChar;
Tag:= Tag+ 1;
while NextChar <> #0 do
begin
case NextChar of
' ', #10,#13:
begin
if Trim(NewString)<>'' then
WordAnalyse(NewString, CurLine);
NewString:= ''; if NextChar= #13 then Inc(CurLine);
end; '+', '-', '*', '/', '(', ')', ';', ',', '=':
begin
if NewString='' then NewString:= NextChar
else
begin
if ((NewString[1]='>') and (NextChar='=')) then NewString:= NewString+ NextChar
else if (NewString[1]='<') and (NextChar='=') then NewString:= NewString+ NextChar
else if (NewString[1]=':') and (NextChar='=') then NewString:= NewString+ NextChar
else if (NewString[1]='/') and (NextChar='*') then
begin
NewString:= NewString+ NextChar;
NoteStart:= Tag-2;
end
else if (NewString[1]='*') and (NextChar='/') then
begin
NewString:= NewString+ NextChar;
NoteEnd:= Tag;
end
else
begin
WordAnalyse(NewString, CurLine);
NewString:= NextChar;
end;
end;
end; '<', '>', ':':
begin
if (NewString[1]='<') and (NextChar='>') then
begin
NewString:= NewString+ NextChar;
end
else
begin
WordAnalyse(NewString, CurLine);
NewString:= NextChar;
end;
end; 'a'..'z', 'A'..'Z', '0'..'9':
begin
if NewString='' then NewString:= NextChar
else
begin
if NewString[1] in ['a'..'z', 'A'..'Z', '0'..'9'] then
NewString := NewString + NextChar
else
begin
WordAnalyse(NewString, CurLine);
NewString:= NextChar;
end
end;
end; else
begin
if NewString='' then NewString:= NextChar
else
begin
WordAnalyse(NewString, CurLine);
NewString:= NextChar;
end;
end;
end; NextChar := GetNextChar;
Tag:= Tag+ 1;
end;
if NewString<>'' then WordAnalyse(NewString, CurLine);
if iError<>0 then Memo3.Lines.Add(' 词法有 '+IntToStr(iError)+' 处错误!');
Memo3.Lines.Add(' ~~~ 词法分析完毕!')
end;
数据结构里面的东西不能很好的解决sqr,sin等函数
procedure TForm1.WordAnalyse(Word: string; Line: Integer);
begin
if ComboBox1.Items.IndexOf(Word)<> -1 then
begin
if CompareText(Word, 'program')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zProgram)+', 0 ) --> '+IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'procedure')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zProcedure)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'var')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zVar)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'begin')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zBegin)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'end')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zEnd)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'if')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zIf)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'then')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zThen)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'else')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zElse)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'while')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zWhile)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'do')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zDo)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'integer')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zInteger)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'real')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zReal)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'not')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zNot)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'and')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zAnd)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'or')= 0 then
begin
Memo2.Lines.Add(Word+' ( '+IntToStr(zOr)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if CompareText(Word, 'function')= 0 then
begin
Memo2.Lines.Add(Word+' ('+IntToStr(zFunction)+', 0 ) --> '+ IntToStr(Line));
ChangeColor(Word);
end
else if Word= '+' then Memo2.Lines.Add(Word+' ('+IntToStr(zPlus)+', 0 ) --> '+ IntToStr(Line))
else if Word= '-' then Memo2.Lines.Add(Word+' ('+IntToStr(zMinus)+', 0 ) --> '+ IntToStr(Line))
else if Word= '*' then Memo2.Lines.Add(Word+' ('+IntToStr(zMultiply)+', 0 ) --> '+ IntToStr(Line))
else if Word= '/' then Memo2.Lines.Add(Word+' ('+IntToStr(zDiv)+', 0 ) --> '+ IntToStr(Line))
else if Word= '(' then Memo2.Lines.Add(Word+' ('+IntToStr(zLPare)+', 0 ) --> '+ IntToStr(Line))
else if Word= ')' then Memo2.Lines.Add(Word+' ('+IntToStr(zRPare)+', 0 ) --> '+ IntToStr(Line))
else if Word= '<' then Memo2.Lines.Add(Word+' ('+IntToStr(zLT)+', 0 ) --> '+ IntToStr(Line))
else if Word= '>' then Memo2.Lines.Add(Word+' ('+IntToStr(zGT)+', 0 ) --> '+ IntToStr(Line))
else if Word= ':=' then Memo2.Lines.Add(Word+' ('+IntToStr(zAssign)+', 0 ) --> '+ IntToStr(Line))
else if Word= '<=' then Memo2.Lines.Add(Word+' ('+IntToStr(zLE)+', 0 ) --> '+ IntToStr(Line))
else if Word= '>=' then Memo2.Lines.Add(Word+' ('+IntToStr(zGE)+', 0 ) --> '+ IntToStr(Line))
else if Word= '<>' then Memo2.Lines.Add(Word+' ('+IntToStr(zNE)+', 0 ) --> '+ IntToStr(Line))
else if Word= ';' then Memo2.Lines.Add(Word+' ('+IntToStr(zSemi)+', 0 ) --> '+ IntToStr(Line))
else if Word= ',' then Memo2.Lines.Add(Word+' ('+IntToStr(zComma)+', 0 ) --> '+ IntToStr(Line))
else if Word= '.' then Memo2.Lines.Add(Word+' ('+IntToStr(zPoint)+', 0 ) --> '+ IntToStr(Line))
else if Word= '=' then Memo2.Lines.Add(Word+' ('+IntToStr(zEQ)+', 0 ) --> '+ IntToStr(Line))
else if Word= '/*' then
begin
CanAdd:= false;
Memo2.Lines.Add(Word);
DelStartLine:= Memo2.Lines.IndexOf('/*');
end
else if Word= '*/' then
begin
CanAdd:= true;
Memo2.Lines.Add(Word);
DelEndLine:= Memo2.Lines.IndexOf('*/');
//Application.ProcessMessages;
While (DelEndLine-DelStartLine)>=0 do
begin
Memo2.Lines.Delete(DelEndLine);
Dec(DelEndLine);
end;
ChangeNoteColor;
end
else if Word= ':' then Memo2.Lines.Add(Word+' ('+IntToStr(zColon)+', 0 ) --> '+ IntToStr(Line));
end
else
begin
if Word[1] in ['a'..'z', 'A'..'Z'] then //标志符
begin
if CanAdd then
AddIdentify(Word, Line);
end
else if Word[1] in ['0'..'9'] then
begin
if CanAdd then
AddNumber(Word, Line);
end
else AddError(Line);
end;
end;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~词法分析完毕~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo3.Clear;
iSyntaxError:= 0;
SyntaxAnalyse; //语法分析(unit2)
Button2.Enabled:= false;
end;
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, unit1;procedure SyntaxAnalyse;
procedure ReadWord;
function Syntax_SentenceList: Boolean; //语句串
function Syntax_Sentence: Boolean; //语句
function Syntax_AssignSentence: Boolean; //赋值语句
function Syntax_ComplexSentence: Boolean; //复合语句
function Syntax_ConditionSentence: Boolean; //条件语句
function Syntax_LoopSentence: Boolean; //循环语句
function Expression: Boolean; //表达式
function Item: Boolean; //项
function factor: Boolean; //因子
function BoolExpr: Boolean; //布尔表达式
function RelativeExpr: Boolean; //关系表达式
function Relation: Boolean; //关系
procedure SyntaxError(Kind: String);
var
IndexOfWord:Integer; //当前所在单词索引
CurWordTag: Integer; //当前单词的助记符(值)
iSyntaxError: Integer = 0; //语法错误计数
CurWordLine: String; //当前行号implementation//根据词法分析,读取得到的字符组合
procedure ReadWord;
var
LineTagStart, LineTagEnd, TagStart, TagEnd: Integer;
begin
//读取下一个字符串的class值
if IndexOfWord= form1.Memo2.Lines.Count then Exit; TagStart:= Pos('(',form1.Memo2.Lines.Strings[IndexOfWord]);
TagEnd:= Pos(',',copy(form1.Memo2.Lines.Strings[IndexOfWord],2,Length(form1.Memo2.Lines.Strings[IndexOfWord])))+1;
if (TagEnd> TagStart) then //and (TagEnd<> 1)
begin
if TagStart<> 1 then
CurWordTag:= StrToInt(Copy(form1.Memo2.Lines.Strings[IndexOfWord],TagStart+1,TagEnd-TagStart-1))
else
begin
TagStart:= TagStart+ 3;
CurWordTag:= StrToInt(Copy(form1.Memo2.Lines.Strings[IndexOfWord],TagStart+1,TagEnd-TagStart-1))
end;
end;
LineTagStart:= Pos('-->',form1.Memo2.Lines.Strings[IndexOfWord]);
LineTagEnd:= Length(form1.Memo2.Lines.Strings[IndexOfWord])+1;
CurWordLine:= copy(form1.Memo2.Lines.Strings[IndexOfWord], LineTagStart+3, LineTagEnd-LineTagStart-3); Inc(IndexOfWord);
end;
用脚本就很容易实现.
因为变量是不定的,还有变量的赋值,如果要按你的方法的话,你怎么知道F表达式结束,又怎么知道哪些是赋值语句。
比如,你怎么适用于各种情况
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
F=(X+Y)*Zx=1,y=2,z=3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
F=(a+b)*c-da=1,b=2,c=3,d=4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
procedure SyntaxAnalyse;
begin
//语法分析
IndexOfWord:= 0;
ReadWord;
if Syntax_SentenceList then Form1.Memo3.Lines.Add(' * * * 语法分析完毕!')
end;function Syntax_SentenceList: Boolean;
begin
//分析语句串 <语句串> --> <语句> (;<语句>)
if Syntax_Sentence then
begin
if CurWordTag= zSemi then
begin
ReadWord;
Result:= Syntax_SentenceList;
end
else
begin
Result:= true;
SyntaxError('无分号');
end;
end
else Result:= true;
end;
function Syntax_Sentence: Boolean;
begin
//语句 <语句> --> <复合语句> | <赋值语句> | <条件语句> | <循环语句>
case CurWordTag of
zBegin : Result:= Syntax_ComplexSentence;
1 : Result:= Syntax_AssignSentence; //是标志符
zIf : Result:= Syntax_ConditionSentence;
zWhile : Result:= Syntax_LoopSentence;
else Result:= false; //只返回假值,不产生错误
end;
end;function Syntax_AssignSentence: Boolean;
begin
//赋值 <赋值语句> --> 标识符 := <表达式>
if CurWordTag= 1 then
begin
ReadWord;
if CurWordTag= zAssign then
begin
ReadWord;
Result:= Expression;
end
else
begin
Result:= false;
SyntaxError('无赋值符号');
end;
end
else
begin
Result:= false;
SyntaxError('非标识符');
end;
end;function Syntax_ComplexSentence: Boolean;
begin
//复合 <复合语句> --> begin <语句串> end
if CurWordTag= zBegin then
begin
ReadWord;
if Syntax_SentenceList then
begin
if CurWordTag= zEnd then
begin
ReadWord;
Result:= true;
end
else
begin
Result:= false;
SyntaxError('无end');
end;
end
else
begin
if CurWordTag= zEnd then
begin
ReadWord;
Result:= true;
end
else
begin
Result:= false;
SyntaxError('无end');
end;
end;
end
else
begin
Result:= false;
SyntaxError('非复合语句,需begin');
end;
end;function Syntax_ConditionSentence: Boolean;
begin
//条件 <条件语句> --> if <布尔表达式> then <语句> [else <语句>]
if CurWordTag= zIf then
begin
ReadWord;
if BoolExpr then
begin
if CurWordTag= zThen then
begin
ReadWord;
if Syntax_Sentence then
begin
if CurWordTag= zElse then
begin
ReadWord;
Result:= Syntax_SentenceList;
end
else
begin
Result:= true;
end;
end
else
begin
Result:= false;
SyntaxError('需语句,但未找到语句');
end;
end
else
begin
Result:= false;
SyntaxError('无then');
end;
end
else
begin
Result:= false;
SyntaxError('非布尔表达式');
end;
end
else
begin
Result:= false;
SyntaxError('非条件语句,需if');
end;
end;function Syntax_LoopSentence: Boolean;
begin
//循环 <循环语句> --> while <布尔表达式> do <语句>
if CurWordTag= zWhile then
begin
ReadWord;
if BoolExpr then
begin
if CurWordTag= zDo then
begin
ReadWord;
Result:= Syntax_Sentence;
end
else
begin
Result:= false;
SyntaxError('无do');
end;
end
else
begin
Result:= false;
SyntaxError('布尔表达式非法');
end;
end
else
begin
Result:= false;
SyntaxError('非循环语句,需while');
end;
end;function Expression: Boolean;
begin
//表达式 <表达式> --> <项> (+ <项>)
if Item then
begin
if CurWordTag= zPlus then
begin
ReadWord;
Result:= Expression;
end
else Result:= true;
end
else
begin
Result:= false;
SyntaxError('项非法');
end;
end;function Item: Boolean;
begin
//项 <项> --> <因子> (* <因子>)
if factor then
begin
if CurWordTag= zMultiply then
begin
ReadWord;
Result:= Item;
end
else Result:= true;
end
else
begin
Result:= false;
SyntaxError('因子非法');
end;
end;function factor: Boolean;
begin
//因子 <因子> --> (<表达式>) | 标识符 | 数字
case CurWordTag of
1,2:
begin
ReadWord;
Result:= true;
end;
zLPare:
begin
ReadWord;
if Expression then
begin
if CurWordTag= zRPare then
begin
ReadWord;
Result:= true;
end
else
begin
Result:= false;
SyntaxError('无右括号');
end;
end
else
begin
Result:= false;
SyntaxError('表达式非法');
end;
end;
else
begin
Result:= false;
//SyntaxError('因子非法');
end;
end;
end;function BoolExpr: Boolean;
begin
//布尔表达式 <布尔表达式>--> not<布尔表达式> | <关系表达式> | and<布尔表达式> | or<布尔表达式> |$
if CurWordTag= zNot then
begin
ReadWord;
Result:= BoolExpr;
end
else if RelativeExpr then
begin
if (CurWordTag= zAnd) or (CurWordTag= zOr) then
begin
ReadWord;
Result:= BoolExpr;
end
else Result:= true;
end
else
begin
Result:= false;
SyntaxError('关系表达式非法');
end;
end;function RelativeExpr: Boolean;
begin
//关系表达式 <关系表达式> --> <表达式> <关系> <表达式>
if Expression then
begin
if Relation then Result:= Expression
else
begin
Result:= false;
SyntaxError('关系非法');
end;
end
else
begin
Result:= false;
SyntaxError('表达式非法');
end;
end;function Relation: Boolean;
begin
//关系 <关系> --> < | > | <= | >= | = | <>
case CurWordTag of
zLT,zGT,zLE,zGE,zEQ,zNE:
begin
ReadWord;
Result:= true;
end
else
begin
Result:= false;
//SyntaxError('关系非法');
end;
end;
end;procedure SyntaxError(Kind: String);
begin
//出错
Inc(iSyntaxError);
form1.Memo3.Lines.Add('*** Error ('+IntToStr(iSyntaxError)+') <第'+CurWordLine+' 行> : '+Kind);
end;
//**************************************语法分析完毕****************************end.
再次申明,如果解决好你问题,绝不仅仅是数据结构的问题,更重要的是编译原理的问题。