2012-02-08 13 views
2

教授は公式言語理論で私のコースのチューリングマシンを勉強していますが、教授は "TM"の背後にある論理を詳細に見るために次のように実行することを推奨しましたが、コンパイルしようとすると、次のエラーが表示されます。ここチューリングマシンの実装をC

C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `Tape* insert_tape(Tape*, Direction, char)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|44|error: invalid conversion from `void*' to `Tape*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `Tape* create_tape(char*)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|68|error: invalid conversion from `void*' to `Tape*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `Transition* get_transition(char*)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|80|error: invalid conversion from `void*' to `Transition*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `List* insert_list(List*, char*)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|93|error: invalid conversion from `void*' to `List*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `List* insert_list_transition(List*, Transition*)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|105|error: invalid conversion from `void*' to `List*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c||In function `TM* createTM(char*)':| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|166|error: invalid conversion from `void*' to `TM*'| 
C:\Documents and Settings\Melkhiah.EQUIPO01\Mis documentos\Downloads\Tarea3 Discretas\TM.c|167|error: invalid conversion from `void*' to `List*'| 
||=== Build finished: 7 errors, 0 warnings ===| 

はコードです:

/* This C file implements a Non-determinitic Pushdown Automata 
* author: Kevin Zhou 
* Computer Science and Electronics 
* University of Bristol 
* Date: 21st April 2010 
*/ 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

typedef struct tapes { 
    struct tapes *left; 
    struct tapes *right; 
    char content; 
} Tape; 

typedef enum { LEFT,RIGHT } Direction; 

typedef struct transition { 
    char current_state; 
    char tape_symbol; 
    char new_state; 
    char new_tape_symbol; 
    Direction dir; 
} Transition; 

typedef struct list { 
    Transition *content; 
    struct list *next; 
} List; 

typedef struct tm { 
    char *input_alpha; 
    char *input; 
    char *tape_alpha; 
    char start; 
    char accept; 
    char reject; 
    List *transition; 
} TM; 

Tape *insert_tape(Tape *t, Direction dir, char c) { 
    Tape *head = t; 
    Tape *new1 = calloc(1,sizeof(Tape));; 
    new1 -> content = c; 
    if(dir == LEFT) { 
     while(t->left != NULL) { 
      t = t->left; 
     } 
     new1->right = t; 
     new1->left = NULL; 
     t->left = new1; 
     return new1; 
    } 
    if(dir == RIGHT) { 
     while(t->right != NULL) { 
      t = t->right; 
     } 
     new1->left = t; 
     new1->right = NULL; 
     t->right = new1; 
    } 
    return head; 
} 

Tape *create_tape(char *input) { 
    int i=1; 
    Tape *t = calloc(1,sizeof(Tape)); 
    t->content = input[0]; 
    while(1) { 
     if(input[i] == '\0') break; 
     t = insert_tape(t,RIGHT,input[i]); 
     i++; 
    } 
    return t; 
} 

/* turn the input string into Transition fields */ 
Transition *get_transition(char *s) { 
    Transition *t = calloc(1,sizeof(Transition)); 
    Direction dir; 
    t->current_state = s[0]; 
    t->tape_symbol = s[1]; 
    t->new_state = s[2]; 
    t->new_tape_symbol = s[3]; 
    dir = (s[4]=='R')? RIGHT:LEFT; 
    t->dir = dir; 
    return t; 
} 

/* turn the string into transitions and add into list */ 
List *insert_list(List *l, char *elem) { 
    List *t = calloc(1,sizeof(List)); 
    List *head = l; 
    while(l->next!=NULL) 
     l = l->next; 
    t->content = get_transition(elem); 
    t->next = NULL; 
    l->next = t; 
    return head; 
} 

/* insert a transition into a list */ 
List *insert_list_transition(List *l, Transition *tr) { 
    List *t = calloc(1,sizeof(List)); 
    List *head = l; 
    while(l->next!=NULL) 
     l = l->next; 
    t->content = tr; 
    t->next = NULL; 
    l->next = t; 
    return head; 
} 

