// Lex.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <process.h>

//P83 3.4.2保留字和标识符的识别
//初始化时就将各个保留字填入符号表中
const char* KEYWORD[6] = {"begin", "if", "then", "while", "do", "end"};
char buffer[1024] = {0};//输入缓冲区
char token[10] = {0};//词素,数组大小限制着标识符的长度。
int forward = 0, syn = -1;//游标和种别码

void analyzer();

int main(int argc, char* argv[])
{
 //输入,以#结束。
 printf("请输入:(示例输入begin x:=9;if x>0 then x:=2*x+1/3;end#)\n");
 char input;
 do
 {
  input = getchar();
  buffer[forward++] = input;
 }
 while(input != '#');

 //分析,以#的种别码0结束。
 forward = 0;
 do
 {
  analyzer();
  printf("(%d, %s)\n", syn, token);
 }
 while(syn != 0);
 system("pause");
 return 0;
}

void analyzer()
{
 memset(token, '\0', sizeof(token));//清空前一个已分析的词素
 char ch = buffer[forward++];//当前分析的字符
 while(isspace(ch))//忽略空格
  ch = buffer[forward++];
 switch(ch)
 {
  case '+':
   token[0] = ch;
   syn = 13;
   return;
  case '-':
   token[0] = ch;
   syn = 14;
   return;
  case '*':
   token[0] = ch;
   syn = 15;
   return;
  case '/':
   token[0] = ch;
   syn = 16;
   return;
  case ':':
   token[0] = ch;
   if(buffer[forward] == '=')
   {
    forward++;
    token[1] = '=';
    syn = 18;
   }
   else
    syn = 17;
   return;
  case '<':
   token[0] = ch;
   if(buffer[forward] == '>')
   {
    forward++;
    token[1] = '>';
    syn = 21;
   }
   else if(buffer[forward] == '=')
   {
    forward++;
    token[1] = '=';
    syn = 22;
   }
   else
    syn = 20;
   return;
  case '>':
   token[0] = ch;
   if(buffer[forward] == '=')
   {
    forward++;
    token[1] = '=';
    syn = 24;
   }
   else
    syn = 23;
   return;
  case '=':
   token[0] = ch;
   syn = 25;
   return;
  case ';':
   token[0] = ch;
   syn = 26;
   return;
  case '(':
   token[0] = ch;
   syn = 27;
   return;
  case ')':
   token[0] = ch;
   syn = 28;
   return;
  case '#':
   token[0] = ch;
   syn = 0;
   return;
  default:
   int i = 0;
   if(isdigit(ch))//数字
   {
    while(isdigit(ch))
    {
     token[i] = ch;
     ch = buffer[forward++];
     i++;
    }
    forward--;
    syn = 11;
    return;
   }
   else if(isalpha(ch))//字符组成保留字或标识符
   {
    while(isalnum(ch))
    {
     token[i] = ch;
     ch = buffer[forward++];
     i++;
    }
    forward--;
    for(int j = 0; j < 6; j++)
    {
     if(strcmp(token, KEYWORD[j]) == 0)
     {
      syn = j + 1;
      return;
     }
    }
    syn = 10;
    return;
   }
 }
}