c言語の中の声明をプログラムで通俗的な言語に翻訳する

4466 ワード

c言語の優先度ルールを理解するには、次の手順に従います.
A
名前から読み取りを開始し、優先順位順に1回読み込むことを宣言します.
B
優先順位は次の順です.
b 1声明の括弧で囲まれた部分
b 2接尾辞オペレータ
かっこ()は関数を表し、角カッコ【】は配列を表します.
b 3接頭辞オペレータ、アスタリスク*は「指す...のポインタ」を表す
C
const(またはvolatile)キーワードの後ろにタイプ説明子(int,longなど)が続く場合、タイプ説明子に作用し、他の場合は左側に作用します.
隣接するポインタ*番号.
例えばchar*const*(*next)();
上式は「nextは1つのポインタで、それは1つの関数を指して、この関数は別のポインタを返して、このポインタは1つのタイプのcharの定数のポインタを指します」を表します.
ここには設計案があり、主なデータ構造はスタックであり、左から右に読み取り、各タグをスタックに順次押し込み、識別子まで読むことを知ってから、識別子の右にあるタグを右に読み込み続け、識別子の左にあるタグを観察します(スタックからポップアップする必要があります).
#include 
#include 
#include 
#include 
#define MAX_LEN 100
enum type_token {IDENTIFIER,QUALIFIER,TYPE};
typedef struct token{
	char string[100];
	char type;
}token;
token tmp_token;
typedef struct stack{
	token array[MAX_LEN];
	int top;
}stack;
struct stack token_stack;
void init(stack *sta)
{
	sta->top=-1;
}
int push(stack *sta,token s)
{
	if(sta->top>=254)
	{
		printf("the stack is full.
"); return 1; } else { sta->array[++(sta->top)]=s; } return 0; } token pop(stack *sta) { if(sta->top==-1) { printf("ERROR,the stack is empty!
"); } else { return sta->array[(sta->top)--]; } } int stack_empty(const stack s) { if(s.top==-1) return 0; else return 1; } token top_stack(const stack s) { if(stack_empty(s)==0) { printf("ERROR the stack is empty!
"); } else return s.array[s.top]; } enum type_token classify_string(); void gettoken() {// token , , , , tmp_token memset(tmp_token.string,'\0',sizeof(tmp_token.string));// tmp_token char *p=tmp_token.string; while((*p=getchar())==' ');// if(isalnum(*p) || *p=='_'){ // , , while(1) { *(++p)=getchar(); if(isalnum(*p) || *p=='_') continue; else break; } ungetc(*p,stdin);// , *p='\0'; tmp_token.type=classify_string(); return; } if(*p=='*'){ strcpy(tmp_token.string,"pointer to "); tmp_token.type='*'; return; } tmp_token.string[1]='\0'; tmp_token.type=*p; return; } enum type_token classify_string() {// char *s=tmp_token.string; if(!strcmp(s,"const")){ strcpy(s,"read-only "); return QUALIFIER; } if(!strcmp(s,"volatile")) return QUALIFIER; if(!strcmp(s,"extern")) return QUALIFIER; if(!strcmp(s,"void")) return TYPE; if(!strcmp(s,"char")) return TYPE; if(!strcmp(s,"signed")) return TYPE; if(!strcmp(s,"unsigned")) return TYPE; if(!strcmp(s,"short")) return TYPE; if(!strcmp(s,"int")) return TYPE; if(!strcmp(s,"long")) return TYPE; if(!strcmp(s,"float")) return TYPE; if(!strcmp(s,"double")) return TYPE; if(!strcmp(s,"struct")) return TYPE; if(!strcmp(s,"union")) return TYPE; if(!strcmp(s,"enum")) return TYPE; return IDENTIFIER; } void read_first_identifier(){ gettoken(); while(tmp_token.type!=IDENTIFIER){ push(&token_stack,tmp_token); gettoken(); } printf("%s is ",tmp_token.string); gettoken(); } void deal_with_array() { while(tmp_token.type=='[') { printf("array"); gettoken(); if(isdigit(tmp_token.string[0])) { printf(" 0..%d ",atoi(tmp_token.string)-1); gettoken(); } gettoken();// ‘】’ token printf("of "); } } void deal_with_function() { while(tmp_token.type != ')') gettoken(); gettoken(); printf(" function returning "); } void deal_with_pointer() { token t; t=top_stack(token_stack); while(t.type=='*') { printf("%s",t.string); pop(&token_stack); t=top_stack(token_stack); } } void deal_with_declarator(){// switch(tmp_token.type){ case '[': deal_with_array();break; case '(': deal_with_function(); } deal_with_pointer(); while(stack_empty(token_stack)==1) { token t=top_stack(token_stack); if(t.type=='('){ pop(&token_stack); gettoken();// ‘)’ deal_with_declarator(); } else { printf("%s",pop(&token_stack).string); } } } int main() { init(&token_stack); read_first_identifier(); deal_with_declarator(); printf("
"); return 0; }