在简单的词法分析器中将字符作为字符串

时间:2014-03-31 19:11:00

标签: c string pointers char lexical

我试图在C中实现一个简单的词法分析器。我的问题是关于字符和字符串。通常在我的链表插入中,我将char作为参数。但是在关键字的情况下,因为它们在打印时是字符串,所以我遇到了问题:

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define MAX 50

char token[MAX];
char ch, str[25];

//Structure definition for lexemes
struct lexeme{
    char lexemes;
    char tokenclass[MAX];
    struct lexeme *next;
};

typedef struct lexeme lexeme;

lexeme *firstPtr = NULL;
lexeme *lastPtr = NULL;

//This method is for inserting the values into linked list.
void insert(char s, char *t){

    lexeme *np;
    np = malloc(sizeof(lexeme));
    np->lexemes = s;
    strcpy(np->tokenclass, t);
    np->next = NULL;

    if (firstPtr == NULL){
        firstPtr = np;
    }
    else{
        lastPtr->next = np;
    }
    lastPtr = np;
}
/*void insert_key(char *kyw, char *t){
    lexeme *kp;
    kp = malloc(sizeof(lexeme));
    kp->lexemes

}*/

void keyw(char *p);
int i = 0;

//Array of keywords
char keys[12][10] = { "break", "char", "continue",
"double", "else", "end", "for", "if", "int", "return", "void", "while" };

int main() {


    char seps[13] = " \n,;(){}[]\"";
    char oper[] = "!%^&*-+=~|.<>/?";
    int j;
    //char fname[200];
    FILE *f1;
    //clrscr();
    fopen_s(&f1, "input.txt", "r");

    if (f1 == NULL)
    {
        printf("file not found");
    }

    while ((ch = fgetc(f1)) != EOF)
    {

        for (j = 0; j <= 14; j++)
        {
            if (ch == oper[j])
            {
                printf("%c is an operator\n", ch);
                strcpy(token, "operator");
                insert(ch, token);
                str[i] = '\0';
                keyw(str);
            }
        }
        for (j = 0; j <= 12; j++)
        {
            /*  if(i==-1)
            break;*/
            if (ch == seps[j])
            {
                // if(strcmp(ch,"==") || strcmp(ch,"<=") || strcmp(ch,">=") || strcmp(ch,"<")|| strcmp(ch,">") || strcmp(ch,"?="))
                // printf("%s is a logical operator",ch);

                str[i] = '\0';
                keyw(str);
            }
        }
        if (i != -1)
        {
            str[i] = ch;
            i++;
        }
        else
            i = 0;
    }
    printf("(");
    while (firstPtr != NULL){

        printf("%c,", firstPtr->lexemes);
        printf("%s |", firstPtr->tokenclass);
    //printf("---- %c,%s ---- \n", firstPtr->next->lexemes, firstPtr->next->tokenclass);
    firstPtr = firstPtr->next;
    }
    printf(")");
    printf("\n");
    printf("\n");

    system("pause");
    return 1;

}

void keyw(char *p)
{
    int k, flag = 0;
    for (k = 0; k <= 11; k++)
    {
        if (strcmp(keys[k], p) == 0)
        {
            printf("%s is a keyword\n", p);
            strcpy(token, "keyword");
            insert(p[0], token);
            flag = 1;
            break;
        }
    }
    if (flag == 0)
    {
        if (isdigit(p[0]))
        {
            printf("%s is a number\n", p);
            strcpy(token, "number");
            insert(p[0], token);
        }
        else
        {

            if (p[0] != '\0')
            {
                printf("%s is an identifier\n", p);
                strcpy(token, "id");
                insert(p[0], token);
            }
        }
    }
    i = -1;
}

我的输入是:

 int a=5;
 int b=3;
 int c;
 if(a>b){
 c=7;
 b=c+a;
 end
 }

通常我会得到这样的输出:

<i,keyword |=,operator |>,operator |a,id |5,number |i,keyword |=,operator |b,id |3,number |i, keyword |c,id | .... and so on.

我知道在关键字的情况下我不应该给 p [0] 。我还检查了我的结构定义,并将 char lexemes 改为 char lexemes [] ,但是我遇到了一些错误。我试图找到适当的str类C但我不能。 我希望我的输出像:

( int,keyword )  (i,keyword) instead

那你有什么建议?我该怎么做才能实现它?

1 个答案:

答案 0 :(得分:1)

我的建议:关键字另存为数字。

注册部分

    if (strcmp(keys[k], p) == 0)
    {
        printf("%s is a keyword\n", p);
        strcpy(token, "keyword");
        insert(k, token);//insert(p[0], token);
        flag = 1;
        break;
    }

打印部分

    if(firstPtr->lexemes < 12)
        printf("%s,", keys[firstPtr->lexemes]);
    else
        printf("%c,", firstPtr->lexemes);
    printf("%s |", firstPtr->tokenclass);