2023.3.8
- SimpleExprRules.g4
- lexer grammar SimpleExprRules:
- 将语法的部分与词法的部分解耦合
- 如果词法需要用到,则import SimpleExprRules
- lexer grammar SimpleExprRules:
- 交互:
- SimpleExpr.g4 @header{package simpleexpr;} header:在里面的写的代码,会被原封不动拷贝到.java文件
- 驱动的main函数
- 手写词法分析器:
- 语言和集合:字母表上定义语言
- 字母表:有限的符号集合,Σ
- 串:符号构成的有穷集合, ε表示空串,空串的长度为0
- 语言:给定字母表上一个任意的可数的串的集合,可以通过集合操作构造新的语言
- 什么都没有的语言和有一个空串的语言的区别,见PPT
- 连接:类似笛卡尔积 x= dog , y= house ---> xy=doghouse
- Kleene闭包:广义的并,类似.g4中的* L*
- 正闭包:类似+ L+
- id:L(L ∪ D)* 如果L为26+26a-zA-Z个字母,D为0-9,则L(L ∪ D)*第一位是字母,加上任意多个0-9a-zA-Z
- 正则表达式是语法,正则语言是语义,每个正则表达式对应一个正则语言
- 正则表达式:
- 定义:
- 正则表达式是语法,正则语言是语义,每个正则表达式r对应一个正则语言(集合)L(r)
- 空 :空串是正则表达式
- a :字母表中任何一个符号自身,也是正则表达式
- (a) :a是正则表达式,则加一个括号还是正则表达式
- r|s,rs,r* : r和s也是正则表达式,做或| 、拼接、*等运算还是正则表达式
- 优先级:() > * > 连接 > |
- 对应的正则语言:
- {空串} = L(ε)
- {a} = L(a)
- 括号可以去掉,语言一样 L((R)) = L(R)
- |对应并,拼接对应拼接,闭包对应语言上的闭包
- PPT上的简单例子
- 匹配三的倍数:(0|(1(01*0)*1))* 自动机理论学习后更加容易理解
- R1/R2 : 后面跟着指定R2才返回匹配到的R1
- 正则表达式的例子:
- 匹配所有的颜色,六位十六进制数字:[0-9a-fA-F]{6} 中括号{}中6表示6位
- 一位数或两位数x2 + 至少是两位数,时间识别: \d{1,2}[-\/]\d{1,2}[-\/]\d{2,4} \/是转义 \d表示是数字
- 小数点前>=100,并且要有$,小数点后2位: \$\d{3, }\.\d{2} {}中只写一边3表示>=3
- 匹配完整的单词而不是某个单词中间出现的符合的部分:\bcat\b \b表示boundry界限
- 匹配正常的html格式,匹配只返回标签之内的内容: (?<= < ( [hH][1-6] ) >).*? (?= < \/[hH]\1 >) 一般来说.*都要考虑会不会贪婪匹配\n,需不需要加上?非贪婪匹配 反向引用:后面匹配的内容与前面的有关,需要引用前面的 ()括起来的是值表达式,后面可以引用,按照下标访问 (?= xxx )表示向后看,后面是否是xxx (?<= xxx)表示向前看是否为xxx,xxx不返回(?)叫做look around
- regex101: build, test, and debug regex
- 正则表达式 – 语法 | 菜鸟教程 (runoob.com)
- 定义:
- 手写词法分析器:
- 整体框架:
- LA(0) : WS(空白符), EOF(结束符), ID, INT, UNKNOWN(出错)
- LA(1) : IF ELSE ID INT
- LA(2) : EQ, NE<>, LT<, GT<=, GE>=
- arbitrary LA:
- nextToken() while(nextToken())
- ws: 直接扔掉就行 advance()
- id: while扫描 用stringbuilder 保存,peek最后到第一个非字母非数字,查关键字表是否是关键字,不是关键字,则返回为一个id
while扫描 用stringbuilder 保存,返回为一个int- relop 和other 错误处理
- int real 和sci :不同的stringbuilder收集
不同的数字部分- 用while中switch做状态切换
- 以下逻辑有缺,可能有误
- 用两个变量记录,intPos和realPos。14,16,17,
- 13:intPos = pos,已经将12数字加入,如果还是数字,则加入intstr;如果是小数点 . ,则用realstr记录,跳转;如果是Ee,则用scistr记录,跳转16;如果是other,则return int。
- 14:如果还是数字,则加入realstr;回退:intPos,intstr
- 15:realPos = pos,如果还是数字,则加入realstr;如果是other,则return real,intstr和realstr拼接;如果Ee,则scistr;
- 16:如果还是数字,则加入scistr;如果是+-,则scistr;可能会回退到15或者13,realstr为空则返回13,return intstr;不为空return intstr+realstr。
- 17:如果还是数字,则加入scistr;reset
- 18:如果还是数字,则加入scistr;如果是other,则return real,intstr和realstr和scistr拼接;
- Reset回退:this.pos = 传入pos; this.peek = input.charAt(pos);
2023.3.10自动机理论
- 手写词法分析器:
- 状态转移图:往前走,调整状态,记录关键点,不符合就回溯
- 自动机automaton automata:
- 状态集和状态转移函数
- NFA:
- 非确定性有穷自动机nondeteministic finite automaton
- 定义:
- 字母表Σ
- 有穷状态集合S
- 唯一的初始状态S0∈S
- 状态转移函数δ
- 接收状态集合F包含于S
- 非确定性:当处于某状态,看到字母a,可能转移到其他状态,也可能还保持原来的状态;当处于某状态,在不看到任何字符情况下,可以自发的转移到其他状态。(图中补上一个ε转移)
如果画出的示意图缺少某些状态转移条件与转移后状态,那就是默认是转移到一个空状态∅上。约定: 所有没有对应出边的字符默认指向一个不存在的 “空状态” ∅- P与np(非确定多项式)
- 定义:(接受 (Accept)) (非确定性) 有穷自动机 A 接受字符串 x, 当且仅当存在一条从开始状态 s0 到某个接受状态 f ∈ F、标号为 x 的路径。因此, A 定义了一种语言 L(A): 它能接受的所有字符串构成的集合。