C语言实现的词法分析器

来源:互联网 发布:net use网络命令的使用 编辑:程序博客网 时间:2024/04/28 07:31
 #ifndef MYLEX_H
02#define MYLEX_H
03  
04#include <stdio.h>
05#include <stdlib.h>
06#include <ctype.h>
07#include <string.h>
08#include <time.h>
09  
10#define MAX_ID 20
11  
12typedef enum SYMBOL {
13    nul, eof, plus, minus, times, slash, lparen, rparen, comma, semicolon, period, becomes,
14    eql, neq, lss, gtr, leq, geq, number, ident,
15    beginsym, callsym, constsym, dosym, endsym, ifsym, oddsym, proceduresym, readsym, thensym, varsym, whilesym, writesym
16} SYMBOL;
17  
18int read_ch();
19int put_back(int);
20SYMBOL getsym();
21int w2f(int);
22  
23int find_tab(char *);
24SYMBOL get_data(int);
25int error();
26  
27#endif

[文件] symbol.c ~ 4KB    下载(21)

view source
print?
001#include "mylex.h"
002  
003extern FILE *source, *out;
004  
005const char *symtype[33] = {
006    "nul","eof", "plus","minus", "times","slash", "lparen","rparen", "comma","seicolon", "period", "becomes",
007    "eql","neq", "lss","gtr", "leq","geq", "number","ident",
008    "beginsym","callsym", "consysym", "dosym","endsym", "ifsym","oddsym", "proceduresym","readsym", "thensym", "varsym","whilesym", "writesym"
009};
010  
011int cur_line, cur_col, err_line, err_col;
012int num;
013char id[21] = "\0";
014int id_len;
015int token_num;
016  
017int read_ch() {
018    intch = fgetc(source);
019    cur_col++;
020    if(ch == '\n') {
021        cur_line++;
022        cur_col = 0;
023    }
024    returnch;
025}
026  
027int put_back(int ch) {
028    ungets(ch, source);
029    cur_col--;
030    if(ch == '\n')
031        cur_line--;
032    return0;
033}
034  
035SYMBOL getsym() {
036    intch;
037    intiskeywords;
038    charinvalid[2] = "\0";
039    while((ch = read_ch()) != EOF && ch <= ' ')
040        ;
041    err_line = cur_line;
042    err_col = cur_col;
043    switch(ch) {
044        caseEOF :
045            strcpy(id,"EOF");
046            returneof;
047        case'+' :
048            strcpy(id,"+");
049            returnplus;
050        case'-' :
051            strcpy(id,"-");
052            returnminus;
053        case'*' :
054            strcpy(id,"*");
055            returntimes;
056        case'/' :
057            strcpy(id,"/");
058            returnslash;
059        case'(' :
060            strcpy(id,"(");
061            returnlparen;
062        case')' :
063            strcpy(id,")");
064            returnrparen;
065        case',' :
066            strcpy(id,",");
067            returncomma;
068        case';' :
069            strcpy(id,";");
070            returnsemicolon;
071        case'.' :
072            strcpy(id,".");
073            returnperiod;
074        case':' :
075            ch = read_ch();
076            if(ch == '=') {
077                strcpy(id,":=");
078                returnbecomes;
079            }else
080                returnnul;
081        case'=' :
082            strcpy(id,"=");
083            returneql;
084        case'#' :
085            strcpy(id,"#");
086            returnneq;
087        case'<' :
088            ch = read_ch();
089            if(ch == '=') {
090                strcpy(id,"<=");
091                returnleq;
092            }
093            put_back(ch);
094            strcpy(id,"<");
095            returnlss;
096        case'>' :
097            ch = read_ch();
098            if(ch == '=') {
099                strcpy(id,">=");
100                returngeq;
101            }
102            put_back(ch);
103            strcpy(id,">");
104            returngtr;
105        default:
106            if(isdigit(ch)) {
107                num = 0;
108                do{
109                    num = 10 * num + ch -'0';
110                    ch = read_ch();
111                }while (ch != EOF &&isdigit(ch));
112                _itoa(num, id, 10);
113                if(isslpha(ch)) {
114                    invalid[0] = (char)ch;
115                    strcat(id, invalid);
116                    ch = read_ch();
117                    while(isalnum(ch)) {
118                        invalid[0] = (char) ch;
119                        strcat(id, invalid);
120                        ch = read_ch();
121                    }
122                    error();
123                    returnnul;
124                }
125                put_back(ch);
126                returnnumber;
127            }
128            if(isalpha(ch)) {
129                id_len = 0;
130                do{
131                    if(id_len < MAX_ID) {
132                        id[id_len] = (char)ch;
133                        id_len++;
134                    }
135                    ch = read_ch();
136                }while (ch != EOF &&isalnum(ch));
137                id[id_len] ='\0';
138                put_back(ch);
139                iskeywords = find_tab(id);
140                return(iskeywords == -1) ? ident : get_data(iskeywords);
141            }
142            error();
143            returnnul;
144    }
145}
146  
147int w2f(int flag) {
148    fprintf(out,"|%4d |%19s |%19s |%19s |\n",token_num, id, symtype[flag],"");
149    return0;
150}

