Parancsértelmezőhöz kellhet
Ha olyan programot írsz, amelynek lesz parancsértelmező része, pl. MI script, akkor biztos, hogy kell lennie benne egy olyan lépésnek, amely a nyers szöveget a nyelv elemeire bontja szét.
A következő példa azt csinálja, hogy egy megadott fájlt nyelv elemekre bont szét, és azokat kiírja egy másik fájba:
C/C++:
#include "stdio.h"
#include "conio.h"
#include "string.h"
#include "stdlib.h"
#define M_NONE 0
#define M_SYMBOL 1
#define M_STRING 2
#define M_NUMBER 3
#define M_HEXNUM 4
#define M_OCTNUM 5
#define M_LE_COMMENT 6
#define M_F_COMMENT 7
#define M_SPECSYM 8
#define M_CHARCONST 9
FILE *in,*out;
char str[200];
int Mode;
//--------//
// Szóköz //
//--------//
char Space(char x)
{
return (x==13) || (x==9) || (x==32) || (x==10);
}
//------//
// Betű //
//------//
char Letter(char x)
{
return ((x>='a') && (x<='z')) || ((x>='A') && (x<='Z')) || (x=='_');
}
//-------------------------//
// Szám, 10-es számrendszer//
//-------------------------//
char Szam10(char x)
{
return (x>='0') && (x<='9');
}
//--------------------------//
// Szám, 16-os számrendszer //
//--------------------------//
char Szam16(char x)
{
return Szam10(x) || ((x>='a') && (x<='f')) || ((x>='A') && (x<='F'));
}
//-------------------------//
// Szám, 8-as számrendszer //
//-------------------------//
char Szam8(char x)
{
return (x>='0') && (x<='7');
}
//------------------//
// Spec szimbólumok //
//------------------//
char SpecSym(char x)
{
char SpecSzm[]={'\'','\"','+','!','%','/','=','(',')','\\',
'|' ,'[' ,']','$','<','>','#','&','@','{',
'}' ,',' ,'?',';','.',':','-','*'};
int i;
for (i=0;i<=28;i++)
{
if (x==SpecSzm[i]) return 1;
}
return 0;
}
//---------------------------------//
// Karakter hozzáfűzése string-hez //
//---------------------------------//
void strccat(char *str,char x)
{
int len;
len=strlen(str);
str[len]=x;
str[len+1]=0;
}
//----------------//
// Elemek kiírása //
//----------------//
void Working()
{
char c;
int sp;
int i;
Mode=M_NONE;
strcpy(str,"");
char ss[40];
while ((c=fgetc(in))!=EOF)
{
switch (Mode)
{
case M_NONE:
{
if (Space(c)) continue;
else
if (Letter(c))
{
Mode=M_SYMBOL;
strccat(str,c);
}
else
if (Szam10(c))
{
Mode=M_NUMBER;
if (c=='0') Mode=M_OCTNUM;
strccat(str,c);
}
else
if (SpecSym(c))
{
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
else
{
Mode=M_SPECSYM;
strccat(str,c);
}
}
else
{
printf("Illegal char: #%d",c);
exit(0);
}
break;
}
case M_SYMBOL:
{
if (Space(c))
{
fprintf(out,"%s (symbol)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
if (Letter(c) || Szam10(c))
{
strccat(str,c);
}
else
if (SpecSym(c))
{
fprintf(out,"%s (symbol)\n",str);
strcpy(str,"");
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
else
{
Mode=M_SPECSYM;
strccat(str,c);
}
}
break;
}
case M_STRING:
{
if ((c=='\"') && ((str[strlen(str)-1]!='\\') ||
((str[strlen(str)-1]=='\\') && (str[strlen(str)-2]=='\\'))))
{
fprintf(out,"%s (string const)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
strccat(str,c);
break;
}
case M_NUMBER:
{
if (Space(c))
{
fprintf(out,"%s (dec number)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
if (Letter(c))
{
printf("Invalid number!");
exit(0);
}
else
if (Szam10(c))
{
strccat(str,c);
}
else
if (SpecSym(c))
{
fprintf(out,"%s (dec number)\n",str);
strcpy(str,"");
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
else
{
Mode=M_SPECSYM;
strccat(str,c);
}
}
break;
}
case M_HEXNUM:
{
if (Space(c))
{
fprintf(out,"%s (hex number)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
if (Szam16(c))
{
strccat(str,c);
}
else
if (Letter(c))
{
printf("Invalid hex number!");
exit(0);
}
else
if (SpecSym(c))
{
fprintf(out,"%s (hex number)\n",str);
strcpy(str,"");
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
else
{
Mode=M_SPECSYM;
strccat(str,c);
}
}
break;
}
case M_OCTNUM:
{
if ((strlen(str)==1) && ((c=='x') || (c=='X')) && (str[0]=='0'))
{
Mode=M_HEXNUM;
strccat(str,c);
continue;
}
else
if (Space(c))
{
fprintf(out,"%s (oct number)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
if (Szam8(c))
{
strccat(str,c);
}
else
if (SpecSym(c))
{
fprintf(out,"%s (oct number)\n",str);
strcpy(str,"");
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
else
{
Mode=M_SPECSYM;
strccat(str,c);
}
}
else
{
printf("Invalid oct number!");
exit(0);
}
break;
}
case M_LE_COMMENT:
{
if (c==10) Mode=M_NONE;
break;
}
case M_F_COMMENT:
{
str[0]=str[1];
str[1]=c;
if (!strcmp(str,"*/"))
{
strcpy(str,"");
Mode=M_NONE;
}
break;
}
case M_SPECSYM:
{
if (!strcmp(str,"//"))
{
Mode=M_LE_COMMENT;
strcpy(str,"");
continue;
}
else
if (!strcmp(str,"/*"))
{
Mode=M_F_COMMENT;
continue;
}
else
if (Space(c))
{
fprintf(out,"%s (special symbol)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
if (Letter(c))
{
fprintf(out,"%s (special symbol)\n",str);
strcpy(str,"");
Mode=M_SYMBOL;
strccat(str,c);
}
else
if (Szam10(c))
{
fprintf(out,"%s (special symbol)\n",str);
strcpy(str,"");
Mode=M_NUMBER;
if (c=='0') Mode=M_OCTNUM;
strccat(str,c);
}
else
if (SpecSym(c))
{
if ((c=='\'') || (c=='\"'))
{
fprintf(out,"%s (special symbol)\n",str);
strcpy(str,"");
if (c=='\"') Mode=M_STRING;
else if (c=='\'') Mode=M_CHARCONST;
}
else
strccat(str,c);
}
else
{
printf("Illegal char: #%d",c);
exit(0);
}
break;
}
case M_CHARCONST:
{
if ((c=='\'') && ((str[strlen(str)-1]!='\\') ||
((str[strlen(str)-1]=='\\') && (str[strlen(str)-2]=='\\'))))
{
fprintf(out,"%s (character const)\n",str);
strcpy(str,"");
Mode=M_NONE;
}
else
strccat(str,c);
if (strlen(str)>2)
{
printf("character constant too long.");
exit(0);
}
break;
}
}
}
strcpy(ss,"");
switch (Mode)
{
case M_SYMBOL: strcpy(ss,"symbol"); break;
case M_STRING: strcpy(ss,"string const"); break;
case M_NUMBER: strcpy(ss,"dec number"); break;
case M_HEXNUM: strcpy(ss,"hex number"); break;
case M_OCTNUM: strcpy(ss,"oct number"); break;
case M_SPECSYM: strcpy(ss,"special symbol"); break;
case M_CHARCONST: strcpy(ss,"character const"); break;
}
if (Mode!=M_NONE)
fprintf(out,"%s (%s)\n",str,ss);
}
//-----------//
// Főprogram //
//-----------//
void main(int argc,char *argv[])
{
if (argc<2)
{
printf("Használat: Szetbont input_file output_file");
return;
}
in=fopen(argv[1],"r");
out=fopen(argv[2],"w+t");
Working();
fclose(in);
fclose(out);
}
Pascal:
PROGRAM SzetBonto;
{----------}
{Konstansok}
{----------}
CONST
M_NONE=0;
M_SYMBOL=1;
M_STRING=2;
M_NUMBER=3;
M_HEXNUM=4;
M_OCTNUM=5;
M_LE_COMMENT=6;
M_F_COMMENT=7;
M_SPECSYM=8;
M_CHARCONST=9;
{--------}
{Változók}
{--------}
VAR
_in:FILE OF CHAR;
Out:TEXT;
str:STRING[200];
Mode:INTEGER;
{------}
{Szóköz}
{------}
FUNCTION Space(x:CHAR):BOOLEAN;
BEGIN
Space:= (x=#13) OR (x=#9) OR (x=#32) OR (x=#10);
END;
{----}
{Betű}
{----}
FUNCTION Letter(x:CHAR):BOOLEAN;
BEGIN
Letter:=((x>='a') AND (x<='z')) OR ((x>='A') AND (x<='Z')) OR (x='_');
END;
{--------------}
{Decimális szám}
{--------------}
FUNCTION Szam10(x:CHAR):BOOLEAN;
BEGIN
Szam10:=(x>='0') AND (x<='9');
END;
{------------------}
{Hexadecimális szám}
{------------------}
FUNCTION Szam16(x:CHAR):BOOLEAN;
BEGIN
Szam16:=Szam10(x) OR ((x>='a') AND (x<='f')) OR ((x>='A') AND (x<='F'));
END;
{------------}
{Oktális szám}
{------------}
FUNCTION Szam8(x:CHAR):BOOLEAN;
BEGIN
Szam8:=(x>='0') AND (x<='7');
END;
{---------------------}
{Speciális szimbólumok}
{---------------------}
FUNCTION SpecSym(x:CHAR):BOOLEAN;
CONST
SpecSzm:SET OF CHAR=
['''','"' ,'+','!','%','/','=','(',')','\',
'|' ,'[' ,']','$','<','>','#','&','@','{',
'}' ,',' ,'?',';','.',':','-','*'];
BEGIN
SpecSym:=x IN SpecSzm;
END;
{--------------}
{Elemek kiírása}
{--------------}
PROCEDURE Working;
VAR
c:CHAR;
sp,i:INTEGER;
ss:STRING[40];
BEGIN
Mode:=M_NONE;
str:='';
WHILE NOT EoF(_in) DO
BEGIN
Read(_in,c);
CASE Mode OF
M_NONE:
BEGIN
IF Space(c) THEN Continue
ELSE
IF Letter(c) THEN
BEGIN
Mode:=M_SYMBOL;
str:=str+c;
END
ELSE
IF Szam10(c) THEN
BEGIN
Mode:=M_NUMBER;
IF c='0' THEN Mode:=M_OCTNUM;
str:=str+c;
END
ELSE
IF SpecSym(c) THEN
BEGIN
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST
ELSE
BEGIN
Mode:=M_SPECSYM;
str:=str+c;
END;
END
ELSE
BEGIN
WriteLn('Illegal char: #',Ord(c));
Halt;
END;
END;
M_SYMBOL:
BEGIN
IF Space(c) THEN
BEGIN
WriteLn(Out,str,' (symbol)');
str:='';
Mode:=M_NONE;
END
ELSE
IF Letter(c) OR Szam10(c) THEN
str:=str+c
ELSE
IF SpecSym(c) THEN
BEGIN
WriteLn(Out,str,' (symbol)');
str:='';
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST
ELSE
BEGIN
Mode:=M_SPECSYM;
str:=str+c;
END;
END;
END;
M_STRING:
BEGIN
IF (c='"') AND ((str[Length(str)]<>'\') OR
((str[Length(str)]='\') AND (str[Length(str)-1]='\'))) THEN
BEGIN
WriteLn(Out,str,' (string const)');
str:='';
Mode:=M_NONE;
END
ELSE
str:=str+c;
END;
M_NUMBER:
BEGIN
IF Space(c) THEN
BEGIN
WriteLn(Out,str,' (dec number)');
str:='';
Mode:=M_NONE;
END
ELSE
IF Letter(c) THEN
BEGIN
WriteLn('Invalid number!');
Halt;
END
ELSE
IF Szam10(c) THEN
str:=str+c
ELSE
IF SpecSym(c) THEN
BEGIN
WriteLn(Out,str,' (dec number)');
str:=c;
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST
ELSE
BEGIN
Mode:=M_SPECSYM;
str:=str+c;
END;
END;
END;
M_HEXNUM:
BEGIN
IF Space(c) THEN
BEGIN
WriteLn(Out,str,' (hex number)');
str:='';
Mode:=M_NONE;
END
ELSE
IF Szam16(c) THEN
str:=str+c
ELSE
IF Letter(c) THEN
BEGIN
WriteLn('Invalid hex number!');
Halt;
END
ELSE
IF SpecSym(c) THEN
BEGIN
WriteLn(Out,str,' (hex number)');
str:=c;
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST
ELSE
BEGIN
Mode:=M_SPECSYM;
str:=str+c;
END;
END;
END;
M_OCTNUM:
BEGIN
IF (Length(str)=1) AND ((c='x') OR (c='X')) AND (str[1]='0') THEN
BEGIN
Mode:=M_HEXNUM;
str:=str+c;
Continue;
END
ELSE
IF Space(c) THEN
BEGIN
WriteLn(Out,str,' (oct number)');
str:='';
Mode:=M_NONE;
END
ELSE
IF Szam8(c) THEN
BEGIN
str:=str+c;
END
ELSE
IF SpecSym(c) THEN
BEGIN
WriteLn(Out,str,' (oct number)');
str:=c;
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST
ELSE
BEGIN
Mode:=M_SPECSYM;
str:=str+c;
END;
END
ELSE
BEGIN
WriteLn('Invalid octal number!');
Halt;
END;
END;
M_LE_COMMENT:
BEGIN
IF (c=#10) THEN Mode:=M_NONE;
END;
M_F_COMMENT:
BEGIN
str[1]:=str[2];
str[2]:=c;
IF str='*/' THEN
BEGIN
str:='';
Mode:=M_NONE;
END;
END;
M_SPECSYM:
BEGIN
IF str='//' THEN
BEGIN
Mode:=M_LE_COMMENT;
str:='';
Continue;
END
ELSE
IF str='/*' THEN
BEGIN
Mode:=M_F_COMMENT;
continue;
END
ELSE
IF Space(c) THEN
BEGIN
WriteLn(Out,str,' (special symbol)');
str:='';
Mode:=M_NONE;
END
ELSE
IF Szam10(c) THEN
BEGIN
WriteLn(Out,str,' (special symbol)');
str:='';
Mode:=M_NUMBER;
IF c='0' THEN Mode:=M_OCTNUM;
str:=str+c;
END
ELSE
IF Letter(c) THEN
BEGIN
WriteLn(Out,str,' (special symbol)');
str:='';
Mode:=M_SYMBOL;
str:=str+c;
END
ELSE
IF SpecSym(c) THEN
BEGIN
IF (c='''') OR (c='"') THEN
BEGIN
WriteLn(Out,str,' (special symbol)');
str:='';
IF c='"' THEN Mode:=M_STRING
ELSE IF c='''' THEN Mode:=M_CHARCONST;
END
ELSE
str:=str+c;
END
ELSE
BEGIN
WriteLn('Illegal char.');
Halt;
END;
END;
M_CHARCONST:
BEGIN
IF (c='''') AND ((str[Length(str)]<>'\') OR
((str[Length(str)]='\') AND (str[Length(str)-1]='\'))) THEN
BEGIN
WriteLn(Out,str,' (character const)');
str:='';
Mode:=M_NONE;
END
ELSE
str:=str+c;
IF Length(str)>2 THEN
BEGIN
WriteLn('Character constant too long.');
Halt;
END;
END;
END;
END;
ss:='';
CASE Mode OF
M_SYMBOL: ss:='symbol';
M_STRING: ss:='string const';
M_NUMBER: ss:='dec number';
M_HEXNUM: ss:='hex number';
M_OCTNUM: ss:='oct number';
M_SPECSYM: ss:='special symbol';
M_CHARCONST: ss:='character const';
END;
IF Mode<>M_NONE THEN
WriteLn(Out,str,' (',ss,')');
END;
{---------}
{FŐPROGRAM}
{---------}
BEGIN
IF ParamCount<2 THEN
BEGIN
WriteLn('Használat: Szetbont input_file output_file');
halt;
END;
Assign(_in,ParamStr(1));
FileMode:=0;
{$I-} Reset(_in); {$I+}
IF IOResult<>0 THEN
BEGIN
WriteLn('Unable to open input file.');
Halt;
END;
Assign(Out,ParamStr(2));
{$I-} Rewrite(Out); {$I+}
IF IOResult<>0 THEN
BEGIN
WriteLn('Unable to open output file.');
Halt;
END;
Working;
Close(_in);
Close(Out);
END.