第十二次作业--递归下降语法分析

一、实验目的:

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

 

二、实验原理

每个非终结符都对应一个子程序。

该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

  • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
  • 每遇到一个非终结符,则调用相应的子程序

 

三、实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

例如:

输入begin a:=9;x:=2*3;b:=a+x end #

输出success

输入x:=a+b*c  end #

输出‘end' error

 

四、实验步骤

      1.待分析的语言的语法(参考P90)

      2.将其改为文法表示,至少包含

–语句

–条件

–表达式

3. 消除其左递归

4. 提取公共左因子

5. SELECT集计算

6. LL(1)文法判断

7. 递归下降分析程序

这次的语法分析程序,融合了上次的语法分析程序,先要通过词法分析才能进行语法分析。

语法分析如下

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class LexicalAnalysis {
static String[] keyWords=new String[]{"main","if","then","while","do","static",
"int","double","struct","break","else",
"long","switch","case","typedef","char",
"return","const","float","short","continue",
"for","void","sizeof"}; //关键字种别码从1开始
static char ch;
static int syn, sum=0, row;
static String str="";
static char Str[] ;
static StringBuilder word=new StringBuilder(""); //建立StringBuilder,方便读取文字信息追加
static boolean result=true;
static int index;
static int bgindex=0;
static boolean grmResult=true;
public static void main(String[] args) {
index=0;
row=1;//从第一行开始扫描
System.out.println("请输入一段C语言源程序字符串(以#符号结束):");
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
try{
do{
String testStr;
testStr=bf.readLine();
str+=testStr;
ch=testStr.charAt(testStr.length()-1); //读到单词最后一个字符
}while(ch!='#');
}catch(IOException e){
e.printStackTrace();
}
index=0; //重置单词字符索引
GrammaticalAnalysis();
}
public static boolean Result(){
while (syn!=0){
Analyzer();
if (syn==-1) {
result=false;
break;
}
}
if (result==false){
System.out.println("词法分析不通过!!!");
}else {
System.out.println("词法分析通过!!!");
}
return result;
}

public static void Analyzer(){
//将单词容器清空
word.delete(0, word.length());
ch=str.charAt(index++);//获取单词每一个字符
//跳过空格
while(ch==' '){
ch=str.charAt(index++);
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ //判断是关键字还是标识符
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
word.append(ch);
ch=str.charAt(index++);
}
index--; //回退标记
syn=25;
String s=word.toString();
//判断为关键字
for(int i=0; i<keyWords.length; i++){
if(s.equals(keyWords[i])){
syn=i+1;
break;
}
}
}
//判断为是数字
else if((ch>='0'&&ch<='9')){
sum=0;
while((ch>='0'&&ch<='9')){
sum=sum*10+ch-'0';
ch=str.charAt(index++);
}
index--;
syn=26;
}
//判断为各种字符
else switch(ch){

case '<':
word.append(ch);
ch=str.charAt(index++);
//判断是否是<=
if(ch=='='){
word.append(ch);
syn=35;
}
//判断是否是<>
else if(ch=='>'){
word.append(ch);
syn=34;
}
//判断为<
else{
syn=33;
index--;
}
break;
case '>':
word.append(ch);
ch=str.charAt(index++);
//判断是否是>=
if(ch=='='){
word.append(ch);
syn=37;
}
//判断是>
else{
syn=36;
index--;
}
break;
case '*':
word.append(ch);
ch=str.charAt(index++);
//判断是否是**
if(ch=='*'){
word.append(ch);
syn=31;
}
//判断是*
else{
syn=13;
index--;
}
break;
case '=':
word.append(ch);
ch=str.charAt(index++);
//判断是否是==
if(ch=='='){
syn=32;
word.append(ch);
}
//判断是=
else{
syn=38;
index--;
}
break;
case '/':
word.append(ch);
ch=str.charAt(index++);
//判断是否是注释
if(ch=='/'){
while(ch!=' '){
ch=str.charAt(index++); //判断里面是否有空格
}
syn=-2;
break;
}
//判断是/
else{
syn=30;
index--;
}
break;
//判断是+
case '+':
syn=27;
word.append(ch);
break;
//判断是-
case '-':
syn=28;
word.append(ch);
break;
//判断是;
case ';':
syn=41;
word.append(ch);
break;
//判断是(
case '(':
syn=42;
word.append(ch);
break;
//判断是)
case ')':
syn=43;
word.append(ch);
break;
//判断是#
case '#':
syn=0;
word.append(ch);
break;
//判断是回车
case '\n':
syn=-2;
word.append(ch);
break;
//没有种别码
default:
syn=-1;
}
}
//语法分析程序
public static void GrammaticalAnalysis(){
Analyzer();
if (Result()==true&&str.endsWith("#")){
System.out.println("进入语法分析");
Str = str.toCharArray();//将键盘输入的程序转为字符数组
ParseE();
}else {
System.out.print("词法有误!");
}
}
static void ParseE(){
ParseT();
ParseE1();
System.out.println("语法分析结果:\n");
if (grmResult){
System.out.println("Success!");
}else {
System.out.println("语法分析不通过!");
}
}

private static void ParseE1() {
switch (Str[bgindex]){
case '+':
bgindex+=1;
ParseT();
ParseE1();
break;
case '#':
break;
case ')':
bgindex+=1;
break;
default:
System.out.println("出现语法错误!");
grmResult=false;
System.exit(0);
break;
}
}

private static void ParseT1() {
switch (Str[bgindex]){
case '*':
bgindex+=1;
ParseF();
ParseT1();
break;
case '#':
break;
case ')':
bgindex+=1;
break;
case '+':
break;
default:
System.out.println("出现语法错误!");
grmResult=false;
System.exit(0);
break;
}
}

private static void ParseF() {
switch (Str[bgindex]){
case '(':
bgindex+=1;
ParseE();
break;
case 'i':
bgindex+=1;
break;
default:
System.out.println("出现语法错误!");
grmResult=false;
System.exit(0);
}
}

private static void ParseT() {
ParseF();
ParseT1();
}
}

 结果截图:

 

 

 

 

posted @ 2019-11-28 15:53  codekid  阅读(251)  评论(0)    收藏  举报