2014-03-25 3 views
1

나는 C로 작성한 간단한 어휘 분석기에 부동 소수점 기능을 추가하려고한다. 필자는이 방법에 대한 아이디어를 가지고 있지만, 모두 Parse 정수 리터럴에 if 문을 추가하는 등 불완전한 솔루션이지만 while 문 때문에 기간을 마침표로 계산합니다. 나는 while 문에 OR을 추가하는 것에 대해 생각했지만, 기간 만 지정하는 방법을 완전히 모르겠습니다.C 어휘 분석기에 float 구문 분석 기능을 추가하려면 어떻게해야합니까?

/* front.c */ 
#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 
#include <conio.h> 
/*Global Declarations */ 
/*variables*/ 
int charClass; 
char lexeme [100]; 
char nextChar; 
int lexLen; 
int token; 
int nextToken; 
FILE *in_fp, *fopen(); 

/*function declarations*/ 
void addChar(); 
void getChar(); 
void getNonBlank(); 
int lex(); 

/*Character classes */ 
#define LETTER 0 
#define DIGIT 1 
#define UNKNOWN 99 

/*token codes*/ 
#define INT_LIT 10 
#define FLOAT 
#define IDENT 11 
#define ASSIGN_OP 20 
#define ADD_OP 21 
#define SUB_OP 22 
#define MULT_OP 23 
#define DIV_OP 24 
#define LEFT_PAREN 25 
#define RIGHT_PAREN 26 
#define MOD_OP 27 
#define SEMICOL 28 
#define COMMA 29 
#define EXCLAMATION_MARK 30 
#define AT_SIGN 31 
#define POUND_SIGN 32 
#define DOLLAR_SIGN 33 
#define CARAT_SIGN 34 
#define AMPERSAND 35 
#define PERIOD_MARK 36 
#define LESSTHAN_SIGN 37 
#define GREATERTHAN_SIGN 38 

#define QUESTION_MARK 39 
#define LEFT_SQUAREBRACKET 40 
#define RIGHT_SQUAREBRACKET 41 
#define LEFT_CURLYBRACKET 42 
#define RIGHT_CURLYBRACKET 43 
#define BACKSLASH 44 
#define VERTICALBAR 45 

#define SINGLE_QUOTE 46 

#define DOUBLE_QUOTE 47 
#define COLON 48 

#define UNDERSCORE 49 
#define TILDE 50 
#define GRAVE_ACCENT 51 




/*********************/ 
/*main driver */ 
main() 
{ 
/*Open the input data file and process its contents*/ 
    if ((in_fp = fopen("front.in", "r")) == NULL) 
     printf("ERROR - cannot open front.in \n"); 
    else 
    { 
     getChar(); 
     do 
     { 
      lex(); 
     } while (nextToken != EOF); 
    } 
} 

/***************************/ 
/*lookup - a function to lookup operators and parentheses 
     and return the token */ 
int lookup(char ch) 
{ 
    switch (ch) 
    { 
     case '=': 
      addChar(); 
      nextToken = ASSIGN_OP 
      break; 

     case '(': 
      addChar(); 
      nextToken = LEFT_PAREN; 
      break; 

     case ')': 
      addChar(); 
      nextToken = RIGHT_PAREN; 
      break; 

     case '+': 
      addChar(); 
      nextToken = ADD_OP; 
      break; 

     case '-': 
      addChar(); 
      nextToken = SUB_OP; 
      break; 

     case '*': 
      addChar(); 
      nextToken = MULT_OP; 
      break; 

     case '/': 
      addChar(); 
      nextToken = DIV_OP; 
      break; 

     case '%': 
      addChar(); 
      nextToken = MOD_OP; 
      break; 

     case ';': 
      addChar(); 
      nextToken = SEMICOL; 
      break; 

     case ':': 
      addChar(); 
      nextToken = COLON; 
      break; 

     case '"': 
      addChar(); 
      nextToken = DOUBLE_QUOTE; 
      break; 

     case ',': 
      addChar(); 
      nextToken = COMMA; 
      break; 

     case '.': 
      addChar(); 
      nextToken = PERIOD_MARK; 
      break; 

     case '!': 
      addChar(); 
      nextToken = EXCLAMATION_MARK; 
      break; 

     case '@': 
      addChar(); 
      nextToken = AT_SIGN; 
      break; 

     case '#': 
      addChar(); 
      nextToken = POUND_SIGN; 
      break; 

     case '$': 
      addChar(); 
      nextToken = DOLLAR_SIGN; 
      break; 

     case '^': 
      addChar(); 
      nextToken = CARAT_SIGN; 
      break; 

     case '&': 
      addChar(); 
      nextToken = AMPERSAND; 
      break; 

     case '<': 
      addChar(); 
      nextToken = LESSTHAN_SIGN; 
      break; 

     case '>': 
      addChar(); 
      nextToken = GREATERTHAN_SIGN; 
      break; 

     case '?': 
      addChar(); 
      nextToken = QUESTION_MARK; 
      break; 

     case '[': 
      addChar(); 
      nextToken = LEFT_SQUAREBRACKET; 
      break; 

     case ']': 
      addChar(); 
      nextToken = RIGHT_SQUAREBRACKET; 
      break; 

     case '{': 
      addChar(); 
      nextToken = LEFT_CURLYBRACKET; 
      break; 

     case '}': 
      addChar(); 
      nextToken = RIGHT_CURLYBRACKET; 
      break; 

     case '\'': 
      addChar(); 
      nextToken = SINGLE_QUOTE; 
      break;* 

     case '|': 
      addChar(); 
      nextToken = VERTICALBAR; 
      break; 

     case '_': 
      addChar(); 
      nextToken = UNDERSCORE; 
      break; 

     case '~': 
      addChar(); 
      nextToken = TILDE; 
      break; 

     case '`': 
      addChar(); 
      nextToken = GRAVE_ACCENT; 
      break; 

     case '\\': 
      addChar(); 
      nextToken = BACKSLASH; 
      break; 

     default: 
      addChar(); 
      nextToken = EOF; 
      break; 
    } 
    return nextToken; 
} 

