當前位置:首頁 » 編程軟體 » c語言文法編譯原理

c語言文法編譯原理

發布時間: 2022-11-14 02:47:55

㈠ 求c語言文法及產生式!要做C編譯器——語法分析部分

轉自http://blog.csdn.net/rill_zhen/article/details/7701259http://blog.csdn.net/rill_zhen/article/details/7701259
希望能幫到你

編譯原理-1-C語言的文法
編譯原理-1-C語言的文法
c語言的文法產生式:
program ->
external_declaration
| program external_declaration
external_declaration ->
function_definition
| declaration
function_definition -> type_specifier declarator compound_statement
type_specifier ->
VOID
| CHAR
| INT
| FLOAT
declarator
pointer direct_declarator
| direct_declarator
Pointer->
'*'
| '*' pointer
direct_declarator
IDENTIFIER
|direct_declarator』[『 『]』
|direct_declarator 』[』 constant_expression 』]』
| IDENTIFIER '(' parameter_list ')'
| IDENTIFIER '(' ')'
|direct_declarator『,』identifier_list
identifier_list
: IDENTIFIER
| identifier_list ',' IDENTIFIER
constant_expression->
conditional_expression
parameter_list ->
parameter_declaration
| parameter_list ',' parameter_declaration

parameter_declaration ->
declaration_specifiers IDENTIFIER
compound_statement ->
'{' '}'
| '{' statement_list '}'
| '{' declaration_list statement_list '}'
declaration_list ->
declaration
| declaration_list declaration
Declaration->
init_declarator
| init_declarator_list ',' init_declarator
init_declarator ->
declarator
| declarator '=' initializer
Initializer ->
assignment_expression
| '{' initializer_list '}'
| '{' initializer_list ',' '}'
initializer_list ->
initializer
| initializer_list ',' initializer
statement_list->
statement
| statement_list statement
Statement ->
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
expression_statement ->
';'
| expression ';'
selection_statement
: IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement
iteration_statement->
WHILE '(' expression ')' statement
| FOR '(' expression_statement expression_statement ')' statement
| FOR '(' expression_statement expression_statement expression ')' statement
jump_statement
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
expression
: assignment_expression
| expression ',' assignment_expression
assignment_expression ->
conditional_expression
| unary_expression assignment_operator assignment_expression
conditional_expression ->
logical_or_expression
| logical_or_expression ' ' expression ':' conditional_expression
logical_or_expression ->
logical_and_expression
| logical_or_expression OR_OP logical_and_expression
logical_and_expression
: inclusive_or_expression
| logical_and_expression AND_OP inclusive_or_expression
inclusive_or_expression->
exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
exclusive_or_expression
: and_expression
| exclusive_or_expression '^' and_expression
and_expression
: equality_expression
| and_expression '&' equality_expression
equality_expression
: relational_expression
| equality_expression EQ_OP relational_expression
| equality_expression NE_OP relational_expression
relational_expression
: shift_expression
| relational_expression '$amp;
| relational_expression '$amp;>apos;$ shift_expression
| relational_expression LE_OP shift_expression
| relational_expression GE_OP shift_expression
shift_expression
: additive_expression
| shift_expression LEFT_OP additive_expression
| shift_expression RIGHT_OP additive_expression
additive_expression
: multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
multiplicative_expression
: cast_expression
| multiplicative_expression '*' cast_expression
| multiplicative_expression '/' cast_expression
| multiplicative_expression '%' cast_expression
cast_expression
: unary_expression
| '(' type_name ')' cast_expression
unary_expression
: postfix_expression
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF '(' type_name ')'
postfix_expression ->
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
| postfix_expression '.' IDENTIFIER
| postfix_expression PTR_OP IDENTIFIER
| postfix_expression INC_OP
| postfix_expression DEC_OP
primary_expression ->
IDENTIFIER
| CONSTANT
| STRING_LITERAL
| '(' expression ')'
argument_expression_list
: assignment_expression
| argument_expression_list ',' assignment_expression
unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
assignment_operator ->
'='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
storage_class_specifier ->
TYPEDEF
| EXTERN
| STATIC
| AUTO
| REGISTER
struct_or_union_specifier
: struct_or_union IDENTIFIER '{' struct_declaration_list '}'
| struct_or_union '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER
struct_or_union
: STRUCT
| UNION
struct_declaration_list
: struct_declaration
| struct_declaration_list struct_declaration
struct_declaration
: specifier_qualifier_list struct_declarator_list ';'
specifier_qualifier_list ->
type_specifier specifier_qualifier_list
| type_specifier
| type_qualifier specifier_qualifier_list
| type_qualifier
struct_declarator_list ->
struct_declarator
| struct_declarator_list ',' struct_declarator
struct_declarator ->
: declarator
| ':' constant_expression
| declarator ':' constant_expression
enum_specifier ->
ENUM '{' enumerator_list '}'
| ENUM IDENTIFIER '{' enumerator_list '}'
| ENUM IDENTIFIER
enumerator_list ->
enumerator
| enumerator_list ',' enumerator
Enumerator ->
IDENTIFIER
| IDENTIFIER '=' constant_expression
type_qualifier ->
CONST
| VOLATILE
type_qualifier_list ->
type_qualifier
| type_qualifier_list type_qualifier
parameter_type_list ->
parameter_list
| parameter_list ',' ELLIPSIS
parameter_list ->
: parameter_declaration
| parameter_list ',' parameter_declaration
type_name ->
specifier_qualifier_list
| specifier_qualifier_list abstract_declarator
abstract_declarator ->
pointer
| direct_abstract_declarator
| pointer direct_abstract_declarator
direct_abstract_declarator ->
'(' abstract_declarator ')'
| '[' ']'
| '[' constant_expression ']'
| direct_abstract_declarator '[' ']'
| direct_abstract_declarator '[' constant_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
| direct_abstract_declarator '(' ')'
| direct_abstract_declarator '(' parameter_type_list ')'
labeled_statement ->
IDENTIFIER ':' statement
| CASE constant_expression ':' statement
| DEFAULT ':' statement

