program LexicalAnalyzer;
function CheckFirstWord( s: string ; var p: integer ) : boolean ;
var
start: integer ;
begin
start : = p;
{ (000)* }
while ( p + 2 <= Length( s) ) and
( s[ p] = '0' ) and
( s[ p + 1 ] = '0' ) and
( s[ p + 2 ] = '0' ) do
p : = p + 3 ;
{ 001 }
if ( p + 2 > Length( s) ) or
( s[ p] <> '0' ) or
( s[ p + 1 ] <> '0' ) or
( s[ p + 2 ] <> '1' ) then
begin
p : = start;
CheckFirstWord : = false ;
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
p : = p + 3 ;
CheckFirstWord : = true ;
end ;
function CheckSecondWord( s: string ; var p: integer ) : boolean ;
begin
{ First two characters must be ab }
if p + 1 > Length( s) then
begin
CheckSecondWord : = false ;
Exit;
end ;
if ( s[ p] <> 'a' ) or ( s[ p + 1 ] <> 'b' ) then
begin
CheckSecondWord : = false ;
Exit;
end ;
p : = p + 2 ;
{ Other characters can be a, b, c or d }
while ( p <= Length( s) ) and
( s[ p] in [ 'a' , 'b' , 'c' , 'd' ] ) do
p : = p + 1 ;
CheckSecondWord : = true ;
end ;
function AnalyzeLine( s: string ; lineNumber: integer ) : boolean ;
var
p: integer ;
ok: boolean ;
begin
p : = 1 ;
AnalyzeLine : = true ;
while p <= Length( s) do
begin
{ Skip spaces }
while ( p <= Length( s) ) and ( s[ p] = ' ' ) do
p : = p + 1 ;
if p > Length( s) then
Exit;
{ Comment }
if s[ p] = '' '' then
begin
Exit;
end ;
{ First word }
if s[ p] = '0' then
begin
ok : = CheckFirstWord( s, p) ;
if not ok then
begin
writeln ( 'Error in line ' , lineNumber,
', position ' , p,
': invalid first word.' ) ;
AnalyzeLine : = false ;
Exit;
end ;
end
{ Second word }
else if s[ p] in [ 'a' , 'b' , 'c' , 'd' ] then
begin
ok : = CheckSecondWord( s, p) ;
if not ok then
begin
writeln ( 'Error in line ' , lineNumber,
', position ' , p,
': invalid second word.' ) ;
AnalyzeLine : = false ;
Exit;
end ;
end
{ Invalid character }
else
begin
writeln ( 'Error in line ' , lineNumber,
', position ' , p,
': invalid character.' ) ;
AnalyzeLine : = false ;
Exit;
end ;
end ;
end ;
var
n: integer ;
i: integer ;
line: string ;
allCorrect: boolean ;
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) ;
writeln ;
writeln ( 'Enter text:' ) ;
allCorrect : = true ;
for i : = 1 to n do
begin
readln ( line) ;
if not AnalyzeLine( line, i) then
allCorrect : = false ;
end ;
writeln ;
if allCorrect then
writeln ( 'No errors found.' ) ;
writeln ;
writeln ( 'Press Enter to exit.' ) ;
readln ;
end .
cHJvZ3JhbSBMZXhpY2FsQW5hbHl6ZXI7CgpmdW5jdGlvbiBDaGVja0ZpcnN0V29yZChzOiBzdHJpbmc7IHZhciBwOiBpbnRlZ2VyKTogYm9vbGVhbjsKdmFyCiAgc3RhcnQ6IGludGVnZXI7CmJlZ2luCiAgc3RhcnQgOj0gcDsKCiAgeyAoMDAwKSogfQogIHdoaWxlIChwICsgMiA8PSBMZW5ndGgocykpIGFuZAogICAgICAgIChzW3BdID0gJzAnKSBhbmQKICAgICAgICAoc1twICsgMV0gPSAnMCcpIGFuZAogICAgICAgIChzW3AgKyAyXSA9ICcwJykgZG8KICAgIHAgOj0gcCArIDM7CgogIHsgMDAxIH0KICBpZiAocCArIDIgPiBMZW5ndGgocykpIG9yCiAgICAgKHNbcF0gPD4gJzAnKSBvcgogICAgIChzW3AgKyAxXSA8PiAnMCcpIG9yCiAgICAgKHNbcCArIDJdIDw+ICcxJykgdGhlbgogIGJlZ2luCiAgICBwIDo9IHN0YXJ0OwogICAgQ2hlY2tGaXJzdFdvcmQgOj0gZmFsc2U7CiAgICBFeGl0OwogIGVuZDsKCiAgcCA6PSBwICsgMzsKCiAgeyAoMDEwKSogfQogIHdoaWxlIChwICsgMiA8PSBMZW5ndGgocykpIGFuZAogICAgICAgIChzW3BdID0gJzAnKSBhbmQKICAgICAgICAoc1twICsgMV0gPSAnMScpIGFuZAogICAgICAgIChzW3AgKyAyXSA9ICcwJykgZG8KICAgIHAgOj0gcCArIDM7CgogIENoZWNrRmlyc3RXb3JkIDo9IHRydWU7CmVuZDsKCgpmdW5jdGlvbiBDaGVja1NlY29uZFdvcmQoczogc3RyaW5nOyB2YXIgcDogaW50ZWdlcik6IGJvb2xlYW47CmJlZ2luCiAgeyBGaXJzdCB0d28gY2hhcmFjdGVycyBtdXN0IGJlIGFiIH0KCiAgaWYgcCArIDEgPiBMZW5ndGgocykgdGhlbgogIGJlZ2luCiAgICBDaGVja1NlY29uZFdvcmQgOj0gZmFsc2U7CiAgICBFeGl0OwogIGVuZDsKCiAgaWYgKHNbcF0gPD4gJ2EnKSBvciAoc1twICsgMV0gPD4gJ2InKSB0aGVuCiAgYmVnaW4KICAgIENoZWNrU2Vjb25kV29yZCA6PSBmYWxzZTsKICAgIEV4aXQ7CiAgZW5kOwoKICBwIDo9IHAgKyAyOwoKICB7IE90aGVyIGNoYXJhY3RlcnMgY2FuIGJlIGEsIGIsIGMgb3IgZCB9CgogIHdoaWxlIChwIDw9IExlbmd0aChzKSkgYW5kCiAgICAgICAgKHNbcF0gaW4gWydhJywgJ2InLCAnYycsICdkJ10pIGRvCiAgICBwIDo9IHAgKyAxOwoKICBDaGVja1NlY29uZFdvcmQgOj0gdHJ1ZTsKZW5kOwoKCmZ1bmN0aW9uIEFuYWx5emVMaW5lKHM6IHN0cmluZzsgbGluZU51bWJlcjogaW50ZWdlcik6IGJvb2xlYW47CnZhcgogIHA6IGludGVnZXI7CiAgb2s6IGJvb2xlYW47CmJlZ2luCiAgcCA6PSAxOwogIEFuYWx5emVMaW5lIDo9IHRydWU7CgogIHdoaWxlIHAgPD0gTGVuZ3RoKHMpIGRvCiAgYmVnaW4KCiAgICB7IFNraXAgc3BhY2VzIH0KICAgIHdoaWxlIChwIDw9IExlbmd0aChzKSkgYW5kIChzW3BdID0gJyAnKSBkbwogICAgICBwIDo9IHAgKyAxOwoKICAgIGlmIHAgPiBMZW5ndGgocykgdGhlbgogICAgICBFeGl0OwoKICAgIHsgQ29tbWVudCB9CiAgICBpZiBzW3BdID0gJycnJyB0aGVuCiAgICBiZWdpbgogICAgICBFeGl0OwogICAgZW5kOwoKICAgIHsgRmlyc3Qgd29yZCB9CiAgICBpZiBzW3BdID0gJzAnIHRoZW4KICAgIGJlZ2luCiAgICAgIG9rIDo9IENoZWNrRmlyc3RXb3JkKHMsIHApOwoKICAgICAgaWYgbm90IG9rIHRoZW4KICAgICAgYmVnaW4KICAgICAgICB3cml0ZWxuKCdFcnJvciBpbiBsaW5lICcsIGxpbmVOdW1iZXIsCiAgICAgICAgICAgICAgICAnLCBwb3NpdGlvbiAnLCBwLAogICAgICAgICAgICAgICAgJzogaW52YWxpZCBmaXJzdCB3b3JkLicpOwogICAgICAgIEFuYWx5emVMaW5lIDo9IGZhbHNlOwogICAgICAgIEV4aXQ7CiAgICAgIGVuZDsKICAgIGVuZAoKICAgIHsgU2Vjb25kIHdvcmQgfQogICAgZWxzZSBpZiBzW3BdIGluIFsnYScsICdiJywgJ2MnLCAnZCddIHRoZW4KICAgIGJlZ2luCiAgICAgIG9rIDo9IENoZWNrU2Vjb25kV29yZChzLCBwKTsKCiAgICAgIGlmIG5vdCBvayB0aGVuCiAgICAgIGJlZ2luCiAgICAgICAgd3JpdGVsbignRXJyb3IgaW4gbGluZSAnLCBsaW5lTnVtYmVyLAogICAgICAgICAgICAgICAgJywgcG9zaXRpb24gJywgcCwKICAgICAgICAgICAgICAgICc6IGludmFsaWQgc2Vjb25kIHdvcmQuJyk7CiAgICAgICAgQW5hbHl6ZUxpbmUgOj0gZmFsc2U7CiAgICAgICAgRXhpdDsKICAgICAgZW5kOwogICAgZW5kCgogICAgeyBJbnZhbGlkIGNoYXJhY3RlciB9CiAgICBlbHNlCiAgICBiZWdpbgogICAgICB3cml0ZWxuKCdFcnJvciBpbiBsaW5lICcsIGxpbmVOdW1iZXIsCiAgICAgICAgICAgICAgJywgcG9zaXRpb24gJywgcCwKICAgICAgICAgICAgICAnOiBpbnZhbGlkIGNoYXJhY3Rlci4nKTsKICAgICAgQW5hbHl6ZUxpbmUgOj0gZmFsc2U7CiAgICAgIEV4aXQ7CiAgICBlbmQ7CgogIGVuZDsKZW5kOwoKCnZhcgogIG46IGludGVnZXI7CiAgaTogaW50ZWdlcjsKICBsaW5lOiBzdHJpbmc7CiAgYWxsQ29ycmVjdDogYm9vbGVhbjsKCmJlZ2luCgogIHdyaXRlbG4oJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PScpOwogIHdyaXRlbG4oJ0xFWElDQUwgQU5BTFlaRVInKTsKICB3cml0ZWxuKCdWQVJJQU5UIDM0Jyk7CiAgd3JpdGVsbignPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7CiAgd3JpdGVsbjsKCiAgd3JpdGVsbignV09SRCAxOiAoMDAwKSowMDEoMDEwKSonKTsKICB3cml0ZWxuKCdXT1JEIDI6IGFiKGEgfCBiIHwgYyB8IGQpKicpOwogIHdyaXRlbG4oJ0NPTU1FTlQ6IGFwb3N0cm9waGUgdG8gZW5kIG9mIGxpbmUnKTsKICB3cml0ZWxuOwoKICB3cml0ZSgnRW50ZXIgbnVtYmVyIG9mIGxpbmVzOiAnKTsKICByZWFkbG4obik7CgogIHdyaXRlbG47CiAgd3JpdGVsbignRW50ZXIgdGV4dDonKTsKCiAgYWxsQ29ycmVjdCA6PSB0cnVlOwoKICBmb3IgaSA6PSAxIHRvIG4gZG8KICBiZWdpbgogICAgcmVhZGxuKGxpbmUpOwoKICAgIGlmIG5vdCBBbmFseXplTGluZShsaW5lLCBpKSB0aGVuCiAgICAgIGFsbENvcnJlY3QgOj0gZmFsc2U7CiAgZW5kOwoKICB3cml0ZWxuOwoKICBpZiBhbGxDb3JyZWN0IHRoZW4KICAgIHdyaXRlbG4oJ05vIGVycm9ycyBmb3VuZC4nKTsKCiAgd3JpdGVsbjsKICB3cml0ZWxuKCdQcmVzcyBFbnRlciB0byBleGl0LicpOwogIHJlYWRsbjsKCmVuZC4=