[文件] keyword.c ~ 1KB    下载(22)

view source
print?
01#include "mylex.h"
02  
03extern FILE *out;
04extern int cur_line, cur_col, err_line, err_col;
05extern int num;
06extern char id[21];
07extern int token_num;
08  
09char *keywords[13] = {
10    "begin","call", "const","do", "end","if", "odd","procedure", "read", "then","var", "while","write"
11};
12  
13int find_tab(char id[21]) {
14    inti;
15    for(i = 0; i !=13; ++i) {
16        if(!strcmp(keywords[i], id))
17            returni;
18        else
19            continue;
20    }
21    return-1;
22}
23  
24SYMBOL get_data(intNo) {
25    switch(No) {
26        case0 :
27            returnbeginsym;
28        case1 :
29            returncallsym;
30        case2 :
31            returnconstsym;
32        case3 :
33            returndosym;
34        case4 :
35            returnendsym;
36        case5 :
37            returnifsym;
38        case6 :
39            returnoddsym;
40        case7 :
41            returnproceduresym;
42        case8 :
43            returnreadsym;
44        case9 :
45            returnthensym;
46        case10 :
47            returnvarsym;
48        case11 :
49            returnwhilesym;
50        case12 :
51            returnwritesym;
52        default:
53            error(">>> Error : ");
54            returnnul;
55    }
56}
57  
58int error() {
59    fprintf(out,"|%4d |%19s |%19s %19s |\n", token_num, id,"nul", "invalid character");
60    return0;
61}

[文件] main.c ~ 2KB    下载(22)

view source
print?
01#include "mylex.h"
02  
03extern int cur_line, cur_col, err_line, err_col;
04extern char id[21];
05extern int token_num;
06  
07FILE *source, *out;
08  
09int main() {
10    clock_tstart, finish;
11    doubleduration;
12    charfilename[21] = "\0";
13    charoutname[21] = "\0";
14    intflag;
15    FILE*stream;
16    charline[100];
17    printf("PL/0 Lexical Analyzer\n\n");
18    printf("Please enter the source file: ");
19    gets_s(filename, 20);
20    if((source = fopen(filename,"r")) == NULL) {
21        printf("Error: the file \"%s\" can not be opened, press any key to exit\n", filename);
22        _getch();
23        return1;
24    } else {
25        inti;
26        start =clock();
27        for(i = 0; i < (int)strlen(filename) - 4; ++i)
28            outname[i] = filename[i];
29        strcat(outname,".out");
30        if((out = fopen(outname,"w+")) == NULL) {
31            printf("Error: can not create \"%s\" in current path, press any key to exit\n", outname);
32            _getch();
33            return1;
34        }
35        cur_line = 1;
36        cur_col = 0;
37        token_num = 0;
38        fprintf(out,"+-----+--------------------+--------------------+--------------------+\n");
39        fprintf(out,"|%4s |%19s |%19s |%19s |\n","No", "Symbol","Symbol Type", "Notes");
40        fprintf(out,"+-----+--------------------+--------------------+--------------------+\n");
41        while(!feof(source)) {
42            token_num++;
43            flag = getsym();
44            if(flag == 0)
45                continue;
46            w2f(flag);
47        }
48        fprintf(out,"+-----+--------------------+--------------------+--------------------+\n");
49        fcloseall();
50        stream =fopen(outname,"r");
51        while(1) {
52            fgets(line, 100, stream);
53            if(feof(stream))
54                break;
55            else
56                printf("%s", line);
57        }
58        fclose(stream);
59        finish =clock();
60        duration = (double)(finish - start) / CLOCKS_PER_SEC;
61        printf("completed successfully. (%2.3f secs)\n", duration);
62    }
63    return0;
}
原创粉丝点击