语法分析之LL(1)分析法

LL(K)分析方法是一种自顶向下的分析技术,这种分析方法是从左到右扫描源程序(输入串),同时从识别符号开始生成句子的最左推导,向前看K个符号,便能确定当前应选用怎样的规则。当K=1时,即是LL(1)分析法。

LL(1)分析法中很重要的一块内容是分析矩阵的构造,这个分析矩阵是进行语法分析的依据,每一步都要靠它来决定如何进行,分析矩阵的构造方法如下:

1.   对于A→ab(a∈Vt),则令LL(A,a)=R(b)/N

2.   对于A→Db(D∈Vn),且Select(A→Db)={b1,b2,…bn},则令LL(A,bi)=R(Db)/P(i=1,2,…n)

3.   对于A→є,且Select(A→є)={b1,b2,…bn},则令LL(A,bi)=R(є)/P(i=1,2,…n)

4.   a∈Vt,a不出现在规则右部的首部,则令LL(a,a)=R(є)/N

5.   #,则令LL(#,#)=acc

6.   其它情况出错,在分析矩阵中可用空白表示


看如下的示例:



其分析矩阵构造如下:



对于输入串i+i*i的分析过程如下:



在此,只用程序来实现在特定的分析矩阵的前提下,实现的语法分析,源程序如下:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

typedef struct E
{
	char *de;//存储产生式
	char *re;//要替换的表达式
	int flag;//是否要消去,为0是不消去,为1是消去
}E;

//栈结构
typedef struct Stack
{
	char *elem;
	int top;
	int size;
}Stack;

E T[7][6];//分析表

Stack as;//分析栈
char rs[30];//剩余字符串

char vn[7]={'E','G','T','S','F',')','#'};//非终结符
char vt[6]={'i','+','*','(',')','#'};//终结符

int p=0;//剩余字符串的指针

//根据终结符和非终结符找到两者在分析表中所对应的位置
E get(char a,char r)
{
	int i;
	int j;
	for(i=0;i<6;i++)
		if(a==vn[i])
			break;
	for(j=0;j<6;j++)
		if(r==vt[j])
			break;
	return T[i][j];
}

//初始化栈
void initStack(Stack *S)
{
	S->elem=(char *)malloc(30*sizeof(char));
	S->top=-1;
	S->size=30;
}

//入栈
void push(Stack *S,char x)
{
	if(S->top==S->size-1)  
	{
		printf("Stack Overflow!\n");
		return;
	}
    S->elem[++S->top]=x;
}  
   
//出栈
char pop(Stack *S)
{  
    char x;
    if(S->top==-1)
	{
		printf("Stack Empty!\n");
		return 0;
	}
    x=S->elem[S->top--];
    return x;
}

//取栈顶元素,但是不删除栈顶元素
char top(Stack *S)
{
    char x;
    if(S->top==-1)
	{
		printf("Stack Empty!\n");
		return 0;
	}
    x=S->elem[S->top];
    return x;
}

//打印栈中和剩余字符串中的数据
void print(Stack *S)
{
	int i;
	unsigned int j;

	for(i=0;i<=S->top;i++)
		printf("%c",S->elem[i]);
	printf("\t\t");
	
	for(i=0;i

输出结果示例如下:




你可能感兴趣的:(编译原理)