|
#1
|
|||
|
|||
Лог.Выражение
Помогите решить задачу за 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. Последний раз редактировалось Nehemian, 13.08.2010 в 14:44. |
#2
|
||||
|
||||
Напиши пример выражения(детальней) и как должны выглядеть выходные данные. Тоесть опиши как бы всё это выводилосяб на екран. Парсер у меня уже есть осталось только дописать функцию которая б переделывала выражения твоего вида в вид приемлимый для парсера.
Не твори зла, и жизнь повернется к тебе передом Последний раз редактировалось Bars1992, 17.08.2010 в 09:25. |
#3
|
|||
|
|||
Гляди, выражения которыемы подаем на вход это TandF или notTorF или Tand(notTorF) и т.д.
|
#4
|
||||
|
||||
Держи http://ifolder.ru/18935367
Если что говори подправлю Не твори зла, и жизнь повернется к тебе передом |
#5
|
|||
|
|||
Спасибо Большое. Знаю много чем помочь не смогу, но если надо попробую. Обращаися если что...
|