批里批里 (゜-゜)つ🍺 干杯~|

七つ一旋桜

园龄:4年2个月粉丝:6关注:3

Day8 规则引擎 | 青训营笔记

这是我参与「第五届青训营」伴学笔记创作活动的第 8 天

编译原理

词法分析

词法分析就是将代码字符串转换为词法单元的过程

如何识别Token?

有限自动机是一个状态机,他的状态数量是有限的,该状态机在任何一个状态,基于输入的字符都可以做一个确定的状态转换

语法分析

在词法分析的基础上,识别表达式的语法结构

image.png

表达式的语法可以用树来表示,其每个节点是一个语法单元,这个单元的构成规则就是语法

image-20230131132323464

抽象语法树

上下文无关语法

如果语句无需考虑上下文就可以判断正确性,可以使用巴科斯范式(BNF)来表达

exp: add;
add: add '+' mul | mul;						// 加法表达式
mul: mul '*' pri | pri;						// 乘法表达式
pri: string | bool | number | identifier;	// 基础表达式

产生式:一个表达式可以由另外已知类型的表达式或符号推导得到

内置符号: 字面量(string, bool, number) 标识符、运算符

一个基础表达式可以由常量或运算符或标识符组成

一个乘法表达式可以由基础表达式或者乘法表达式 * 基础表达式组成

递归下降算法

递归下降算法是使用自顶向下构造语法树

不断地对Token进行与发展开,展开中可能会遇到递归的情况

image.png 从左往右遍历表达式分析词法结构

exp: log;
log: log('&&'|'||') cmp | cmp
cmp: cmp '>' add | add
add: add '+' mul | mul
mul: mul '*' pri | pri
pri: const | id | (exp)

从左往右遍历price > 500分别将这三个字符串解析为price cmp const 由此这三个字段构成了一个词法单元Token

image.png 最终的词法解析上图

类型检查

  • 类型综合 根据子表达式的类型构造出父表达式的类型,例如表达式(A+B)的类型是根据A和B的类型定义的 这种情况需要提前声明参数的类型,在构造语法树的过程中进行类型检查
    a: int; b:string;
    
  • 编译时检查 & 运行时检查 类型的检查可以在语法树的构造阶段进行,也可以在代码执行时进行 这种情况根据执行时参数的值类型进行类型检查
    a: 100; b: "200";
    

设计规则引擎

目标:支持特定的词法、运算符、数据类型和优先级,并支持预定义语法的规则表达式的编译和执行

词法分析

词法

参数:由字母和下划线组成
布尔值: truefalse
字符串:"abcd"'abcd'ˋabcdˋ
十进制int: 1234
十进制float: 123.4
预定义运算符: + -

运算符

一元运算符: + -
二元运算符: + - * / % > < >= <= == !=
逻辑运算符:&& || !
括号: ()

优先级

image.png

设计词法分析状态机

image.png

可以设计如下的词法

expr: logOr EOF;
logOr: logOr '||' logAnd | logAnd;
logAnd: logAnd '&&' logNot | logNot;
logNot: '!' logNot | cmp;
cmp: cmp '>' add | cmp '>=' add | cmp '<' add | cmp '<=' add | cmp '==' add | cmp '!=' add | add;
add: add '+' mul | add '-' mul | mul;
mul: mul '*' pri | mul '/' pri | mul '%' pri | pri;
pri: BooleanLiteral|IntegerLiteral|FloatLiteral|StringLiteral|Identifier|'('expr')';

优先级的表达

type precedence struct {
    validSymbols []Symbol // 当前优先级的运算符
    nextPrecedence *precedence // 更高一级的优先级
    planner planner // 当前优先级的处理函数
}

语法树

一元运算符:左子树为空,右子树为右操作符 二元运算符:左子树为左操作符,右子树为右操作符 括号:左子树为空,右子树为内部表达式的抽象语法树

语法树的执行和类型检查

执行

定义语法树之后对语法树进行后序遍历,最终得到根节点的值

类型检查

检查时机:执行时检查 在一个节点的左右子节点执行完之后分别校验左右子节点的类型是否符合预设规则

  • >符号要求左右节点的值都存在且都为int或float
  • !符号要求左节点的值为空且右节点的值为bool

本文作者:七つ一旋桜

本文链接:https://www.cnblogs.com/poifa/p/17716919.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   七つ一旋桜  阅读(15)  评论(0编辑  收藏  举报  
历史上的今天:
2022-01-31 acm with ACL(atcoder library)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起