형식언어: 2개의 글

형식언어 퀴즈(Quiz)

Posted by Patchman
2010.02.15 16:16 Univ Study/형식언어




형식언어 수업중 갑자기 나타난 퀴즈~!

정답이 궁굼하다면 댓글이나 메일로 문의

형식언어 스캐터(Scanner) 구현

Posted by Patchman
2010.02.15 16:12 Univ Study/형식언어

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

 

#define NO_KEYWORDS 12

#define ID_LENGTH 12

 

char id[ID_LENGTH];

 

 

enum tsymbol { tnull = -1,

tnot, tnotequ,tmod, tmodAssign, tident,tnumber,

/* 0 12 3 45 */

tfnumber, tand, tlparen, trparen, tmul, tmulAssign,

/*6 78 9 10 11 */

tplus, tinc, taddAssign, tcomma, tminus,tdec,

/* 12 1314 15 1617 */

tsubAssign, tdiv, tdivAssign, tsemicolon, tless, tlesse,

/* 18 1920 21 2223 */

tassign, tequal,tgreat, tgreate, tlbracket,trbracket,

/* 24 2526 27 2829 */

teof,

/* 30

 

//.................................................. word symnols .................................................. //

 

/* 31 3233 343536 */

tconst, telse,tif, tint,treturn, tvoid,

/* 37 3839 404142 */

twhile, tlbrace,tor, trbrace, tfor, tgoto,

/* 42 4344 */

tdo, tchar, tdouble

};

 

struct tokenType {

int number;// token number

union {

char id[ID_LENGTH];

int num;

float fnum;

} value;// token value

};

 

char *keyword[NO_KEYWORDS] = {

"const", "else", "if", "int", "return", "void", "while", "for", "goto", "do", "char", "double"

};

 

enum tsymbol tnum[NO_KEYWORDS] = {

tconst, telse, tif, tint, treturn, tvoid, twhile, tfor, tgoto, tdo, tchar, tdouble

};

 

void lexicalError(int n)

{

printf(" *** Lexical Error : ");

switch (n){

case 1 : printf("an identifier length must be less than 12.\n");

break;

case 2 : printf("next character must be &.\n");

break;

case 3 : printf("next character must be |.\n");

break;

case 4 : printf("invalid character!!!\n");

break;

}

}

 

int superLetter(char ch)

{

if(isalpha(ch) || ch == '_') return 1;

else return 0;

}

 

int superLetterOrDigit(char ch)

{

if (isalnum(ch) || ch == '_') return 1;

else return 0;

}

 

int hexValue(char ch)

{

switch (ch) {

case '0' : case '1' : case '2' : case '3' : case '4' :

case '5' : case '6' : case '7' : case '8' : case '9' :

return (ch - '0');

case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' :

return (ch - 'A' + 10);

case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' :

return (ch - 'a' + 10);

 

default : return -1;

}

}

 

int numCheck(char Character, FILE* source_file) // IntNum, RealNum Check

{

int flag=0;

 

if(Character == '.') flag=1;

else{

 

while(isdigit(Character) || Character == '.')

{

if(Character == '.') flag=1;

Character = fgetc(source_file);

}

}

 

ungetc(Character,stdin);

return flag;

}

 

float getRealNum(char Character, FILE* source_file)

{

int fnum1 = 0;

int fnum2 = 0;

do{

if(Character == '.'){

Character = fgetc(source_file);

fnum2 = 10*fnum2 + (int)(Character - '0');

}

else{

fnum1 = 10*fnum1 + (int)(Character - '0');

}

Character = fgetc(source_file);

}while (isdigit(Character) || Character == '.');

ungetc(Character,stdin);

return fnum1 + '.' + fnum2; // 코드 수정 필요함

}

 

int getIntNum(char firstCharacter, FILE* source_file)

{

 

int num = 0;

int value;

char ch;

 

if (firstCharacter != '0') {// decimal

ch = firstCharacter;

do {

num = 10*num + (int)(ch - '0');

ch = fgetc(source_file);

} while (isdigit(ch));

} else {

ch = fgetc(source_file);

if ((ch >= '0') && (ch <= '7'))// octal

do {

num = 8*num + (int)(ch - '0');

ch = fgetc(source_file);

} while ((ch >= '0') && (ch <= '7'));

else if ((ch == 'X') || (ch == 'X')) {// hexa decimal

while ((value = hexValue(ch=fgetc(source_file))) != -1)

num = 16 * num + value;

}

else num = 0;// zero

}

ungetc(ch,stdin);// retract

 

return num;

}

 

struct tokenType scanner(FILE* source_file)

