小C语言--词法分析程序

小C语言文法 
1. <程序>→(){<声明序列><语句序列>}
2. <声明序列>→<声明序列><声明语句>|<声明语句>|<空>
3. <声明语句>→<标识符表>;
4. <标识符表>→<标识符>,<标识符表>|<标识符>
5. <语句序列>→<语句序列><语句>|<语句>
6. <语句>→< if语句>|< while语句>|< for语句>|<复合语句>|<赋值语句>

7. < if语句>→< if关键字>(<表达式>)<复合语句>|(<表达式>)<复合语句>< else关键字><复合语句>
8. < while语句>→< while关键字>(<表达式>)<复合语句>
9. < for语句>→< for关键字>(<表达式>;<表达式>;<表达式>)<复合语句>
10. <复合语句>→{<语句序列>}
11. <赋值语句>→<表达式>;
12. <表达式>→<标识符>=<算数表达式>|<布尔表达式>
13. <布尔表达式>→<算数表达式> |<算数表达式><关系运算符><算数表达式>
14. <关系运算符>→>|<|>=|<=|==|!=
15. <算数表达式>→<算数表达式>+<项>|<算数表达式>-<项>|<项>
16. <项>→<项>*<因子>|<项>/<因子>|<因子>
17. <因子>→<标识符>|<无符号整数>|(<算数表达式>)
18. <标识符>→<字母>|<标识符><字母>|<标识符><数字>
19. <无符号整数>→<数字>|<无符号整数><数字>
20. <字母>→a|b|…|z|A|B|…|Z
21. <数字>→0|1|2|3|4|5|6|7|8|9

22. < main关键字>→main
23. < if关键字>→if
24. < else关键字>→else
25. < for关键字>→for
26. < while关键字>→while
27. < int关键字>→int


小C语言文法如上,现在我们对小C语言写的一个源程序进行词法分析,分析出关键字、自定义标识符、整数、界符
和运算符。
关键字:main if else for while int
自定义标识符:除关键字外的标识符
整数:无符号整数
界符:{ } ( ) , ;
运算符:= + - * / < <= > >= == !=


/*************************************************************************
    > File Name: lexer.cc
    > Author: 
    > Mail: 
    > Function: 
    > Remark: 
    > Created Time: 2017年11月28日 星期二 08时53分08秒
    > Last Modified: 2017年11月28日 星期二 08时53分08秒
 ************************************************************************/

#include <iostream>
#include <map>
#include <cstring>
#include <cstdlib>
using namespace std;
#define BUFLEN  100
static bool file = true;
int lineLen = 0;
int readPos = -1;
char buffer[BUFLEN];
char lastch = '0';

class Scanner
{
    public:
        char scan();
        void back();
};

char 
Scanner::scan()
{
    if (readPos == lineLen-1) {
        cin.getline(buffer, BUFLEN);
        lineLen = strlen(buffer);
        if (lineLen == 0) {
            lineLen = 1;
            buffer[0] = -1;
        }
        readPos = -1;
    }

    readPos ++;
    char ch = buffer[readPos];
    return ch;
}

void 
Scanner::back()
{
    readPos --;
}

enum Tag
{
    KEY, BOU, IDE, OPE, INT
};

class Boundary
{
    public :
        map<string, Tag> boundaries;
        Boundary();
        Tag getTag(string name);
};

Boundary::Boundary()
{
    boundaries["("] = BOU;
    boundaries[")"] = BOU;
    boundaries["{"] = BOU;
    boundaries["}"] = BOU;
    boundaries[";"] = BOU;
    boundaries[","] = BOU;
}
Tag 
Boundary::getTag(string name)
{
    return boundaries.find(name) != boundaries.end() ? boundaries[name] : OPE;
}

class Keyword
{
    public :
        map<string, Tag> keywords;
        Keyword();
        Tag getTag(string name);
};

Keyword::Keyword()
{
    keywords["main"] = KEY;
    keywords["if"] = KEY;
    keywords["else"] = KEY;
    keywords["int"] = KEY;
    keywords["while"] = KEY;
    keywords["for"] = KEY;
}

Tag
Keyword::getTag(string name)
{
    return keywords.find(name) != keywords.end() ? keywords[name] : IDE;
}


class Lexer
{
    public :
        bool scan(char);
        void lexer();
};

bool 
Lexer::scan(char need=0)
{
    Scanner *S = new Scanner();
    char ch = S -> scan();
    if (need) {
        if (ch!=need) {
            S -> back();
            return false;
        }
        return true;
    }
    return true;
}

void
Lexer::lexer()
{
    Scanner *S = new Scanner();
    char ch;
    do 
    {
        ch = S -> scan();
        if (isalpha(ch)) {
            string name = "";
            do {
                name += ch;
                ch = S -> scan();
            }while(isalpha(ch)||isalnum(ch));
            S -> back();
            if (name != "") {
                Keyword *K = new Keyword();
                Tag t = K -> getTag(name);
                if (t == IDE) {
                    cout << "(identifier," << name << ')' << endl;
                } else {
                    cout << "(keyword," << name << ')' << endl;
                }
            }
        } else if(isalnum(ch)) {
            int val = 0;
            if (ch != '0') {
                do 
                {
                    val = val*10+ch-'0';
                    ch = S -> scan();
                }while(isalnum(ch));
                S -> back();
                cout << "(integer," << val << ')' << endl;
            } else {
                cout << "(integer," << val << ')' << endl;
            }
        } else {
            Lexer *L = new Lexer();
            string name = "";
            switch(ch) {
                case '+': 
                case '-': 
                case '*': 
                case '/': 
                case '(': 
                case ')': 
                case '{': 
                case '}': 
                case ',': 
                case ';': name+=ch; break;
                case '>': L->scan('=') ? name+=">=" : name+=ch; break;
                case '<': L->scan('=') ? name+="<=" : name+=ch; break;
                case '=': L->scan('=') ? name+="==" : name+=ch; break;
                case '!': L->scan('=') ? name+="!=" : name+=ch; break;
            }
            if (name != "") {
                Boundary *B = new Boundary();
                Tag t = B -> getTag(name);
                if (t == BOU) {
                    cout << "(boundary," << name << ')' << endl;
                } else {
                    cout << "(operator," << name << ')' << endl;
                }
            }
        }
    }while(ch != -1);
}
int main(int argc,char *argv[])
{
    Lexer *L = new Lexer();
    L->lexer();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值