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の定数のポインタを指します」を表します.
ここには設計案があり、主なデータ構造はスタックであり、左から右に読み取り、各タグをスタックに順次押し込み、識別子まで読むことを知ってから、識別子の右にあるタグを右に読み込み続け、識別子の左にあるタグを観察します(スタックからポップアップする必要があります).
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;
}