㈡ 什麼是編譯原理

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。雖然只有少數人從事編譯方面的工作,但是這門課在理論、技術、方法上都對學生提供了系統而有效的訓練,有利於提高軟體人員的素質和能力。
這門課程關注的是編譯器方面的產生原理和技術問題,似乎和計算機的基礎領域不沾邊,可是編譯原理卻一直作為大學本科的 必修課程,同時也成為了研究生入學考試的必考內容。編譯原理及技術從本質上來講就是一個演算法問題而已,當然由於這個問題十分復雜,其解決演算法也相對復雜。 我們學的數據結構與演算法分析也是講演算法的,不過講的基礎演算法,換句話說講的是演算法導論,而編譯原理這門課程講的就是比較專註解決一種的演算法了。在20世紀 50年代,編譯器的編寫一直被認為是十分困難的事情,第一Fortran的編譯器據說花了18年的時間才完成。在人們嘗試編寫編譯器的同時,誕生了許多跟 編譯相關的理論和技術,而這些理論和技術比一個實際的編譯器本身價值更大。就猶如數學家們在解決著名的哥德巴赫猜想一樣,雖然沒有最終解決問題,但是其間 誕生不少名著的相關數論。

㈢ 編譯原理中如何用c語言來編寫程序判斷輸入的字元串是否符合文法規則

LEX可以進行詞法分析。
如果要自己寫,主要是把正則文法轉化為自動機,根據輸入串進行狀態轉移。

㈣ 學習編譯原理要有什麼基礎

數學知識要具備一些,因該是高數吧,C語言是要知道的,還有數據結構啊,也有點相關的,我們學校是大四才開的課。
這門課還是找個老師教比較好,自學是比較吃力的,希望你能成功!

㈤ 編譯原理 給出一文法 用C語言求其first集

找本課本,抄一道例題不就成了

㈥ C語言編譯原理是什麼

