program LexicalAnalysis;
{$mode objfpc}{$H+}
uses
SysUtils;
var
Lines: array of string ;
Row, Col: Integer ;
ErrorFound: Boolean ;
procedure ShowError;
begin
Writeln ( 'ERROR: invalid word at line ' ,
Row, ', position ' , Col) ;
ErrorFound : = True ;
end ;
function CheckFirstWord( var S: string ; var P: Integer ) : Boolean ;
var
StartPos: Integer ;
begin
Result : = False ;
StartPos : = P;
{ (000)* }
while ( P + 2 <= Length( S) ) and
( S[ P] = '0' ) and
( S[ P + 1 ] = '0' ) and
( S[ P + 2 ] = '0' ) do
begin
P : = P + 3 ;
end ;
{ 001 }
if ( P + 2 > Length( S) ) or
( S[ P] <> '0' ) or
( S[ P + 1 ] <> '0' ) or
( S[ P + 2 ] <> '1' ) then
begin
P : = StartPos;
Exit;
end ;
P : = P + 3 ;
{ (010)* }
while ( P + 2 <= Length( S) ) and
( S[ P] = '0' ) and
( S[ P + 1 ] = '1' ) and
( S[ P + 2 ] = '0' ) do
begin
P : = P + 3 ;
end ;
Result : = True ;
end ;
function CheckSecondWord( var S: string ; var P: Integer ) : Boolean ;
begin
Result : = False ;
{ First two symbols must be ab }
if ( P + 1 > Length( S) ) or
( S[ P] <> 'a' ) or
( S[ P + 1 ] <> 'b' ) then
Exit;
P : = P + 2 ;
{ After ab: a,b,c,d }
while ( P <= Length( S) ) and
( S[ P] in [ 'a' , 'b' , 'c' , 'd' ] ) do
begin
P : = P + 1 ;
end ;
Result : = True ;
end ;
procedure SkipComment( var S: string ; var P: Integer ) ;
begin
{ Skip apostrophe }
P : = P + 1 ;
{ Skip comment to end of line }
while P <= Length( S) do
P : = P + 1 ;
end ;
procedure AnalyzeLine( var S: string ; LineNumber: Integer ) ;
var
P: Integer ;
OldP: Integer ;
TokenFound: Boolean ;
begin
P : = 1 ;
while P <= Length( S) do
begin
{ Skip spaces }
while ( P <= Length( S) ) and
( S[ P] = ' ' ) do
P : = P + 1 ;
if P > Length( S) then
Break ;
{ Comment }
if S[ P] = '' '' then
begin
SkipComment( S, P) ;
Break ;
end ;
OldP : = P;
TokenFound : = False ;
{ First word }
if S[ P] = '0' then
begin
if CheckFirstWord( S, P) then
TokenFound : = True ;
end
{ Second word }
else if S[ P] = 'a' then
begin
if CheckSecondWord( S, P) then
TokenFound : = True ;
end ;
{ Invalid word }
if not TokenFound then
begin
Row : = LineNumber;
Col : = OldP;
ShowError;
Exit;
end ;
{ Check separator }
if ( P <= Length( S) ) and
not ( S[ P] in [ ' ' , '' '' ] ) then
begin
Row : = LineNumber;
Col : = P;
ShowError;
Exit;
end ;
end ;
end ;
var
N, I: Integer ;
begin
Writeln ( '==============================================' ) ;
Writeln ( ' LEXICAL ANALYZER' ) ;
Writeln ( ' VARIANT 34' ) ;
Writeln ( '==============================================' ) ;
Writeln ;
Writeln ( 'WORD 1: (000)*001(010)*' ) ;
Writeln ( 'WORD 2: ab(a|b|c|d)*' ) ;
Writeln ( 'COMMENT: apostrophe to end of line' ) ;
Writeln ;
Write ( 'Enter number of lines: ' ) ;
ReadLn ( N) ;
SetLength( Lines, N) ;
Writeln ;
Writeln ( 'Enter text:' ) ;
for I : = 1 to N do
ReadLn ( Lines[ I - 1 ] ) ;
ErrorFound : = False ;
for I : = 1 to N do
begin
AnalyzeLine( Lines[ I - 1 ] , I) ;
if ErrorFound then
Break ;
end ;
Writeln ;
if not ErrorFound then
Writeln ( 'No errors found.' ) ;
Writeln ;
Writeln ( 'Press Enter to exit.' ) ;
ReadLn ;
end .
cHJvZ3JhbSBMZXhpY2FsQW5hbHlzaXM7Cgp7JG1vZGUgb2JqZnBjfXskSCt9Cgp1c2VzCiAgU3lzVXRpbHM7Cgp2YXIKICBMaW5lczogYXJyYXkgb2Ygc3RyaW5nOwogIFJvdywgQ29sOiBJbnRlZ2VyOwogIEVycm9yRm91bmQ6IEJvb2xlYW47CgoKcHJvY2VkdXJlIFNob3dFcnJvcjsKYmVnaW4KICBXcml0ZWxuKCdFUlJPUjogaW52YWxpZCB3b3JkIGF0IGxpbmUgJywKICAgICAgICAgIFJvdywgJywgcG9zaXRpb24gJywgQ29sKTsKICBFcnJvckZvdW5kIDo9IFRydWU7CmVuZDsKCgpmdW5jdGlvbiBDaGVja0ZpcnN0V29yZCh2YXIgUzogc3RyaW5nOyB2YXIgUDogSW50ZWdlcik6IEJvb2xlYW47CnZhcgogIFN0YXJ0UG9zOiBJbnRlZ2VyOwpiZWdpbgogIFJlc3VsdCA6PSBGYWxzZTsKICBTdGFydFBvcyA6PSBQOwoKICB7ICgwMDApKiB9CgogIHdoaWxlIChQICsgMiA8PSBMZW5ndGgoUykpIGFuZAogICAgICAgIChTW1BdID0gJzAnKSBhbmQKICAgICAgICAoU1tQICsgMV0gPSAnMCcpIGFuZAogICAgICAgIChTW1AgKyAyXSA9ICcwJykgZG8KICBiZWdpbgogICAgUCA6PSBQICsgMzsKICBlbmQ7CgogIHsgMDAxIH0KCiAgaWYgKFAgKyAyID4gTGVuZ3RoKFMpKSBvcgogICAgIChTW1BdIDw+ICcwJykgb3IKICAgICAoU1tQICsgMV0gPD4gJzAnKSBvcgogICAgIChTW1AgKyAyXSA8PiAnMScpIHRoZW4KICBiZWdpbgogICAgUCA6PSBTdGFydFBvczsKICAgIEV4aXQ7CiAgZW5kOwoKICBQIDo9IFAgKyAzOwoKICB7ICgwMTApKiB9CgogIHdoaWxlIChQICsgMiA8PSBMZW5ndGgoUykpIGFuZAogICAgICAgIChTW1BdID0gJzAnKSBhbmQKICAgICAgICAoU1tQICsgMV0gPSAnMScpIGFuZAogICAgICAgIChTW1AgKyAyXSA9ICcwJykgZG8KICBiZWdpbgogICAgUCA6PSBQICsgMzsKICBlbmQ7CgogIFJlc3VsdCA6PSBUcnVlOwplbmQ7CgoKZnVuY3Rpb24gQ2hlY2tTZWNvbmRXb3JkKHZhciBTOiBzdHJpbmc7IHZhciBQOiBJbnRlZ2VyKTogQm9vbGVhbjsKYmVnaW4KICBSZXN1bHQgOj0gRmFsc2U7CgogIHsgRmlyc3QgdHdvIHN5bWJvbHMgbXVzdCBiZSBhYiB9CgogIGlmIChQICsgMSA+IExlbmd0aChTKSkgb3IKICAgICAoU1tQXSA8PiAnYScpIG9yCiAgICAgKFNbUCArIDFdIDw+ICdiJykgdGhlbgogICAgRXhpdDsKCiAgUCA6PSBQICsgMjsKCiAgeyBBZnRlciBhYjogYSxiLGMsZCB9CgogIHdoaWxlIChQIDw9IExlbmd0aChTKSkgYW5kCiAgICAgICAgKFNbUF0gaW4gWydhJywgJ2InLCAnYycsICdkJ10pIGRvCiAgYmVnaW4KICAgIFAgOj0gUCArIDE7CiAgZW5kOwoKICBSZXN1bHQgOj0gVHJ1ZTsKZW5kOwoKCnByb2NlZHVyZSBTa2lwQ29tbWVudCh2YXIgUzogc3RyaW5nOyB2YXIgUDogSW50ZWdlcik7CmJlZ2luCiAgeyBTa2lwIGFwb3N0cm9waGUgfQoKICBQIDo9IFAgKyAxOwoKICB7IFNraXAgY29tbWVudCB0byBlbmQgb2YgbGluZSB9CgogIHdoaWxlIFAgPD0gTGVuZ3RoKFMpIGRvCiAgICBQIDo9IFAgKyAxOwplbmQ7CgoKcHJvY2VkdXJlIEFuYWx5emVMaW5lKHZhciBTOiBzdHJpbmc7IExpbmVOdW1iZXI6IEludGVnZXIpOwp2YXIKICBQOiBJbnRlZ2VyOwogIE9sZFA6IEludGVnZXI7CiAgVG9rZW5Gb3VuZDogQm9vbGVhbjsKYmVnaW4KICBQIDo9IDE7CgogIHdoaWxlIFAgPD0gTGVuZ3RoKFMpIGRvCiAgYmVnaW4KCiAgICB7IFNraXAgc3BhY2VzIH0KCiAgICB3aGlsZSAoUCA8PSBMZW5ndGgoUykpIGFuZAogICAgICAgICAgKFNbUF0gPSAnICcpIGRvCiAgICAgIFAgOj0gUCArIDE7CgogICAgaWYgUCA+IExlbmd0aChTKSB0aGVuCiAgICAgIEJyZWFrOwoKCiAgICB7IENvbW1lbnQgfQoKICAgIGlmIFNbUF0gPSAnJycnIHRoZW4KICAgIGJlZ2luCiAgICAgIFNraXBDb21tZW50KFMsIFApOwogICAgICBCcmVhazsKICAgIGVuZDsKCgogICAgT2xkUCA6PSBQOwogICAgVG9rZW5Gb3VuZCA6PSBGYWxzZTsKCgogICAgeyBGaXJzdCB3b3JkIH0KCiAgICBpZiBTW1BdID0gJzAnIHRoZW4KICAgIGJlZ2luCiAgICAgIGlmIENoZWNrRmlyc3RXb3JkKFMsIFApIHRoZW4KICAgICAgICBUb2tlbkZvdW5kIDo9IFRydWU7CiAgICBlbmQKCgogICAgeyBTZWNvbmQgd29yZCB9CgogICAgZWxzZSBpZiBTW1BdID0gJ2EnIHRoZW4KICAgIGJlZ2luCiAgICAgIGlmIENoZWNrU2Vjb25kV29yZChTLCBQKSB0aGVuCiAgICAgICAgVG9rZW5Gb3VuZCA6PSBUcnVlOwogICAgZW5kOwoKCiAgICB7IEludmFsaWQgd29yZCB9CgogICAgaWYgbm90IFRva2VuRm91bmQgdGhlbgogICAgYmVnaW4KICAgICAgUm93IDo9IExpbmVOdW1iZXI7CiAgICAgIENvbCA6PSBPbGRQOwogICAgICBTaG93RXJyb3I7CiAgICAgIEV4aXQ7CiAgICBlbmQ7CgoKICAgIHsgQ2hlY2sgc2VwYXJhdG9yIH0KCiAgICBpZiAoUCA8PSBMZW5ndGgoUykpIGFuZAogICAgICAgbm90IChTW1BdIGluIFsnICcsICcnJyddKSB0aGVuCiAgICBiZWdpbgogICAgICBSb3cgOj0gTGluZU51bWJlcjsKICAgICAgQ29sIDo9IFA7CiAgICAgIFNob3dFcnJvcjsKICAgICAgRXhpdDsKICAgIGVuZDsKCiAgZW5kOwplbmQ7CgoKdmFyCiAgTiwgSTogSW50ZWdlcjsKCmJlZ2luCgogIFdyaXRlbG4oJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTsKICBXcml0ZWxuKCcgICAgICAgICAgIExFWElDQUwgQU5BTFlaRVInKTsKICBXcml0ZWxuKCcgICAgICAgICAgICAgICAgIFZBUklBTlQgMzQnKTsKICBXcml0ZWxuKCc9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7CiAgV3JpdGVsbjsKCiAgV3JpdGVsbignV09SRCAxOiAoMDAwKSowMDEoMDEwKSonKTsKICBXcml0ZWxuKCdXT1JEIDI6IGFiKGF8YnxjfGQpKicpOwogIFdyaXRlbG4oJ0NPTU1FTlQ6IGFwb3N0cm9waGUgdG8gZW5kIG9mIGxpbmUnKTsKICBXcml0ZWxuOwoKCiAgV3JpdGUoJ0VudGVyIG51bWJlciBvZiBsaW5lczogJyk7CiAgUmVhZExuKE4pOwoKICBTZXRMZW5ndGgoTGluZXMsIE4pOwoKICBXcml0ZWxuOwogIFdyaXRlbG4oJ0VudGVyIHRleHQ6Jyk7CgogIGZvciBJIDo9IDEgdG8gTiBkbwogICAgUmVhZExuKExpbmVzW0kgLSAxXSk7CgoKICBFcnJvckZvdW5kIDo9IEZhbHNlOwoKCiAgZm9yIEkgOj0gMSB0byBOIGRvCiAgYmVnaW4KICAgIEFuYWx5emVMaW5lKExpbmVzW0kgLSAxXSwgSSk7CgogICAgaWYgRXJyb3JGb3VuZCB0aGVuCiAgICAgIEJyZWFrOwogIGVuZDsKCgogIFdyaXRlbG47CgogIGlmIG5vdCBFcnJvckZvdW5kIHRoZW4KICAgIFdyaXRlbG4oJ05vIGVycm9ycyBmb3VuZC4nKTsKCgogIFdyaXRlbG47CiAgV3JpdGVsbignUHJlc3MgRW50ZXIgdG8gZXhpdC4nKTsKICBSZWFkTG47CgplbmQu
stdin
NyAyMQoxIDIgNTQ3MTUyCjEgMyA1MDkxNTcKMSA0IDUzOTI4MgoxIDUgNTQxNjQ1ICAgICAgICAgCjEgNiA0NTg0MzMKMSA3IDM4NTE3M+KAqAoyIDMgMTMxNTI4CjIgNCA5MjczNQoyIDUgMTUwNTExCjIgNiA5NDQ0MAoyIDcgMTk0NTQyCjMgNCAyMTY2MDAKMyA1IDI3MjQwMQozIDYgMTU3MTc2CjMgNyAxMjQwNzcKNCA1IDU3Nzg1CjQgNiA5NzMyMwo0IDcgMjQyMjMyCjUgNiAxMzY2NjMKNSA3IDI4Mzg2Mgo2IDcgMTQ3NDI2
7 21
1 2 547152
1 3 509157
1 4 539282
1 5 541645
1 6 458433
1 7 385173
2 3 131528
2 4 92735
2 5 150511
2 6 94440
2 7 194542
3 4 216600
3 5 272401
3 6 157176
3 7 124077
4 5 57785
4 6 97323
4 7 242232
5 6 136663
5 7 283862
6 7 147426