void print_tape(Tape *t,char blank) { 
    char c; 
    while(1) { 
     if(t->content != blank) break; 
     t= t->right; 
    } 
    while(1) { 
     if(t==NULL) break; 
     c = t->content; 
     if(t->content != blank) 
      putchar(c); 
     t= t->right; 
    } 
    putchar('\n'); 
} 

void print_transition (Transition *t) { 
    char s1[] = "Left"; 
    char s2[] = "Right"; 
    if(t==NULL) { 
     printf("NULL Transfer"); 
     return; 
    } 
    printf("current:%c tape:%c new state:%c new tape:%c direction %s\n",t->current_state,t->tape_symbol,t->new_state,t->new_tape_symbol,(t->dir == LEFT)?s1:s2); 
} 

/*test if the char c is in the string s */ 
int contains (char c, char *s) { 
    int i=0; 
    while(1) { 
     if(c== s[i]) return 1; 
     if(s[i] == '\0') return 0; 
     i++; 
    } 
} 

/* test if the input is a valid input */ 
int is_valid_input(char *input_alpha, char *input) { 
    int i=0; 
    char c; 
    while(1) { 
     c = input[i]; 
     if(c == '\0') break; 
     if(!contains(c,input_alpha)) return 0; 
     i++; 
    } 
    return 1; 
} 

TM *createTM (char *input) { 

    TM *m = calloc(1,sizeof(TM)); 
    List *tr = calloc(1,sizeof(List)); 
    char *buffer; 
    /*read input alphabet of PDA*/ 
    buffer = strtok(input,":"); 
    if(buffer == NULL) { 
     printf("Error in reading input alphabet!\n"); 
     exit(1); 
    } 
    m->input_alpha = buffer; 

    /*read tape alphabet*/ 
    buffer = strtok(NULL,":"); 

    if(buffer == NULL) { 
     printf("Error in reading tape alphabet!\n"); 
     exit(1); 
    } 
    m->tape_alpha = buffer; 

    /*read input sequence*/ 
    buffer = strtok(NULL,":"); 
    if(buffer == NULL) { 
     printf("Error in reading input sequence!\n"); 
     exit(1); 
    } 

    if(!is_valid_input(m->input_alpha,buffer)) { 
     printf("Error! Input contains some invalid characters that don't match the input alphabet!\n"); 
     exit(1); 
    } 

    m->input = buffer; 
    buffer = strtok(NULL,":"); 
    m->start = buffer[0]; 
    buffer = strtok(NULL,":"); 
    m->accept = buffer[0]; 
    buffer = strtok(NULL,":"); 
    m->reject = buffer[0]; 

    /*read tape transition*/ 
    while(1) { 
     buffer = strtok(NULL,":"); 
     if(buffer == NULL) break; 
     tr = insert_list(tr,buffer); 
    } 

    m->transition = tr->next; 
    return m; 
} 

Transition *find_transition(List * list,char state, char tape_symbol) { 
    Transition *t; 
    while(1) { 
     if(list==NULL) return NULL; 
     t = list -> content; 
     if(t->current_state == state && t->tape_symbol == tape_symbol) 
      return t; 
     list = list->next; 
    } 
} 

Tape *move(Tape *t,Direction dir, char blank) { 
    if(dir == LEFT) { 
     if(t->left==NULL) { 
      t = insert_tape(t,LEFT,blank); 
     } 
     return t->left; 
    } 
    if(dir == RIGHT) { 
     if(t->right==NULL) { 
      t = insert_tape(t,RIGHT,blank); 
     } 
     return t->right; 
    } 
    return NULL; 
} 

void simulate(TM *m) { 
    /* first symbol in input symbol used to represent the blank symbol */ 
    const char blank = m->tape_alpha[0]; 
    char current_state = m->start; 
    Tape *tape = create_tape(m->input); 
    Tape *current_tape = tape; 
    char current_tape_symbol; 
    Transition *current_transition; 
    while(1) { 
     if(current_state == m->accept) { 
      printf("Accept\n"); 
      print_tape(tape,blank); 
      break; 
     } 
     if(current_state == m->reject) { 
      printf("Reject\n"); 
      print_tape(tape,blank); 
      break; 
     } 
     current_tape_symbol = (current_tape==NULL||current_tape ->content == '\0')?blank:current_tape->content; 
     current_transition = find_transition(m->transition,current_state,current_tape_symbol); 
     current_state = current_transition -> new_state; 
     current_tape -> content = current_transition -> new_tape_symbol; 
     current_tape = move(current_tape, current_transition ->dir, blank); 
    } 
} 