編譯共分為四個階段:預處理階段、編譯階段、匯編階段、鏈接階段。
1、預處理階段:
主要工作是將頭文件插入到所寫的代碼中,生成擴展名為「.i」的文件替換原來的擴展名為「.c」的文件,但是原來的文件仍然保留,只是執行過程中的實際文件發生了改變。(這里所說的替換並不是指原來的文件被刪除)
2、匯編階段:
插入匯編語言程序,將代碼翻譯成匯編語言。編譯器首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤後,編譯器把代碼翻譯成匯編語言,同時將擴展名為「.i」的文件翻譯成擴展名為「.s」的文件。
3、編譯階段:
將匯編語言翻譯成機器語言指令,並將指令打包封存成可重定位目標程序的格式,將擴展名為「.s」的文件翻譯成擴展名為「.o」的二進制文件。
4、鏈接階段:
在示例代碼中,改代碼文件調用了標准庫中printf函數。而printf函數的實際存儲位置是一個單獨編譯的目標文件(編譯的結果也是擴展名為「.o」的文件),所以此時主函數調用的時候,需要將該文件(即printf函數所在的編譯文件)與hello
world文件整合到一起,此時鏈接器就可以大顯神通了,將兩個文件合並後生成一個可執行目標文件。

㈦ 編譯原理

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。編譯原理課程是計算機相關專業學生的必修課程和高等學校培養計算機專業人才的基礎及核心課程,同時也是計算機專業課程中最難及最挑戰學習能力的課程之一。編譯原理課程內容主要是原理性質,高度抽象[1]。

中文名
編譯原理[1]
外文名
Compilers: Principles, Techniques, and Tools[1]
領域
計算機專業的一門重要專業課[1]
快速
導航
編譯器

編譯原理課程

編譯技術的發展

編譯的基本流程

編譯過程概述
基本概念
編譯原理即是對高級程序語言進行翻譯的一門科學技術, 我們都知道計算機程序由程序語言編寫而成, 在早期計算機程序語言發展較為緩慢, 因為計算機存儲的數據和執行的程序都是由0、1代碼組合而成的, 那麼在早期程序員編寫計算機程序時必須十分了解計算機的底層指令代碼通過將這些微程序指令組合排列從而完成一個特定功能的程序, 這就對程序員的要求非常高了。人們一直在研究如何如何高效的開發計算機程序, 使編程的門檻降低。[2]
編譯器
C語言編譯器是一種現代化的設備, 其需要藉助計算機編譯程序, C語言編譯器的設計是一項專業性比較強的工作, 設計人員需要考慮計算機程序繁瑣的設計流程, 還要考慮計算機用戶的需求。計算機的種類在不斷增加, 所以, 在對C語言編譯器進行設計時, 一定要增加其適用性。C語言具有較強的處理能力, 其屬於結構化語言, 而且在計算機系統維護中應用比較多, C語言具有高效率的優點, 在其不同類型的計算機中應用比較多。[3]
C語言編譯器前端設計
編譯過程一般是在計算機系統中實現的, 是將源代碼轉化為計算機通用語言的過程。編譯器中包含入口點的地址、名稱以及機器代碼。編譯器是計算機程序中應用比較多的工具, 在對編譯器進行前端設計時, 一定要充分考慮影響因素, 還要對詞法、語法、語義進行分析。[3]
1 詞法分析[3]
詞法分析是編譯器前端設計的基礎階段, 在這一階段, 編譯器會根據設定的語法規則, 對源程序進行標記, 在標記的過程中, 每一處記號都代表著一類單詞, 在做記號的過程中, 主要有標識符、關鍵字、特殊符號等類型, 編譯器中包含詞法分析器、輸入源程序、輸出識別記號符, 利用這些功能可以將字型大小轉化為熟悉的單詞。[3]
2 語法分析[3]
語法分析是指利用設定的語法規則, 對記號中的結構進行標識, 這包括句子、短語等方式, 在標識的過程中, 可以形成特殊的結構語法樹。語法分析對編譯器功能的發揮有著重要影響, 在設計的過程中, 一定要保證標識的准確性。[3]
3 語義分析[3]
語義分析也需要藉助語法規則, 在對語法單元的靜態語義進行檢查時, 要保證語法規則設定的准確性。在對詞法或者語法進行轉化時, 一定要保證語法結構設置的合法性。在對語法、詞法進行檢查時, 語法結構設定不合理, 則會出現編譯錯誤的問題。前端設計對精確性要求比較好, 設計人員能夠要做好校對工作, 這會影響到編譯的准確性, 如果前端設計存在失誤, 則會影響C語言編譯的效果。[3]

