Лог.Выражение
Помогите решить задачу за 1 курс Люди, помогите, я на вас надеюсь
Вывести значение логического выражения, заданного в виде строки S. Выражение определяется следующим образом ("T" — True, "F" — False):
<выражение> ::= T | F | And(<операнды>) | Or(<операнды>) | Not(<выражение>)
<операнды> ::= <выражение> | <выражение>,<операнды>
Вот наметки, но они мне не нравятся. Помогите *HELP**HELP**HELP*
Код:
unit Lexical;
interface
USES SysUtils;
TYPE TLexemeType=(LTrue, LFalse, LAnd, LOr, LNot, FINISH);
Tres=RECORD
lexeme:TLExemeType;
value: LONGINT;
name:STRING;
position:WORD
END;
TResult=ARRAY OF TRes;
TLexicalAnalyzer=CLASS
PRIVATE
Ferr:STRING;
Flex:TResult;
FUNCTION GetError:STRING;
FUNCTION GetLex:TResult;
PUBLIC
CONSTRUCTOR Create;
DESTRUCTOR Free;
PROCEDURE Run(s:STRING);
PROPERTY Error:STRING READ GetError;
PROPERTY Lexem:TResult READ GetLex;
END;
implementation
DESTRUCTOR TLexicalAnalyzer.Free;
BEGIN
Finalize(Flex)
END;
FUNCTION TLexicalAnalyzer.GetLex:TResult;
BEGIN
Result:=Self.Flex
END;
CONSTRUCTOR TLexicalAnalyzer.Create;
BEGIN
INHERITED Create;
FErr:='';
SetLength(FLex,0);
END;
FUNCTION TLexicalAnalyzer.GetError:STRING;
BEGIN
Result:=Ferr
END;
PROCEDURE TLexicalAnalyzer.Run(s:STRING);
VAR i:WORD;
PROCEDURE addlex(l:TLexemeType; v:LONGINT; n:STRING);
BEGIN
SetLength(FLex,Length(FLex)+1);
WITH FLex[Length(FLex)-1] DO
BEGIN
Lexeme:=L;
Value:=v;
Name:=n;
Position:=i
END
END;
PROCEDURE ReadAnd;
VAR n:STRING;
BEGIN
n:=s[i];
INC(i);
If (i<=LENGTH(s)) AND (s[i] in ['n','N']) Then
BEGIN
n:=n+s[i];
INC(i);
If (i<=LENGTH(s)) AND (s[i] in ['d','D']) Then
BEGIN
n:=n+s[i];
AddLex(LAnd,0,n);
{INC(i); }
end
ELSE {IF Not(s[i] in ['n','N']) THEN} BEGIN Ferr:='Недопустимые символы после '''+s[i-1]+''''; Exit END;
END
ELSE {IF Not(s[i] in ['n','N']) THEN} BEGIN Ferr:='Недопустимые символы после '''+s[i-1]+''''; Exit END;
{DEC(i)}
END;
PROCEDURE ReadOr;
VAR n:STRING;
BEGIN
n:=s[i];
INC(i);
If (i<=LENGTH(s)) AND (s[i] in ['r','R']) Then
BEGIN
n:=n+s[i];
{INC(i); }
AddLex(LOr,0,n);
END
ELSE IF Not(s[i] in ['r','R']) THEN BEGIN Ferr:='Недопустимые символы после '''+s[i-1]+''''; Exit END;
{DEC(i);}
END;
PROCEDURE ReadNot;
VAR n:STRING;
BEGIN
n:=s[i];
INC(i);
If (i<=LENGTH(s)) AND (s[i] in ['o','O'])Then
BEGIN
n:=n+s[i];
INC(i);
If (i<=LENGTH(s)) AND (s[i] in ['t','T']) Then
BEGIN
n:=n+s[i];
{INC(i);}
AddLex(LNot,0,n);
end
Else BEGIN Ferr:='Недопустимые символы после '''+s[i-1]+''''; Exit END;
END
ELSE {IF Not(s[i] in ['o','O']) THEN } BEGIN Ferr:='Недопустимые символы после '''+s[i-1]+''''; Exit END;
{DEC(i);}
END;
BEGIN
i:=1;
SetLength(Flex,0);
Ferr:='';
WHILE i<=LENGTH(s) DO
BEGIN
CASE s[i] OF
'T','t': AddLex(LTrue,0,'T');
'F','f': AddLex(LFalse,0,'F');
'A','a': ReadAnd;
'O','o': ReadOr;
'N','n': ReadNot;
ELSE
BEGIN
Ferr:='Недопустимый символ';
Exit
END
END;
INC(i)
END;
AddLex(FINISH,0,'')
END;
end.
unit Syntax2;
interface
USES Lexical;
type TSyntaxAnalyzer=CLASS
PROTECTED
FLex:TResult;
Ferr:STRING;
Ferrpos:WORD;
count:LONGINT;
FUNCTION GetLex:TRes;
FUNCTION GetError:STRING;
FUNCTION GetErrorPos:WORD;
PUBLIC
CONSTRUCTOR Create(ll:TResult);
DESTRUCTOR Free;
PROPERTY error:STRING READ GetError;
PROPERTY errorpos:WORD READ GetErrorPos;
PROCEDURE Parse;VIRTUAL;
END;
implementation
CONSTRUCTOR TSyntaxAnalyzer.Create(ll:TResult);
BEGIN
INHERITED Create;
Flex:=ll;
count:=0;
Ferr:='';
Ferrpos:=0
END;
DESTRUCTOR TSyntaxAnalyzer.Free;
BEGIN
Finalize(Flex)
END;
FUNCTION TSyntaxAnalyzer.GetError:STRING;
BEGIN
Result:=self.Ferr
END;
FUNCTION TSyntaxAnalyzer.GetErrorPos:WORD;
BEGIN
Result:=self.FErrPos
END;
FUNCTION TSyntaxAnalyzer.GetLex:TRes;
BEGIN
IF count<=LENGTH(FLex)-1 THEN
BEGIN
Result:=Flex[count];
INC(count)
END
ELSE
WITH Result DO
BEGIN
Lexeme:=FINISH;
name:='';
value:=0;
position:=0
END
END;
PROCEDURE TSyntaxAnalyzer.Parse;
CONST unaryoper=LNot; // операция
binaryoper=[LAnd, LOr]; // операция
item=[LTrue,LFalse]; // слагаемое
TYPE TState=(TSTART, TITEM, TUNARYOPER, TBINARYOPER,TERROR, TFINISH);
VAR state:TState;
curlex:TRes;
BEGIN
state:=TSTART;
REPEAT
curlex:=GetLex;
CASE state OF
TSTART:
IF curlex.lexeme = unaryoper THEN
State:=TUNARYOPER
ELSE
IF curlex.lexeme IN item THEN
State:=TITEM
{ELSE
IF curlex.lexeme = FINISH THEN
State:=TFINISH }
Else
State:=TERROR;
TITEM:
IF curlex.Lexeme IN binaryoper THEN
state:=TBINARYOPER
ELSE
{IF curlex.Lexeme = unaryoper THEN
state:=TUNARYOPER
ELSE}
IF curlex.lexeme = FINISH THEN
State:=TFINISH
ELSE
state:=TERROR;
TUNARYOPER:
IF curlex.Lexeme IN item THEN
state:=TITEM
ELSE
state:=TERROR;
TBINARYOPER:
IF curlex.Lexeme IN item THEN
state:=TITEM
ELSE
state:=TERROR;
END;
UNTIL (State=TERROR) OR (curlex.lexeme=FINISH);
// IF (curlex.lexeme<>FINISH) THEN
IF STATE=TERROR THEN
BEGIN
Ferr:='Синтаксическая ошибка';
FErrPos:=curlex.position
END
END;
end.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,Lexical, Syntax2,StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
LA:TLExicalAnalyzer;
SA:TSyntaxAnalyzer;
Rez:Boolean;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
LA:=TLExicalAnalyzer.Create;
end;
procedure TForm1.Button1Click(Sender: TObject);
var R:tresult;
mes:STRING;
begin
SetLength(r,0);
WITH LA DO
BEGIN
Run(Trim(edit1.Text));
IF Error='' THEN
begin
r:=Lexem;
SA:=TSyntaxAnalyzer.Create(r);
SA.Parse;
IF SA.error='' THEN
mes:='выражение корректное'
ELSE
BEGIN
mes:=SA.error+' (поз. '+IntToStr(SA.errorpos)+')';
WITH Edit1 DO
BEGIN
SetFocus;
IF SA.errorpos<Length(Edit1.Text) THEN
SelStart:=SA.errorpos
ELSE
SelStart:=Length(Edit1.Text)-1;
SelLength:=1
END
END;
MessageDlg(mes,mtInformation,[mbOK],0);
SA.Free;
END
ELSE
MessageDlg(error,mtInformation,[mbOK],0);
END
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
LA.Free
end;
end.
|