简单函数绘图语言解释器:语法分析器

把权力意志放出来

:创造是极客唯一的属性

一、基本思路

这一节讲解语法分析器的构造。

语法分析器的核心:读取词法分析的记号流,利用上下文无关文法识别语句。
关于语句识别的具体细节:上下文无关文法的编程实现是递归下降产生式。由于绘图语言只有四种类型的语句,所以子产生式也分四种:OriginStatement、RotStatement、ScaleStatement、ForStatement,这四个产生式分别解释一种语句规则。
另外重要的是关于表达式的产生式,它解释表达式的构造规则:表达式允许出现常数、参数、运算符和函数,并且拥有运算优先级。那么就构造出五种优先级依次上升的产生式:Expression、Term、Factor、Component、Atom。

语法分析要么识别出一个合法的语句,要么报出语法错误。

二、代码实现

语法分析器头文件parse.h

#pragma once
#ifndef PARSE_H
#define PARSE_H
#include"scanner.h"

//全局变量区
struct Token token;
double Parameter;

//数据结构区
typedef double(*FuncPtr)(double);

// 表达式节点
struct ExprNode
{
   
	enum Token_Type OpCode;//记号种类
	union {
   
		struct {
   
			struct ExprNode *Left, *Right;
		}CaseOperator;//二元运算

		struct {
   
			struct ExprNode *Child;
			FuncPtr MathFuncPtr;
		}CaseFunc;//函数调用

		double CaseConst;//常数,绑定右值
		double *CaseParmPtr;//参数T,绑定左值
	}Content;
};


//函数区
void Parser(char *SrcFilePtr);//语法分析主程序

//主函数:产生式(语句级)逻辑区
void Program();
void Statement();
void OriginStatment();
void RotStatement();
void ScaleStatment();
void ForStatement();

//主函数:产生式(表达式级)逻辑区
struct ExprNode * Expression();
struct ExprNode * Term();
struct ExprNode * Factor();
struct ExprNode * Component();
struct ExprNode * Atom();

//构建语法树
struct ExprNode * MakeExprNode(enum Token_Type opcode,...);

//辅助函数
void FetchToken();
void MatchToken(enum Token_Type AToken);
void SyntaxError(int case_of);

//测试函数
void PrintSyntaxTree(struct ExprNode *root, int indent);//打印表达式的语法树


#endif

语法分析器实现文件parse.c

#include"parse.h"

//函数区
void Parser(char *SrcFilePtr) {
   
	/*语法分析主程序:
	调用词法分析器的GetToken函数(封装在FetchToken中)返回记号,
	 然后使用核心产生式program()对记号流进行递归下降分析,
	 判断记号流的结构是否符合文法规则
	*/
	if (!initScanner(SrcFilePtr)) {
   
		printf("open Source File Error!\n");
		return;
	}
	FetchToken();//返回的记号存放在全局变量token中
	Program();//递归下降的核心产生式
	closeScanner();
}

//主函数:产生式(语句级)逻辑区
void Program() {
   
	while (token.type != NONTOKEN) {
   //词法分析器输出NONTOKEN表示已达记号流末尾
		Statement();//匹配一条语句
		MatchToken(SEMICO);
	}
}

void Statement() {
   
	switch (token.type)
	{
   
	case ORIGIN:OriginStatment(); break;
	case ROT:RotStatement(); break;
	case SCALE:ScaleStatment(); break;
	case FOR:ForStatement(); break;
	default:SyntaxError(2);
	}
}

void
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值