㈧ 急求:編譯原理判斷文法類型的C語言源代碼!!!!!!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/**//*全局變數定義*/
char inputString[10]; /**//*用來存儲用戶輸入的字元串,最長為20個字元*/
char stack[10]; /**//*用來進行語法分析的棧結構*/
int base=0; /**//*棧底指針*/
int top=1; /**//*棧頂指針*/
char VT[4]={'a','d','b','e'}; /**//*用來存放5個終結符*/
char chanShengShi[10]; /**//*用來存放預測分析表M[A,a]中的一條產生式*/
int firstCharIntex=0; /**//*如果a匹配產生式,則每次firstCharIntex 自增 1 */
/**//*firstCharIntex用來存放用戶輸入串的第一個元素的下標*/

/**//*自定義函數聲明*/
char pop() ; /**//*彈出棧頂元素*/

int push(char) ; /**//*向棧內添加一個元素,成功返回1,若棧已滿則返回0*/

int search(char temp) ; /**//*查找非終結符集合VT中是否存在變數temp,存在返回1,不存在返回0*/

int M(char A, char a) ; /**//* 若預測分析表M[A,a]中存在產生式,
則將該產生式賦給字元數組chanShengShi[10],並返回 1,
若M[A,a]中無定義產生式則返回 0
*/

void init() ; /**//*初始化數組inputString[10] 、棧 stack[10] 和 chanShengShi[10]*/

int yuCeFenXi() ; /**//* 進行輸入串的預測分析的主功能函數,
若輸入串滿足文法則返回 1,不滿足則返回0
*/
void printStack(); /**//*列印棧內元素 */
void printinputString(); /**//*列印用戶輸入串 */

/**//*進入主函數*/
void main()
{
system("cls");
yuCeFenXi(); /**//*調用語法預測分析函數*/
system("pause");
}

/**//*函數的定義*/

int yuCeFenXi()
{
char X; /**//*X變數存儲每次彈出的棧頂元素*/
char a; /**//*a變數存儲用戶輸入串的第一個元素*/
int i;
int counter=1; /**//*該變數記錄語法分析的步驟數*/

init(); /**//*初始化數組*/
printf("wen fa : \n"); /**//*輸出文法做為提示*/
printf("S -> aH \n");
printf("H -> aMd | d \n");
printf("M -> Ab | \n");
printf("A -> aM | e \n");

printf("\ninput string ,'#' is a end sign !!(aaabd#) \n"); /**//*提示用戶輸入將要測試的字元串*/
scanf("%s",inputString);

push('#');
push('S');

printf("\nCounter-----Stack---------------Input string \n"); /**//*輸出結果提示語句*/

while(1) /**//*while循環為語法分析主功能語句塊*/
{
printf(" ");
printf(" %d",counter); /**//*輸出分析步驟數*/
printf(" "); /**//*輸出格式控制語句*/
printStack(); /**//*輸出當前棧內所有元素*/
X=pop(); /**//*彈出棧頂元素賦給變數X*/
printinputString(); /**//*輸出當前用戶輸入的字元串*/

if( search(X)==0 ) /**//*在終結符集合VT中查找變數X的值,存在返回 1,否則返回 0*/
{
if(X == '#') /**//*棧已經彈空,語法分析結果正確,返回 1*/
{
printf("success \n"); /**//*語法分析結束,輸入字元串符合文法定義*/
return 1;
}
else
{
a = inputString[firstCharIntex];
if( M(X,a)==1 ) /**//*查看預測分析表M[A,a]是否存在產生式,存在返回1,不存在返回0*/
{
for(i=0;i<10;i++) /**//* '$'為產生式的結束符,for循環找出該產生式的最後一個元素的下標*/
{
if( chanShengShi[i]=='$' ) break;
}
i-- ; /**//*因為 '$' 不是產生式,只是一個產生式的結束標志,所以i自減1*/

while(i>=0)
{
push( chanShengShi[i] ); /**//*將當前產生式逆序壓入棧內*/
i-- ;
}
}
else
{
printf(" error(1) !!\n"); /**//*若預測分析表M[A,a]不存在產生式,說明語法錯誤*/
return 0;
}
}
}
else /**//*說明X為終結符*/
{
if( X==inputString[firstCharIntex] ) /**//*如果X等於a,說明a匹配*/
{
firstCharIntex++; /**//*輸入串的第一個元素被約去,下一個元素成為新的頭元素*/
}
else
{
printf(" error(2) !! \n");
return 0;
}
}
counter++;
}
}

