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.