МИНОБРНАУКИ РОССИИ
ФГБОУ ВПО «Тульский государственный университет»
Кафедра «Автоматизированные станочные системы»
Курс «Лингвистическое и программное обеспечение САПР»
Отчет по лабораторной работе №2
Вариант№15
Выполнил: студ. гр. 622101 Федечкин Р.С.
Проверил: асс. Епифанова О.В.
Тула 2012
Текст задания
Задание №2
Язык выражений с побитовыми операциями логики языка Си, со скобками, с операндами в форме идентификаторов и целыми константами ( в двоичной форме).
<цифра> ( 0 | 1)
<число> <цифра>{<цифра>}
<A1> ( A | B | C | D … Z | _ )
<A2> ( A | B | C | D … Z | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | _ )
<идентификатор> <A1>{<A2>}
<операнд> (<идентификатор> |<число> )
<операция1> ( OR | XOR | AND )
<операция2> ( NOT )
<выражение1> (<операнд><операция1><операнд>){<операция1><операнд>}
<выражение2> (<операция2><операнд>){<операция2><операнд>}
<скобка1>(LB)
<скобка2>(RB)
<Выражение со скобками>-> <скобка1>(<выражение1>|<выражение2>)<скобка2>
<L> (<выражение со скобками>|<выражение1>|<выражение2>){(<выражение со скобками>|<выражение1>|<выражение2>)}
Цифра:
Число:
А1:
А2:
Идентификатор:
Операнд:
Операция1:
Операция2:
Выражение1:
Выражение2:
Скобка1: Скобка2:
Выражение со скобками:
Итог:
Текст программы
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Lexical, Syntax,Syntax2,Syntax3,StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: 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;
SA2:TSyntaxAnalyzer2;
SA3:TSyntaxAnalyzer3;
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.
Таблица лексем
unit Lexical;
interface
USES SysUtils;
TYPE TLexemeType=(NUMBER, ID, _AND, _XOR, FINISH, _OR,_NOT ,LP, RP);
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 ReadID;
VAR n:STRING;
BEGIN
n:=s[i];
INC(i);
WHILE (i<=LENGTH(s)) AND (s[i] IN ['A'..'Z','a'..'z','_','0'..'9']) DO
BEGIN
n:=n+s[i];
INC(i)
END;
AddLex(ID,0,n);
DEC(i)
END;
PROCEDURE ReadNumber;
VAR n:STRING;
BEGIN
n:=s[i];
INC(i);
WHILE (i<=LENGTH(s)) AND (s[i] IN ['0'..'1']) DO
BEGIN
n:=n+s[i];
INC(i)
END;
AddLex(NUMBER,StrToInt(n),n);
DEC(i)
END;
BEGIN
i:=1;
SetLength(Flex,0);
Ferr:='';
WHILE i<=LENGTH(s) DO
BEGIN
CASE s[i] OF
'&': AddLex(_AND,0,'AND');
'*': AddLex(_XOR,0,'XOR');
'^': AddLex(_OR,0,'OR');
'-': AddLex(_NOT,0,'NOT');
'(': AddLex(LP,0,'(');
')': AddLex(RP,0,')');
'A'..'Z','_','a'..'z': ReadID;
'0'..'1': ReadNumber
ELSE
BEGIN
Ferr:='Недопустимый символ;
Exit
END
END;
INC(i)
END;
AddLex(FINISH,0,'')
END;
end.
Синтаксический анализатор
unit Syntax;
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
var
nr,nl:integer;
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;
VAR curlex:TRes;
CONST operation=[_AND, _XOR, _OR{,_NOT}];
operationN=[_NOT];
skobki=[LP,RP];
item=[ID,NUMBER];
BEGIN
nl:=0;
nr:=0;
BEGIN
REPEAT
Curlex:=GetLex;
If (curlex.lexeme in OperationN) then
begin
Curlex:=GetLex;
If not (curlex.lexeme in item) then
Begin
Ferr:='Синтаксическая ошибка';
Ferrpos:=curlex.position;
Exit;
end;
end;
If (curlex.lexeme in item) then
if curlex.lexeme=LP then
begin
inc(nr);
Curlex:=GetLex;
If not(curlex.lexeme in Operation) then
Begin
if curlex.lexeme=Finish then exit;
Ferr:='Синтаксическая ошибка';
Ferrpos:=curlex.position;
Exit;
end;
end;
If (curlex.lexeme in Operation) then
if curlex.lexeme=RP then
begin
inc(nl);
Curlex:=GetLex;
If not (curlex.lexeme in item) then
Begin
Ferr:='Синтаксическая ошибка';
Ferrpos:=curlex.position;
Exit;
end;
end;
UNTIL curlex.lexeme=FINISH;
end;
end;
end.
Результаты работы программы
Рис.1
Рис.2