void init()
{
int i;
for(i=0;i<10;i++)
{
inputString[i]=NULL; /**//*初始化數組inputString[10] */
stack[i]=NULL; /**//*初始化棧stack[10] */
chanShengShi[i]=NULL; /**//*初始化數組chanShengShi[10]*/
}
}

int M(char A, char a) /**//*文法定義因實際情況而定,該文法為課本例題的文法*/
{ /**//*該函數模擬預測分析表中的二維數組 */
if( A=='S'&& a=='a' ) { strcpy(&chanShengShi[0],"aH$"); return 1; }
if( A=='H'&& a=='a' ) { strcpy(&chanShengShi[0],"aMd$"); return 1; }
if( A=='H'&& a=='d' ) { strcpy(&chanShengShi[0],"d$"); return 1; }
if( A=='M'&& a=='a' ) { strcpy(&chanShengShi[0],"Ab$"); return 1; }
if( A=='M'&& a=='d' ) { strcpy(&chanShengShi[0],"$"); return 1; }
if( A=='M'&& a=='b' ) { strcpy(&chanShengShi[0],"$"); return 1; }
if( A=='M'&& a=='e' ) { strcpy(&chanShengShi[0],"Ab$"); return 1; }
if( A=='A'&& a=='a' ) { strcpy(&chanShengShi[0],"aM$"); return 1; }
if( A=='A'&& a=='e' ) { strcpy(&chanShengShi[0],"e$"); return 1; }
else return 0; /**//*沒有定義產生式則返回0*/
}

char pop() /**//*彈出棧頂元素,用topChar返回*/
{
char topChar;
topChar=stack[--top];
return topChar;
}

int push(char ch)
{
if( top>9 )
{
printf(" error : stack overflow "); /**//*棧空間溢出*/
return 0;
}
else
{
stack[top]=ch; /**//*給棧頂空間賦值*/
top++;
return 1;
}
}

int search(char temp)
{
int i,flag=0; /**//*flag變數做為標志,若找到temp則賦1,否則賦0*/
for(i=0;i<4;i++)
{
if( temp==VT[i] ) /**//*終結符集合中存在temp*/
{
flag=1;
break;
}
}

if(flag==1) return 1; /**//*flag==1說明已找到等於temp的元素*/
else return 0;

}

void printStack() /**//*輸出棧內內容*/
{
int temp;
for(temp=1;temp<top;temp++)
{
printf("%c",stack[temp]);
}
}

void printinputString() /**//*輸出用戶輸入的字元串*/
{
int temp=firstCharIntex ;
printf(" "); /**//*該句控制輸出格式*/
do{
printf("%c",inputString[temp]);
temp++;
}while(inputString[temp-1]!='#');
printf(" \n");
}

㈨ C語言語法分析器 編譯原理實驗報告 [email protected]

