1

私は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 語彙素char lexemes[]にしましたが、いくつかのエラーが発生しました。C の適切な str クラスを見つけようとしましたが、できませんでした。次のような出力が必要です。

( int,keyword )  (i,keyword) instead

それで、あなたは何を提案しますか?それを達成するにはどうすればよいですか?

4

1 に答える 1

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);
于 2014-04-01T01:14:57.310 に答える