功能概述:
根据简单语言的词法和各单词符号种别码表,采用LL(1)分析法进行文法分析编写C或C++语言源程序,实现针对该简单语言的词法分析器,对词法分析程序所提供的单词序列进行语法检查和结构分析然后构造语法分析器。
所用知识:1.词法分析 2.语法分析
开发环境:VS2019
//main.c 主函数
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include"def.h"
#include"funs.h"
using namespace std;
WORD scaner();
int main()
{
int over = 1; WORD one = new Node;
std::cout << "输入句子#号结束:";
cin.getline(input,100);//scanf("%s",input);
p_input = 0;
cout << "输入的句子:";cout<<input<<"\n";
fun(one);
lr();
}
//funs.h文件 实现功能
void te(), fa(), ex(), st(), yu(), lr();
char ch, input[255] = "", token[255] = "";
int p_input, p_token, k = 0, legth = 0;
const char* rwtab[] = { "begin","if" ,"then","while","do","end","game over" };
LinkList * wd;
WORD scaner();
void fun(WORD one) {
int over = 1;
LinkList* head = (LinkList*)malloc(sizeof(LinkList));
LinkList * q, * r;
q = head;
head->next = NULL;
r = head;
wd = head;
while (over < 1000 && over != -1) {
one = scaner();
LinkList *p = (LinkList*)malloc(sizeof(LinkList));
p->num = one->typenum;
p->w = one->word;
p->next = NULL;
q->next = p;
q = p;
if (one->typenum < 1000) std::cout << "(" << p->num << "," << p->w << ") ";
over = one->typenum;
}
wd = head->next;
}
void ex() {
te();
while(wd->num==13||wd->num==14)
{
wd = wd->next;
te();
}
return;
}
void fa() {
if (wd->num == 10 || wd->num == 11) wd = wd->next;
else if (wd->num == 27)
{
wd = wd->next;
ex();
if (wd->num == 28) wd = wd->next;
else { std::cout << "\n)错误"; k = 1; }
}
else { std::cout << "\n表达式错误"; k = 1; }
return;
}
void te() {
fa();
while (wd->num==15||wd->num==16)
{
wd = wd->next;
fa();
}
return;
}
void st() {
if (wd->num == 10)
{
wd = wd->next;
if (wd->num == 18)
{
wd = wd->next;
ex();
}
else { std::cout << "\n赋值号错误"; k = 1; }
}
else {std::cout << "\n输出于醋错误"; k = 1;}
return;
}
void yu() {
st();
while (wd->num==26)//;
{
wd = wd->next;
st();
}
return;
}
void lr() {
if (wd->num == 1)//begin
{
wd = wd->next;
yu();
if (wd->num == 6) //end
{
wd = wd->next;
if ( k == 0) std::cout << "\nsuccess";
}
else { if (k != 1) std::cout << "\nend错误"; k = 1; }
}
else std::cout << "\nbegin错误";
return;
}
char m_getch()
{
ch = input[p_input];
p_input = p_input + 1;
return (ch);
}
void getbc()
{
while (ch == ' ' || ch == 10)
{
ch = input[p_input];
p_input = p_input + 1; //std::cout <<ch <<"//";
}
}
void concat()
{
token[p_token] = ch;
p_token++;
token[p_token] = '\0';
}
int letter()
{
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
return 1;
else
return 0;
}
int digit()
{
if (ch >= '0' && ch <= '9')
return 1;
else
return 0;
}
int reserve()
{
int i = 0;
while (strcmp(rwtab[i], "game over"))
{
if (!strcmp(rwtab[i], token))
{
return i + 1;
}
i = i + 1;
}
return 10;
}
void retract()
{
p_input = p_input - 1;
}
WORD scaner() {
WORD myword = new Node;
//char* t = (char*)calloc(legth, sizeof(char));
//for (int i = 0; i <= 255;i++) token[i] = ' ';
p_token = 0;
m_getch();
getbc();
if (letter())
{
//legth = 0;
while (letter() || digit())
{
//legth++;
concat();
m_getch();
}
//char* t = (char*)malloc(legth * sizeof(char));
retract();
// for (int i = 0; i <= legth - 1; i++) { t[i] = token[i]; }
myword->typenum = reserve();
myword->word = token;
return(myword);
}
else if (digit())
{
//legth = 0;
while (digit())
{
// legth++;
concat();
m_getch();
}
retract();
//char* t = (char*)malloc(legth * sizeof(char)); for (int i = 0; i <= legth - 1; i++) std::cout <<t[i]<<"+";
//for (int i = 0; i <= legth-1; i++) t[i] = token[i];
myword->typenum = 11;
myword->word = token;
return(myword);
}
else switch (ch)
{
case '=': m_getch();
if (ch == '=')
{
myword->typenum = 25;
myword->word = "==";
return(myword);
}
retract();
myword->typenum = 25;
myword->word = "=";
return(myword);
break;
case '+': myword->typenum = 13;
myword->word = "+";
return(myword);
break;
case '-': myword->typenum = 14;
myword->word = "-";
return(myword);
break;
case '*': myword->typenum = 15;
myword->word = "*";
return(myword);
break;
case '/': myword->typenum = 16;
myword->word = "/";
return(myword);
break;
case '(': myword->typenum = 27;
myword->word = "(";
return(myword);
break;
case ')': myword->typenum = 28;
myword->word = ")";
return(myword);
break;
case ':': m_getch();
if (ch == '=')
{
myword->typenum = 18;
myword->word = ":=";
return myword;
}
retract();
myword->typenum = 17;
myword->word = ":";
return(myword);
break;
case ';': myword->typenum = 26;
myword->word = ";";
return(myword);
break;
case '#': myword->typenum = 0;
myword->word = "#";
return(myword);
break;
case '>': m_getch();
if (ch == '=')
{
myword->typenum = 24;
myword->word = ">=";
return(myword);
}
retract();
myword->typenum = 23;
myword->word = ">";
return(myword);
break;
case '<': m_getch();
if (ch == '=')
{
myword->typenum = 22;
myword->word = "<=";
return(myword);
}
retract();
myword->typenum = 20;
myword->word = "<";
return(myword);
break;
case '\0': myword->typenum = 1000;
myword->word = "OVER";
return(myword);
break;
default: myword->typenum = -1;
myword->word = "ERROR";
return(myword);
break;
}
}
//def.h文件 定义结构体
typedef struct {
int typenum;
char *word;
}Node,*WORD;
typedef struct HNode{
struct HNode *next;
int num;
char* w;
}LinkList;
运行结果:
这里没有强制要求以#结束,且功能较为简单。此处用C下一篇使用Java编写程序。