20221021服务器初始化ilo+esxi+openwert软路由配置

背景

见 https://blog.hylstudio.cn/archives/1022

服务器到货后直播初始化,有同学想看我翻车hhh

网络拓扑设计

连线

略  两根电源+3根网线,按设计网络拓扑连接即可

ilo远程接管

网络设置

把电脑的网卡IP设定到和ilo网口相同的子网后可通过443端口进入ilo网页,密码在服务器上印着

进入iLO Dedicated Network Port – IPv4 Settings

勾选 

 


点击Submit后并不会生效,修改时间后一同保存重启ilo

修改BIOS时间

进入iLO Dedicated Network Port – SNTP Settings
修改时间服务器地址为ntp.tencent.com,这里直接用腾讯云的
时区选择GMT+8
点击Submit后并不会生效,按提示点击reset重启ilo后生效
重启过程时间不一定,可以开长ping访问ilo端口的IP,能ping通了网页上也就能登录了
按下图创建自己常用的账户

raid

服务器raid的配置是在服务器启动时候配置,无情开评的小伙伴帮忙配好了raid5,为了防止服务器大晚上起飞还是先不看了

看了下从esxi里已经是一块硬盘了,建立的VMFS6,因此从esxi暴露iSCSI给nas的方案pass。目前的这个配置下会更复杂,如果想省心继续使用群晖系统,还是寻找新的方式从这组raid5上抠出来一块挂到nas上比较方便省事。虽然我继续可以选择iSCSI,但nfs也不是不行,到时候测下速度看看哪个好搞就搞哪个方案,nfs兜底肯定能搞定

远程接管esxi

进入iLO Overview

点击Integrated Remote Console  后面的Java Web Start 进入虚拟控制台

无情开评的小伙伴已经装好了esxi,进入这个页面可看到esxi用的网口和静态IP

按F2进入系统设置,第一次先输入密码,然而看着密码输入框的我一脸懵逼。。大哥并没告诉我esxi密码啊啊啊啊,问了下拿到后才登录。这里差评,到货都3天了都没想起来告诉我一下这个的密码,还要我主动问!!