/*****************************/ 
/* addChar = a function to add nextChar to lexeme */ 
void addChar() 
{ 
    if (lexLen <= 98) 
    { 
     lexeme[lexLen++] = nextChar; 
     lexeme[lexLen] = 0; 
    } 
    else 
     printf("Error - lexeme is too long \n"); 
} 

/**********************************/ 
/* getChar- a function to get the next character of 
      input and determine its character class */ 
void getChar() 
{ 
    if ((nextChar = getc(in_fp)) != EOF) 
    { 
     if (isalpha(nextChar)) 
      charClass = LETTER; 
     else if (isdigit(nextChar)) 
       charClass = DIGIT; 
      else charClass = UNKNOWN; 
    } 
    else 
     charClass = EOF; 
} 

/********************************************/ 
/* getNonBlank - a function to call getChar until it 
        returns a non-whitespace character */ 
void getNonBlank() 
{ 
    while (isspace(nextChar)) 
     getChar(); 
} 

/*******************************/ 
/* lex - a simple lexical analyzer for arithmetic 
     expressions */ 
int lex() 
{ 
    lexLen = 0; 
    getNonBlank(); 
    switch (charClass) 
    { 
    /*Parse identifiers */ 
     case LETTER: 
      addChar(); 
      getChar(); 
      while (charClass == LETTER || charClass == DIGIT) 
      { 
       addChar(); 
       getChar(); 
      } 
     nextToken = IDENT; 
     break; 


/*Parse integer literals and ?Floats?*/ 
     case DIGIT: 
      addChar(); 
      getChar(); 
      while (charClass == DIGIT) 
      { 
       addChar(); 
       getChar(); 
      } 
      nextToken = INT_LIT; 
      break; 

/*Parentheses and operators*/ 
     case UNKNOWN: 
      lookup(nextChar); 
      getChar(); 
      break; 

/*EOF*/ 
     case EOF: 
      nextToken = EOF; 
      lexeme[0] = 'E'; 
      lexeme[1] = 'O'; 
      lexeme[2] = 'F'; 
      lexeme[3] = 0; 
      break; 
    }/*End of switch*/ 
    printf("Next token is: %d, Next lexeme is %s\n", 
     nextToken, lexeme); 
    return nextToken; 
} /*End of function lex*/ 

내가 "== charClass.ch '.'"같은 것을 사용 어쩌면 경우 while 문에 ||를 통해의 연장 "charClass == DIGIT"로 그 생각을했다 : 여기에 코드입니다 (또는),하지만 나는 다른 언어와 섞여 있거나 잘못하고 있다고 생각합니다. 나는 그럴 수는 없지만이 프로그램을 현재 제대로 테스트하는 것은 어렵습니다.

/*Parse integer literals and ?Floats?*/ 
    case DIGIT: 
     addChar(); 
     getChar(); 
     while (charClass == DIGIT) 
     { 
      addChar(); 
      getChar(); 
     } 
     nextToken = INT_LIT; 
     break; 
+2

난 당신이 당신이 도움이 필요한 비트에 코드 샘플을 잘라 제안 할 수 있음 ... 나는이 모든 것을 읽으려고 익사하고있다. – Floris

+2

'flex (1)'과 같은 도구를 사용하지 않는 이유는 무엇입니까? – vonbrand

+0

'char nextChar;'int nextChar; – chux

답변

1
/*Parse integer literals and ?Floats?*/ 
    case DIGIT: 
     addChar(); 
     getChar(); 
     while (charClass == DIGIT) 
     { 
      addChar(); 
      getChar(); 
     } 

이 시점에서 이미 nextChar가 무엇인지 :

여기에 내가 플로트 얻을 변경할 필요가 있다고 생각 특정 부분입니다. 이 점이 있다면, 그것은 모든 다음 숫자를 소비하는 몇 가지 더 많은 코드를 작성하고 FLOAT_LIT.-nextToken 그렇지 않으면이로 넘어 설정 :

 nextToken = INT_LIT; 
     break; 
+0

내가 이해할 지 모르겠다. "while (charClass == DIGIT || charClass.ch == '." " – cluemein

+0

도움이되었지만 그다지 도움이되지 못했습니다. 어쨌든. – cluemein

+0

당신은' 'on'while 'on'을 원한다면, 그 중 하나만 허용하고 싶을 것입니다. 실제로 실제 코드가 아닌, 답에 더 많은 것을 필요로 할 수 있는지를보기가 어렵습니다. – EJP

관련 문제