#include<stdio.h>
void main()
{

int m=0,n=0,n1=0,n2=0,n3=0,zg,fzg,flag;
int bz[7]={1,1,1,1,1,1,1};/*狀態改變控制,1 表示可以改變狀態zt值,0 表示不可以*/
int zt[7]={2,2,2,2,2,2,2};/*狀態值,2表示未定狀態,1表示 是,0表示 否*/

char temp[100]="\0";/*用於求first集*/
char z[7];/*非總結符*/
char z1[7];/*總結符*/
char z2[7]="\0";/*gs[]文法中出現的標記個數的輔助字元 01234*/
char gs[100]="\0";/*文法,按順序排成字元串*/

printf("請依次輸入非終結符(不超過7個):");
gets(z);
while(z[m]!='\0')
{m++;}
fzg=m;//zg是非終結符個數

while(n<m)
{z2[n]=n+48;n++;}//生成01234輔助字元
printf("您輸入了:");
puts(z);
fflush(stdin);

printf("請依次輸入終結符(不超過7個):");
gets(z1);
while(z1[n1]!='\0')
{n1++;}
zg=n1;
printf("您輸入了:");
puts(z1);
fflush(stdin);

printf("按照正確格式輸入所有文法(總長度不超過100格式如下):");
printf("如果文法為(字元'k'表示空):\n");
printf("S-->AB S-->bC A-->k A-->b\n");
printf("輸入:0SAB0SbC1Ak1Ab\n");
printf(" (注:數字01234表示第一二三四個非終結符)\n");

gets(gs);
fflush(stdin);
printf("您輸入了:");
puts(gs);
m=0;
//對於輸入文法字元串的轉換,將每個文法式左部去除
while(gs[m]!='\0')
{
n=m;
if(gs[m]>='0'&&gs[m]<='9')
{
m++;
while(gs[m]!='\0')
{
gs[m]=gs[m+1];
m++;
}
//gs[m-1]='\0';
}
m=++n;
}

m=0;

//puts(gs);

/*情況一,直接判定是 形如: (A-->k) */
while(gs[m]!='\0')
{
if(gs[m]=='k')
{
zt[gs[m-1]-48]=1;
bz[gs[m-1]-48]=0;
}
m++;
}

/*情況二,直接判定--否 形如: (D-->aS ,D-->c) */
for(n=0;n<fzg;n++)
{
if(bz[n]==1)
{
m=0;
n2=0;
while(gs[m]!='\0')
{
if(z2[n]==gs[m])
{
if(gs[m+1]>=z1[0]&&gs[m+1]<=z1[n1-1])
zt[n]=0;
else {n2=99;break;} //gs[m+1] 是非終結符n2做標記
}
//跳出循環,無法解決該情況,推到下面情況三
m++;
}
if(n2!=99) {zt[n]=0;bz[n]=0;} //完成所有掃描,未出現非終結符,得出結論zt[n]=0.bz[n]=0不允許再改變zt[n]
}
}

/*情況三,最終判定*/
do
{
flag=0;
for(n=0;n<fzg;n++)
{
if(bz[n]==1) //未得到判定
{ m=0;
while(gs[m]!='\0')
{
if(gs[m]==z2[n]) //判定gs[m]是輔助字元0123
{
m++;
while(gs[m]>='A'&&gs[m]<='Z')
{

n1=0;
for(n2=0;n2<fzg;n2++) //循環查找是gs[m]哪個非終結符
{
if(gs[m]==z[n2])
{
if(zt[n2]==1) //這個非終結符能推出空
zt[n]=1;
else if(bz[n2]==1) //這個非終結符 現在 不能推出空,但它的狀態可改即它最終結果還未判定
{zt[n]=2;bz[n]=1;}
else
{zt[n]=0;bz[n]=0;n1=99;} //設 m1 做標記供下一if參考
break; //找到gs[m]是哪個非終結符,for循環完成任務,可以結束
}

}
if(n1==99) break;
m++;
}
}
m++;
}
if(zt[n]==1) bz[n]=0;
if(bz[n]==0) flag=1;//對應for下的第一個if(zt[n]==2)
}

}
}while(flag);

printf("結果是:\n");

for(m=0;m<5;m++)
{
switch(zt[m])
{
case 0:printf("%c---否\n",z[m]);break;
case 1:printf("%c---是\n",z[m]);break;
case 2:printf("%c---未定\n",z[m]);break;
}

}
/*
puts(gs);
puts(zt);
puts(z);
puts(z1);
puts(z2);
printf("%d,,,%d",fzg,zg);
*/

//下面求first集
//下面求first集

for(n=0;n<fzg;n++)
{bz[n]=0;}
m=0;n=0;n1=0;n2=0;
while(gs[n]>='0'&&gs[n]<='9')
{
for(;m<fzg;m++)
{
if(n2!=m)
n1=0; //m=n2用於第二次以後的for循環中還原上次m的值

if(gs[n]==z2[m])
{
while(gs[n+1]>'9')
{
if(n1==0)
{temp[m*13+n1]=gs[n+1];n1++;} //如果是第一個直接保存

//不是第一個,先與字元數組中其它字元比較,沒相同的才保存
else if(gs[n]>='a'&&gs[n]<='z'&&gs[n+1]>='A'&&gs[n+1]<='Z') //gs[n]是終結符 且 gs[n+1]是非終結符
;//什麼也不做,程序繼續n++,掃描下一個gs[n]

else
{
for(n3=0;n3<=n1;n3++)
{
if(temp[m*13+n3]==gs[n+1])
break;
}

if(n3>n1) //for循環結束是因為n3而不是break
{temp[m*13+n1]=gs[n+1];n1++;}
}
n++;
}
break; //break位於if(gs[n]==z2[m]),對於gs[n]已找到z2[m]完成任務跳出for循環
}
}
n2=m; //存放該for循環中m的值
n++;
}
//進一步處理集除去非終結符
m=0;n=0;n1=0;n2=0;
for(m=0;m<fzg;m++)
{
if(flag!=m)
n1=0; //m=flag用於第二次以後的for循環中還原上次m的值

while(temp[m*13+n1]!='\0')
{
while(temp[m*13+n1]>='A'&&temp[m*13+n1]<='Z') //搜索非終結符
{
for(n=0;n<fzg;n++) //確定是哪個非終結符
{if(temp[m*13+n1]==z[n])
break;
}
while(temp[m*13+n1]!='\0') //從temp[n*13+n1]開始每個字元依次往前移動一
{temp[m*13+n1]=temp[m*13+n1+1];n1++;}
n1--;
while(temp[n*13+n2]!='\0') //把z[n]對應的first加入temp[m*13+n1]這個first中,每個字元依次加在最後
{
for(n3=0;n3<n1;n3++) //循環判定是否有相同的字元
{
if(temp[m*13+n3]==temp[n*13+n2])
break;
}
if(temp[n*13+n2]=='k'&&zt[m]==0) //那些不能推出 空,但是因為要加入 其他非終結符的first集 而可能含有 空
n2++;
else if(n3>=n1) //for循環結束是因為n3而不是break ,即無相同字元
{temp[m*13+n1]=temp[n*13+n2];n2++;n1++;}
else n2++;
}

n1=0;
n2=0;
}

n1++;
}
flag=m; //存放該for循環中m的值
}

//非終結符的first集輸出
m=0;n1=0;
for(m=0;m<fzg;m++)
{
n1=0;
printf("非終結符 %c 的first集是: ",z[m]);
while(temp[m*13+n1]!='\0')
{
printf("%c",temp[m*13+n1]);
n1++;
}
printf("\n");
}

}

㈩ 編譯原理中如何用c語言來編寫程序判斷輸入的字元串是否符合文法規則

scanf()有返回值,若返回值是0,則不符合文法規則
一般情況下,scanf()返回值是輸入的字元數

熱點內容
subplotpython 發布:2025-05-14 06:53:51 瀏覽:661
豎屏大屏導航工廠密碼一般是多少 發布:2025-05-14 06:49:29 瀏覽:806
如何在手機里設置無線網密碼 發布:2025-05-14 06:47:54 瀏覽:120
動態ip文件伺服器 發布:2025-05-14 06:44:22 瀏覽:891
文字分行的腳本有什麼 發布:2025-05-14 06:33:10 瀏覽:288
svn小烏龜怎麼配置 發布:2025-05-14 06:31:43 瀏覽:393
視頻播放器android 發布:2025-05-14 06:31:43 瀏覽:720
android工作室 發布:2025-05-14 06:26:00 瀏覽:658
汽車官方配置表如何下載 發布:2025-05-14 06:21:41 瀏覽:800
停車項目源碼 發布:2025-05-14 06:20:05 瀏覽:358