说好的什么都没配置呢(

第二次会进入这样的页面,按回车修改IP地址后重启管理网即可通过443端口进入esxi管理页面

进入网页后即可正常使用,按下图进入用户添加,输入自己常用的用户名添加身份

进入主机-权限-给自己添加管理员后即可使用自己账户登录

虚拟机

剩下的就是新建虚拟机了,这部分没啥好说的,基本上就是大号的Vmware,会用vmware就会用这个

为了测试虚拟交换机我配置对了没,搞一个虚拟机win10接到不同的虚拟交换机上看看IP就知道了,拓扑看上面的图就行

顺带一提网页版的esxi控制台做的还是很NB的,不知道是不是内网造成的错觉,但感觉远程的体验完爆各种vnc

硬盘速度很给力,装win10进度条从0到100只花了大概2分钟

要是啥硬件装系统都是这个速度,我就再也不怕重装系统折腾了

虚拟交换机

混杂模式 是否允许交换机上的虚机看到其他vlan流量

MAC 地址更改  是否允许交换机上的虚机修改自己的MAC地址

伪传输 懒得看了,总之也是和MAC地址有关系,留给网工的研究去吧,总之除了存储iSCSI之外都选否就对了

按之前的设计有4个子网,但iSCSI的没找到明显入口就先放弃了。默认自带一个虚拟交换机了当作管理网,再新建两个交换机当作公网和测试内网

管理网,IP为0.x

模拟公网,IP为1.x

测试网,IP为2.x

新建跳板机,添加三个网卡分别接到admin public test中,通过控制面板的状态即可看到是否拿到了正确的地址

到这里开始对我来说难度就逐渐下降了,比较软件才是我的专业=-=

断开所有网卡连接后依次连接admin public test,分别测试网络连通性

效果:连接test的网卡一定没网,连接admin和public的网卡和直接把线插到光猫和路由器上一样,只不过是虚拟的

有了跳板机,接下来就可以方便的配置软路由了,因为软路由无实体且方便的配置方法都在网页上,命令行操作不便,一定会借助这个跳板机

目前图里跳板机连接了公网入口,当软路由配置完成后直接断开public的那张网卡连接即可满足我的安全需求

openwrt

固件下载

官网 https://downloads.openwrt.org/releases/22.03.2/targets/x86/64/

lede https://github.com/coolsnowwolf/lede/releases

注意,generic-ext4-combined-efi.img.gz 下载后的img需要用磁盘格式转换工具,如StarWind V2V Conterver

转成vmdk上传到raw下

esxi开启ssh后后执行vmkfstools -i raw/xxx.vmdk xxx.vmdk

raw/xxx.vmdk raw/xxx-flat.vmdk会复制一份到当前目录 xxx.vmdk和xxx-flat.vmdk

用转换后的vmdk新建虚拟机后即可调整磁盘容量

我先后尝试了官网版和lede版本,发现lede版本的功能更多些,虽然不知道用不用的上,但还是用了lede的

按网口顺序增加/etc/config/network的配置,我这里是两个wan 一个lan,观察windows连接到lan网卡是否正常即可完成软路由初始化

中间如果出现问题,配合ping和tracert排除故障即可(这部分才是最恶心的,软工出身的我配置路由器和交换机真的头疼,硬件命令行还好,纯软件模拟的根本搞不清楚对应关系hhhh)

注意下双wan口通过/etc/config/network配置之后有几率无法上网,需要先通过网页上把新加的第二个wan划到防火墙的wan zone里

配置参考如下

能耗

进入ilo的电源管理,选择Static Low Power Mode

进入esxi的电源管理,选择低能耗

通过ilo可观察服务器功率

nas扩容

居然已经快三点了,还是直播原神日常吧hhhh这次是真日常

https://blog.hylstudio.cn/archives/1078 

虚机测试环境

有了隔离的子网后,就可以搭建任意的服务器折腾学习了

见后续文章

参考文档

http://hzhcontrols.com/new-206249.html

https://wenku.baidu.com/view/629900cd142ded630b1c59eef8c75fbfc77d94d4.html

20221015新nas&私有云实验环境规划

背景

因原群晖已经试用了3年并且是单盘,考虑到数据风险决定对它做升级。本来在B站无情开评看到的FusionCube 500完美满足我的需求,但询问售价后果断放弃hhhhh根本不是个人用户能玩得起的设备。但也是因此机缘巧合发现无情开评居然承接个人业务需求,他们负责硬件组装和虚拟化平台配置,服务周到省心省力,欢迎有兴趣但懒得自己折腾的同学联系他们帮忙,比自己折腾要方便的多。就这样我又多了一台服务器,在到货之前提前设计下网络结构和软件结构

目标

1.保证家里其他人的IPTV、无线设备的正常使用,即使服务器挂掉也不应该影响原有网络结构

2.加强nas上数据的安全性,重要数据利用nas自带功能备份一份到新的服务器上

3.创建新子网3和4,子网3与光猫相连赋予公网访问权,子网4和公网隔离但能通过子网2访问,虚拟化一个软路由方便控制子网3和4下虚机

4.剩余资源搭建一个分布式的私有实验环境放到子网4,满足我对开源软件和分布式软件开发和测试的需求,解放我的台式机。后面也许就有机会做各种实验了

5.基础网络安全防护,内网随意折腾但从公网无法轻易穿透到内网

 

网络结构设计

现网络结构

相关设备如下,为了网络安全不暴露具体设备型号信息

1.光猫

2.无线路由器

3.群晖nas

4.iptv

5.手机、电脑、平板等无线客户端

目前nas上和一个台式机上运行着tailscale,配合ipv6可以让我随时从公网穿透回子网2做操作,虽然麻烦了点但足够安全。

其余需要对外暴露的端口均通过光猫和无线路由器人工配置端口和协议范围,可以满足公网上手机和电脑对nas的访问需求

新网络结构

看了下服务器文档,有4个千兆口/可选两个万兆口,如果实际到货有2个以上接口的话,可以考虑把nas改为接到服务器下面,剩下的接光猫使用,(为了nas稳定使用还是算了,等服务器运行稳定了再考虑把nas挂到服务器下面用软路由精细控制流量)

nas本身的加强因预留了足够的磁盘空间,并且无情开评会帮忙配置好磁盘阵列,因此我只需要划一部分空间给nas就行了。这部分既可以开个linux,也可以到时候优先看看能不能直接在ESXI里通过iSCSI搞定。这样还可以继续使用群晖正版系统,虽然理论上可以把我的白群转到虚拟化里做”黑”群,但我懒得折腾还是算了,等nas的磁盘坏了再考虑

个人电脑都在子网2下操作子网4的路径待设计,想避免出现网络故障还要满足子网4一定的隔离和访问需求,不是网工专业的我设计这玩意真的头疼= = 实在搞不定到时候再问问同学吧hhh

服务器的管理口和esxi的管理口都放到子网2下

服务器软件集群设计

TODO

群晖扩容

远程磁盘创建

TODO in ESXI

远程磁盘挂载

群晖本身的DSM只看到了FTP SFTP WebDav CIFS NFS这几种协议来远程挂载,没看到能把DSM当作iscsi的客户端的,网上能找到的资料都是把DSM当作iscsi服务器来使用。之所以选择iscsi是因为不想再创建一个虚拟机来提供FTP SFTP WebDav CIFS NFS这些协议转换,尽可能使用ESXI本身的虚拟化能力,减少后期维护成本

但尝试登陆群晖命令行后执行iscsiadm 是可以的,因此将尝试直接用命令行挂载

TODO

 

20220908编译原理读书笔记

 

 

 

20220908编译原理读书笔记
前言

为啥我今天又开始读书了呢?是因为昨天拔牙之后持续的疼痛让我无法集中注意力工作,但睡觉也是有限度的,否则结果就是3点多还睡不着,依然煎熬。这种疼痛不剧烈但持久,让又人无法忽视。。。。简直是煎熬
还是找点事情分散下注意力吧,某博建议刷114514的题并没有找到这个题号(逃
还是读书吧,也许在我全神贯注的打字时可以让编译原理的复杂性来减轻我的精神负担

4. 自顶向下语法分析方法

语法分析分为自顶向下和自底向上的语法分析,还可以分为确定分析和不确定分析
本篇为确定的自顶向下分析
这种分析也成为面向目标的分析方法

4.1. 思路

从开始符号,根据当前的输入符号,寻找唯一确定的产生式,替换非终结符
如果输入的符号在满足<使用某个生成式的条件>,则就使用这个生成式
简易想法是,给每个生成式生成互不相交的符号集合,根据当前输入在哪个集合里就选取哪个生成式
这个想法贯穿到最终的SELECT集合定义,书本没说,这里提前提出方便理解FIRST集和FOLLOW集的由来
注意,这里的符号不再是单一字母,而是经过词法分析输出的token串,英文为symbol

例1 文法G1[S]:
S->pA|qB
A->cAd|a
B->dB|b
给定输入串W=pccadd,注:教科书这里其实是为了简化,所以用的都是单字母,实际一个字母对应一个symbol

推导过程显然为S->pA->pcAd->pccAdd->pccadd

例2 文法G2[S]:
S->Ap
S->Bq
A->a
A->cA
B->b
B->dB
给定输入串W=ccap

推导过程为S->Ap->cAp->ccAp->ccap
第一步选择S->Ap的原因为A->cA的右侧存在c开头的非终结符
人肉还可以比较容易的看到,但对机器来说不那么容易,需要总结规则
因此如果能知道S->Ap的第一个非终结符是什么就好了
因此定义FIRST集合如下:
设G=(Vt,Vn,P,S)是上下文无关文法
FIRST(t)={t|t=>* aq, t ∈ Vt, t,q ∈ V*}
称FIRST(t)为t的开始符号集或首符号集

给定文法G[S]:
S->aA
S->d
A->bAS
A->NULL
给定输入串W=abd
S->aA->abAS->abNULLS->abNULLd
当面临输入d时,因A的FIRST集里只有b和NULL,不包含d,因此只能认为d的匹配依赖于A后面的符号,因此选择A->NULL
同理找规律,如果我们可以直接知道d可以是A后面首个终结符,那是不是就可以直接选取确定的一个生成式了?
FOLLOW集定义也就是这样,数学表达比较抽象,懒得打了
结合FIRST和FOLLOW集合即可定义SELECT集合,前面的数学证明可保证生成的SELECT集合互不相交

设G=(Vt,Vn,P,S)是上下文无关文法
给定产生式A->t,A是终结符,t属于V的*闭包
若t无法推出空NULL,则SELECT(A->t) = FIRST(t)
显然嘛,没有空的干扰,就直接是第一个非终结符
若t可以推出空NULL,则SELECT(A->t) = (FIRST(t) – {NULL}) ∪ FOLLOW(A)
这个也好理解,排除掉NULL的干扰后,再继续往后寻找A后面的第一个非终结符就行了

LL1文法指的是,从左L到右扫描使用最左L推导,每次往后看1个符号
条件是,对于相同非终结符的两个产生式A->t A->q, 满足SELECT(A->t)∩SELECT(A->q) = {空集}

对于FIRST FOLLOW SELECT集合的生成,纯粹就是力气活了。。。细节不再赘述,相信编程能力过关的同学都能正确实现,这里说思路。可能需要多次扫描才能完成
1.求出能推出NULL的非终结符
2.计算FIRST集合,这里可以根据定义计算,使用迭代法使得每个FIRST集合不再增大即可结束
也可以使用图论的算法计算,思路类似,在图上使用增广做标记即可
3.计算FOLLOW集合,同理也是根据定义计算,使用迭代法使得每个FOLLOW集合不再增大即可结束
也可以使用图论的算法计算,思路类似,在图上使用增广做标记即可
4.计算SELECE集合,根据前面的计算结果合并生成

4.3 非LL1文法到LL1文法的等价变换

4.3.1.提取左公因子

4.3.2.消除左递归

4.4 不确定性的自顶向下分析


mark
当前86页

 

国内运行coder的坑

https://github.com/coder/coder

git clone && cd coder

在docker-compose.yaml中给postgres增加privileged: true,防止数据库出错

export CODER_ACCESS_URL=http://YOUR_IP:7080

docker-compose up

启动后注册

找个客户端安装coder的cli后按https://coder.com/docs/coder-oss/latest/templates创建模板

先用bare测试,执行coder template create后会报错

bare的模板上传后会报错,进容器

ps aux 可以看到执行了 /tmp/coder-cache/terraform init -no-color -input=false

通过ps aux获取PID后执行 ls -hal $PID/cwd

可以看到在provisionerd开头的文件夹下有客户端上传的文件,趁着失败之前复制走好手动测试

可以看到国内的网络执行terraform init一定会卡,fuck

参考这些尝试中

https://cloud.tencent.com/developer/article/1987762

https://developer.aliyun.com/article/713099

https://developer.aliyun.com/article/723935

 

coder实现了terraform的provider,来管理自己的资源

https://github.com/coder/terraform-provider-coder

20220731lamda表达式中的方法调用识别

psi过滤直接用JavaRecursiveElementVisitor过滤PsiMethodCallExpression会发现只识别到了collect的调用

因为JavaRecursiveElementVisitor的逻辑是当一个节点满足要求后,下一个继续的节点是nextSibing

因此需要增加特殊逻辑,当第一层PsiMethodCallExpression被匹配到后,需要递归在PsiReferenceExpression继续寻找,需要把PsiReferenceExpression+PsiReferenceParameterList中的lamda表达式以及其中的方法调用和方法引用都找出来,这里只写方法调用,方法引用也是一样的套路

 

不知道jetbrains有没有类似的工具类做这种深度搜索,代码太多了懒得看,就先这么写着,附语义树如下

完整代码,更新中

20220721数据库基础-谓词逻辑转写sql

20220721数据库原理
同事在学数据库,问我这个题,重新总结下我上学时候的经典套路
这个套路针对任意存在性和任意性判定的sql编写或集合运算,当时数据库老师疯狂改题目条件,导致sql毫无规律且从字面含义上难以正向理解运算逻辑。为了考试以不变应万变总结了这个套路,核心思想是不要纠结于最终sql的语法表达,而是通过逻辑化简来确保集合元素的正确性,化简后再转写成sql
主要运用集合论、关系代数基础以及离散数学的谓词逻辑,这些应该是我要做sql自动生成和优化的理论基础
题目经典的三张表如下
学生表s(sid,sname)
课程表c(cid,cname)
选课关系表sc(scid,sid,cid)
求至少学过lz同学学过所有课程的同学的学号
编写过程如下
首先做形式化表达和逻辑化简,原则:逻辑取反极可能少,尽可能使用存在性判断
谓词逻辑定义f(x,y) = 学生x选择了课程y
{x|对任意y,f(lz,y)->f(x,y)}
–逆否命题
{x|!(存在y,!(f(lz,y) -> f(x,y)))}
–蕴含等值 p->q === !p||q
{x|!(存在y,!(!f(lz,y) || f(x,y)))}
{x|对任意x,!(存在y,!(!f(lz,y) || f(x,y)))}
–等价替换
{x|!(存在y,(f(lz,y) && !f(x,y)))}
{x|对任意x,!(存在y,(f(lz,y) && !f(x,y)))}
–对任意x
select sc.sid from sc where 1=1
— f(x,y)
exists (
    select * from sc where sc.sid = x and sc.cid = y
)
— f(lz,y)
exists (
    select * from sc where sc.sid = ‘lz’ and sc.cid = y
)
— 存在y, (f(lz,y) && !f(x,y))
exists (– 存在y, 取y = sc1.cid  看作是定值,但要注意给表加别名
    select sc1.cid from sc sc1 where exists (
        select * from sc sc2 where sc2.sid = ‘lz’ and sc2.cid = sc1.cid –f(lz,y)
    )
    and not exists ( –!f(x,y)
        select * from sc sc3 where sc3.sid = x and sc3.cid = sc1.cid
    )
)
— 对任意x, 取x = sc0.sid
select * from sc sc0 where not exists (
    select sc1.cid from sc sc1 where exists (
        select * from sc sc2 where sc2.sid = ‘lz’ and sc2.cid = sc1.cid
    )
    and not exists (
        select * from sc sc3 where sc3.sid = sc0.sid and sc3.cid = sc1.cid
    )
)
— 从来没有人告诉我存在这样一个化简的过程,这个方法多年间也未曾见到有人和我讲过,以上中间过程我翻遍了互联网也没找到。这是我上学时候应对考试用的通解套路,工作后好久没这么详细的写过sql转写了,简单的业务都是直接写sql结果而快忘却了正确的通解解法
— 在exists内select sc1.cid和select *是一样的,判定结果只看行数,但语义完全不一样,如果是从谓词逻辑转来的不应该都是*
— 另外,从exists子句转为where子句是容易的,反过来理论上也一样,但网上的所谓教程根本不会讲这个是怎么来的
— 因子句存在永真式sc1.cid = sc1.cid 且 存在性判定可由where条件代替一次子查询
— 所以接下来才是你在网上轻易看到的答案格式,也就是课本或老师PPT给的的答案
exists (– y sc1.cid
    select sc1.cid from sc sc1 where sc1.sid = ‘lz’ and sc1.cid = sc1.cid –f(lz,y)
    and not exists ( — !f(x,y)
        select * from sc sc2 where sc2.sid = x and sc2.cid = sc1.cid
    )
)
–投影输出结果
select sc0.sid from sc sc0 where not exists (
     select sc1.cid from sc sc1 where sc1.sid = ‘lz’ and not exists (
        select * from sc sc2 where sc2.cid = sc1.cid and sc0.sid = sc2.sid
    )
)
–等价答案
— {x|对任意x,!(存在y,!(!f(lz,y) || f(x,y)))}
exists (– 存在y, 取y = sc1.cid  看作是定值,但要注意给表加别名
    select sc1.cid from sc sc1 where not(
        not exists (
            select * from sc sc2 where sc2.sid = ‘lz’ and sc2.cid = sc1.cid –f(lz,y)
        )
        or
        exists ( –f(x,y)
            select * from sc sc3 where sc3.sid = x and sc3.cid = sc1.cid
        )
    )
)
— 对任意x, 取x = sc0.sid
select * from sc sc0 where not (
    exists (– 存在y, 取y = sc1.cid  看作是定值,但要注意给表加别名
        select sc1.cid from sc sc1 where not (
            not exists (
                select * from sc sc2 where sc2.sid = ‘lz’ and sc2.cid = sc1.cid — f(lz,y)
            )
            or
            exists ( — f(x,y)
                select * from sc sc3 where sc3.sid = sc0.sid and sc3.cid = sc1.cid
            )
        )
    )
)
— 投影输出略
— 语义分析
sc0.sid = sc2.sid的子查询条件字面意义上是扫描了sc的每一行来分别做两次集合的存在性判定
第1行数据执行
id sid cid
sc0 1 lz 1
select sc0.sid from sc sc0 where not exists (
    select * from sc sc1 where sc1.sid = ‘lz’ and not exists (
        select * from sc sc2 where sc2.cid = 1 and ‘lz’ = sc2.sid
    )
)
select sc0.sid from sc sc0 where not exists (
    select * from sc sc1 where sc1.sid = ‘lz’ and not true
)
select sc0.sid from sc sc0 where not exists (
    empty
)
select sc0.sid from sc sc0 where true
1 lz 1输出
CREATE DATABASE test;
use test;
CREATE TABLE sc (
    id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
    sid varchar(255),
    cid varchar(255)
);
INSERT INTO sc(sid,cid) VALUES
('lz', '1'),
('lz', '2'),
('a', '1'),
('b', '2'),
('c', '1'),
('c', '2'),
('c', '3')
;
SELECT * FROM sc;
+----+------+------+
| id | sid  | cid  |
+----+------+------+
|  1 | lz   | 1    |
|  2 | lz   | 2    |
|  3 | a    | 1    |
|  4 | b    | 2    |
|  5 | c    | 1    |
|  6 | c    | 2    |
|  7 | c    | 3    |
+----+------+------+
7 rows in set (0.00 sec)

20220628编译原理读书笔记

 

 

 

 

20220628编译原理读书笔记

2.5 上下文无关文法及其语法树

给定文法G=(Vn,Vt,P,S)
语法树又称推导树,定义:
1.每个节点都有一个标记属于V
2.根节点是S
3.若一个节点n至少有一个它自己除外的子孙A,则A肯定属于Vn
4.若节点n的直接子孙从左到右为n1,n2,…n,则n=>n1,n2,…n是P中的产生式

推导过程不唯一
若每一步都是对左部最左的Vn替换则称为最左推导,反之是最右推导
形式语言中最右推导被叫做规范推导,所得句型叫规范句型或最右句型

若一个文法存在多个语法树,则称这个文法是二义的
判定给定的上下文无关文法是否是二义的,或它是否产生一个先天二义的语言,这两个问题递归不可解

2.6 句型分析

自顶向下、自底向上

3 词法分析

虽然词法和语法可以同时放到文法描述里,但一半实现时候都是独立做词法分析

常见分类
标识符、字母数字、整数、运算符、等号、界符

正则表达式可以方便的描述词法规则,且正则表达式和正规文法都能定义语言,且有时候表达更加方便


A->xB,B->y => A = xy
A->xA|y => A = x*y
A->x, A->y => A = x|y

3.4 有穷自动机

确定的有穷自动机DFA,不确定的有穷自动机NFA
M=(K,M,f,S,Z)
K:有穷状态集
M:有穷字母表
f:转换函数,是K和M的笛卡尔积到K上的映像,用来定义状态转换条件
S:唯一的初态
Z:终态集合,是K的真子集

这里歪个楼,画状态转换图一定要有这几个元素,工作这么久很少见有人完全画对。初始要有一个箭头指向S,Z上的元素要有双层圈标记,每个线段代表转换规则,线上要有M元素的标记

NFA区别就是转换函数在特定状态上可以不唯一
NFA有算法可以转DFA,核心思想是构造确定性的子集

DFA化简,计算入度为0的状态可删除、计算等价状态合并多余的状态

3.5 正则表达式和有穷自动机的等价性

结论是等价,证明略,因此用正则表达式可以直接描述状态机,状态机的实现可由特定算法自动生成结构完整

3.6 正规文法和有穷自动机的等价性

结论是等价的,证明略,经过前面的铺垫,为自动化打下了良好的理论基础

3.7 词法分析器的自动构造工具

这可能是正常途径下接触到的第一个元编程吧。。。。
由前面的铺垫可知,既然等价,那就可以直接用程序生成程序,人工提供规则即可

这里歪个楼介绍下正则表达式基础,其实如果你手写练习过一些正规文法的生成式,就知道正则表达式多简洁了。因为这个概念是数学集合论的,因此正则表达式的写法也和集合闭包几乎一样,掌握基础并不困难

r* 匹配r的星闭包,r出现0次到多次
r+ 匹配r的正闭包,r出现1次到多次
r? 匹配r的任选,r出现0次或1次
r{n} 匹配r的n次幂,r出现n次
r{m,n} 匹配r的m到n次幂,r出现m次到n次闭区间
r{m,} 匹配r的m次幂以上,r出现m次以上闭区间
rs 匹配r和s的连接
r|s 匹配r和s的并集
其余写法均为简写,常见的就这几个

借助lex描述文件可以目标结构的c语言代码,完成词法分析器的自动生成
类似的工具不唯一,可以看看antlr

第4章到第6章都是语法分析的各种方法,有点懒得看了,总之结果是个语法树
我关心的是第7章语法制导的语义计算
也许是明天继续?
mark当前68页