int main(void) { 
    char s[300]; 
    TM *p; 
    scanf("%s",s); 
    p = createTM(s); 
    simulate(p); 
    return 0; 
} 

このプログラムが動作しないのはなぜ?

+3

あなたはこのCのタグを付けていますが、コメントには「This C file」と表示されますが、ファイルは通常はC++を意味する '.cpp 'で、最初のエラーは' new' C++の問題。あなたはそのエラーを読んだのですか?彼らはすべて行番号を持っています。エラーを生成する各行に移動し、それを見て、間違っているかどうかを確認します。次に、これを簡単なコンパイル可能なコードに単純化して、解決できないエラー(またはエラー)を生成してください。私たちのプログラム全体をダンプして、少なくともあなたが何らかの努力を払っていることを示すことなく「修正する」と言ってはいけません。 –

+0

@Chris Luts私は拡張子を.cに変更しましたが、動作しません。さらにnew1で新しいファイルを変更しても、C:\ Documents and Settings \ Melkhiah.EQUIPO01 \ Mis documentos \ Downloads \ Tarea3 Discretas \ TM .c | 44 | error: 'void * 'から' Tape *'への無効な変換| – franvergara66

+2

@ Melkhiah66:まだC++コンパイラを使用しています。下のTomの答えは右半分にすぎません。コンパイラーのオプションとその呼び出し方法によっても異なります。 – Arafangion

答えて

9

提供されているプログラムはCですが、C++コンパイラでコンパイルしています。

Cを使用してもう一度コンパイルしてください。これでOKです。

1

newはC++の予約語で、変数名をnew1のように変更します。または、ファイル名に.cppをcに変更します。

2

ファイル拡張子が.cppなので、コードはC++として扱われています。それを.cに変更するとうまくいくはずです。これは、C++互換にするためにソースコードを修正することをはるかに容易にし(問題を起こしにくい)

編集

は、私が使用しているコンパイラは 行うは、ファイルの拡張子に基づいて言語を検出する gccまたは cl、だったと仮定しました。それは当てはまらないので、使用しているコンパイラ(とオプション)を教えてください。

編集2:それはC++コンパイラで動作するように取得するためには、あなたは@whitelionVが提案ようnew1newの名前を変更する必要があります。このような適切なタイプに、すべてのcalloc()の戻り値をキャスト:

44  Tape *new1 = (Tape*)calloc(1,sizeof(Tape));; 
68  Tape *t = (Tape *)calloc(1,sizeof(Tape)); 
80  Transition *t = (Transition *)calloc(1,sizeof(Transition)); 
93  List *t = (List *)calloc(1,sizeof(List)); 
105 List *t = (List *)calloc(1,sizeof(List)); 
166 TM *m = (TM *)calloc(1,sizeof(TM)); 
167 List *tr = (List *)calloc(1,sizeof(List)); 
+0

@MichaelBurr質問が変更されました(元々はturing_machine.cppという編集内容を参照してください)。 gccとclの両方がファイル拡張子を使ってCまたはC++であるかどうかを判断します。 – tom

+0

@tom:gccはファイル拡張子を使ってCまたはC++であるかどうかを判断しません。 gccはCコンパイラです。 g ++はC++コンパイラであり、どちらもGnuコンパイラコレクション(GCC)の一部です。 – Arafangion

+0

これをテストしたところ、gccはa.cとa.cppを同じように扱っていません。 http://www.network-theory.co.uk/docs/gccintro/gccintro_54.htmlから: "...gccはC++ファイル拡張子を検出したときに実際にC++ソースコードをコンパイルしますが、その結果生成されたオブジェクトファイルをリンクすることはできません」 – tom