{

struct tokenType token;

int i, index;

char ch;

 

token.number = tnull;

 

do {

while (isspace(ch= fgetc(source_file))); // state 1:

if (superLetter(ch)) {

i=0;

do {

if (i<ID_LENGTH) id[i++] = ch;

ch = fgetc(source_file);

} while (superLetterOrDigit(ch));

if (i>=ID_LENGTH) lexicalError(1);

id[i] = '\0';

ungetc(ch, stdin); // retract

 

// find the identifier in the keyword table

for (index=0; index < NO_KEYWORDS; index++)

if (!strcmp(id, keyword[index])) break;

if (index < NO_KEYWORDS)// fount, keyword exit

token.number = tnum[index];

else {// not found, identifier exit

token.number = tident;

strcpy(token.value.id, id);

}

} // end of identifier or keyword

 

else if (isdigit(ch) || ch == '.') { // IntNum, RealNum Check

 

if(numCheck(ch, source_file) == 0){ // IntNum

token.number = tnumber;

token.value.num = getIntNum(ch, source_file);

}

else{ // RealNum

token.number = tfnumber;

token.value.fnum = getRealNum(ch, source_file);

}

}

 

else switch (ch) {// special character

 

case '/' : // state 10

ch = fgetc(source_file);

if (ch == '*')// text comment

do {

while (ch != '*') ch = fgetc(source_file);

ch = fgetc(source_file);

} while (ch != '/');

else if (ch == '/')// line comment

while (fgetc(source_file) != '\n');

else if (ch == '=') token.number = tdivAssign;

else { token.number = tdiv;

ungetc(ch, stdin); // retract

}

break;

 

case '!' :// state 17

ch = fgetc(source_file);

if (ch == '=') token.number = tnotequ;

else { token.number = tnot;

ungetc(ch, stdin);// retract

}

break;

 

case '%' :// state 20

ch = fgetc(source_file);

if (ch == '=')

token.number = tmodAssign;

else {

token.number = tmod;

ungetc(ch, stdin);

}

break;

 

case '&' :// state 23

ch = fgetc(source_file);

if (ch == '&') token.number=tand;

else { lexicalError(2);

ungetc(ch, stdin);// retract

}

break;

 

case '*' :// state 25

ch = fgetc(source_file);

if (ch == '=') token.number = tmulAssign;

else { token.number = tmul;

ungetc(ch, stdin);// retract

}

break;

 

case '+' :// state 28

ch = fgetc(source_file);

if (ch == '+') token.number = tinc;

else if (ch == '=') token.number = taddAssign;

else { token.number = tplus;

ungetc(ch, stdin);// retract

}

break;

 

case '-' :// stats 32

ch = fgetc(source_file);

if (ch == '-') token.number = tdec;

else if (ch == '=') token.number = tsubAssign;

else { token.number = tminus;

ungetc(ch, stdin);// retract

}

break;

 

case '<' :// state 36

ch = fgetc(source_file);

if (ch == '=') token.number = tlesse;

else { token.number = tless;

ungetc(ch, stdin);// retract

}

break;

 

case '=' :// state 39

ch = fgetc(source_file);

if (ch == '=') token.number = tequal;

else { token.number = tassign;

ungetc(ch, stdin);// retract

}

break;

 

case '>' :// state 42

ch = fgetc(source_file);

if (ch == '=') token.number = tgreate;

else { token.number = tgreat;

ungetc(ch, stdin);// retract

}

break;

 

case '|' :// state 45

ch = fgetc(source_file);

if (ch =='|') token.number = tor;

else { lexicalError(3);

ungetc(ch, stdin);// retract

}

break;

 

case '(' : token.number = tlparen;break;

case ')' : token.number = trparen;break;

case ',' : token.number = tcomma;break;

case ';' : token.number = tsemicolon;break;

case '[' : token.number = tlbracket; break;

case ']' : token.number = trbracket; break;

case '{' : token.number = tlbrace;break;

case '}' : token.number = trbrace;break;

case EOF : token.number = teof;break;

 

default : {

printf("Current character : %c", ch);

lexicalError(4);

break;

}

 

} // switch end

} while (token.number == tnull);

return token;

} // end of scanner

 

void main(int argc, char *argv[])

{

FILE *source_file;

int i;

struct tokenType token;

 

if (argc != 2) {

fprintf(stderr, "Usage : scanner <source file name>\n");

exit(1);

}

 

if((source_file = fopen(argv[1], "r")) == NULL) {

fprintf(stderr, "%s file not found \n", argv[1]);

exit(-1);

}

 

do {

for(i=0; i<ID_LENGTH; i++)

id[i]=' ';

token = scanner(source_file);

fprintf(stdout, "Token ---> ");

 

if(token.number == 5) { // integer constant

for(i=0; i<ID_LENGTH; i++)

fprintf(stdout, "%c", id[i]);

fprintf(stdout, ": (%d, %d)\n", token.number, token.value.num);

}

else if(token.number == 6) { // real number

for(i=0; i<ID_LENGTH; i++)

fprintf(stdout, "%c", id[i]);

fprintf(stdout, ": (%d, %f)\n", token.number, token.value.fnum);

}

else if(token.number == 4) {

for (i=0; i<ID_LENGTH; i++)

fprintf(stdout, "%c", id[i]);

fprintf(stdout, ": (%d, %s)\n", token.number, token.value.id);

}

else {

for (i=0; i<ID_LENGTH; i++)

fprintf(stdout, "%c", id[i]);

fprintf(stdout, ": (%d, 0)\n", token.number);

}

} while (!feof(source_file));

fclose(source_file);

}