構文アナライザーと字句アナライザーの共通点
構文アナライザーはプッシュダウンオートマトンとも呼ばれ、字句アナライザーは有限オートマトンとも呼ばれます。
1.分析する単純言語の形態
同じ点:どちらも分析タイプコードです
違い:字句解析プログラムは、文字列内の単語のカテゴリコード(単語)を分析します
パーサーは、文字列の文法が正しいかどうかを分析します(文)
分析する単純な言語の文法
BNF:(1)<プログラム> :: =begin<ステートメント文字列>end
(2)<ステートメント文字列> ::=<ステートメント>{;<ステートメント>}
(3)<ステートメント> ::=<割り当てステートメント>
(4)<代入ステートメント> :: = ID:=<式>
(5)<式> ::=<アイテム>{+<アイテム>|-<アイテム>}
(6)<item> :: = <factor {* <factor> | / <factor>}
パーサーの機能
#記号で終わるC言語の文字列を入力します。文法的に正しい文の場合、プログラムは成功メッセージを出力します。文法的に正しくない文の場合、プログラムはエラーメッセージを出力し、エラーが発生した場所にプロンプトを表示します。 。
正しい文法:BNF文法を開始しますend#
【例1】
文字列を指定して、構文が正しいかどうかを確認します。
入力:開始a:= 9; x:= 2 * 3; b:= a + x終了#
出力:成功!
入力:開始x:= a + b*c終了
出力:エラー!「終了」後のエラー
入力:開始x:= a + b * c
出力:エラー!「終わり」がありません
入力:x:= a + b * c end#
出力:エラー!行方不明の始まり
プログラム検証コード(パーサー)
#include <studio.h>
#include <string.h>
void scaner();
void sentence();
void statement();
void expression();
void term();
void factor();
char *key[0]={"begin","if","then","while","do","end"},ch[100];
int p=0,kk=0,q,syn;
int main()
{
printf("输入:\n");
gets(ch);
sentence();
return 0;
}
void scanner()
{
char token[100] = {};
q = 0;
while(ch[p] == ' ') p++;
if((ch[p] >= 'a' && ch[p] <= 'z')||(ch[p] >= 'A' && ch[p] <= 'Z')
{
token[q++] = ch[p];
p++;
while((ch[p] >= '0' && ch[p] <= '9')||(ch[p] >= 'a' && ch[p] <= 'z')
||(ch[p] >= 'A' && ch[p] <= 'Z')) token[q++] = ch[p++];
syn = 10;
token[q] = '\0';
for(int n = 0;n < 6;n++)
if(strcmp(token,key[n]) == 0)
{
syn = n + 1;
break;
}
}
else if(ch[p] >= '0' && ch[p] <= '9')
{
token[q++] = ch[p];
p++;
while(ch[p] >= '0' && ch[p] <= '9') token[q++] = ch[p++];
syn = 11;
}
else switch(ch[p])
{
case '<':token[q++] = ch[p++];
if(ch[p] == '>')
{
syn = 21;
token[q++] = ch[p++];
}
else if(ch[p] == '=')
{
syn = 22;
token[q++] = ch[p++];
}
else syn = 23;
break;
case '>':token[q++] = ch[p++];
if(ch[p] == '>')
{
syn = 24;
token[q++] = ch[p++];
}
else syn = 20;
break;
case “:” :token[q++] = ch[p++];
if(ch[p] == "="){
syn = 18;
token[q++] = ch[p++];
}
else syn = 17;
token[q++] = ch[p++];
break;
case '*':syn = 13;
token[q++] = ch[p++];
break;
case '/':syn = 14;
token[q++] = ch[p++];
break;
case '+':syn = 15;
token[q++] = ch[p++];
break;
case '-':syn = 16;
token[q++] = ch[p++];
break;
case '=':syn = 25;
token[q++] = ch[p++];
break;
case ';':syn = 26;
token[q++] = ch[p++];
break;
case '(':syn = 27;
token[q++] = ch[p++];
break;
case ')':syn = 28;
token[q++] = ch[p++];
break;
case '#':syn = 0;
token[q++] = ch[p++];
break;
case '\n':syn = -2;
break;
default:syn = -1;
break;
}
}
void sentence()
{
scaner();
if(syn == 1)
{
statement();
while(syn == 26) statement();
if(syn == 6)
{
scaner();
if(syn == 0) printf("成功!\n");
else printf("错误!“end”后出错。\n");
}
else
{
printf("错误!缺少“end”。\n");
kk = 1;
}
}
else
{
printf("错误!缺少“begin”。\n");
kk = 1;
}
}
void statement()
{
scaner();
if(syn == 10)
{
scaner();
if(syn == 18)
{
scaner();
expression();
}
else
{
printf("错误!“:=”出错。\n");
kk = 1;
}
}
else
{
printf("错误!句子出错。\n");
kk = 1;
}
return;
}
void expression()
{
term();
while((syn == 13)||(syn == 14))
{
scaner();
term();
}
return;
}
void term()
{
factor();
while((syn == 15)||(syn == 16))
{
scaner();
factor();
}
return;
}
void factor()
{
if((syn == 10)||(syn == 11)) scaner();
else if(syn == 27)
{
scaner();
expression();
if(syn == 28) scaner();
else
{
printf("错误!“(”出错。\n");
kk = 1;
}
}
else
{
printf("错误!\n");
kk = 1;
}
return;
}
//begin a:=9;x:=2*3;b:=a+x end#
//begin x:a+b*c end
走る
文字列を入力してEnterキーを押すと、上記の例1の結果が出力されます。