Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
PlayWithCompiler
提交
b660b479
P
PlayWithCompiler
项目概览
后端镜像
/
PlayWithCompiler
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PlayWithCompiler
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b660b479
编写于
9月 20, 2019
作者:
R
Richard Gong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
added LRParser
上级
4efdea4a
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1067 addition
and
153 deletion
+1067
-153
lab/16-18/.idea/workspace.xml
lab/16-18/.idea/workspace.xml
+169
-146
lab/16-18/src/main/java/play/parser/ASTNode.java
lab/16-18/src/main/java/play/parser/ASTNode.java
+6
-0
lab/16-18/src/main/java/play/parser/DFAState.java
lab/16-18/src/main/java/play/parser/DFAState.java
+6
-6
lab/16-18/src/main/java/play/parser/LRParser.java
lab/16-18/src/main/java/play/parser/LRParser.java
+788
-0
lab/16-18/src/main/java/play/parser/Lexer.java
lab/16-18/src/main/java/play/parser/Lexer.java
+1
-1
lab/16-18/src/main/java/play/parser/SampleGrammar.java
lab/16-18/src/main/java/play/parser/SampleGrammar.java
+73
-0
lab/16-18/src/main/java/play/parser/Token.java
lab/16-18/src/main/java/play/parser/Token.java
+3
-0
lab/16-18/src/main/java/play/parser/TokenReader.java
lab/16-18/src/main/java/play/parser/TokenReader.java
+21
-0
未找到文件。
lab/16-18/.idea/workspace.xml
浏览文件 @
b660b479
此差异已折叠。
点击以展开。
lab/16-18/src/main/java/play/parser/ASTNode.java
浏览文件 @
b660b479
...
...
@@ -27,6 +27,12 @@ public class ASTNode {
this
.
type
=
type
;
}
protected
ASTNode
(
String
type
,
String
text
){
this
.
type
=
type
;
this
.
text
=
text
;
}
public
String
getType
()
{
return
type
;
}
...
...
lab/16-18/src/main/java/play/parser/DFAState.java
浏览文件 @
b660b479
...
...
@@ -23,13 +23,13 @@ public class DFAState extends State {
}
/**
* 提供一个
字符
,看能否迁移到下一个状态
* @param
ch
* 提供一个
对象作为迁移条件
,看能否迁移到下一个状态
* @param
obj,做词法分析
* @return
*/
protected
DFAState
getNextState
(
char
ch
)
{
protected
DFAState
getNextState
(
Object
obj
)
{
for
(
Transition
transition
:
transitions
())
{
if
(
transition
.
match
(
ch
))
{
if
(
transition
.
match
(
obj
))
{
return
(
DFAState
)
getState
(
transition
);
}
}
...
...
@@ -39,7 +39,7 @@ public class DFAState extends State {
@Override
public
String
toString
()
{
String
rtn
=
super
.
toString
();
rtn
+=
"\t
(
"
;
rtn
+=
"\t
NFA states:
"
;
int
i
=
0
;
for
(
State
state
:
states
)
{
if
(
i
++
>
0
)
{
...
...
@@ -50,7 +50,7 @@ public class DFAState extends State {
rtn
+=
"("
+
state
.
getGrammarNode
().
getName
()
+
")"
;
}
}
rtn
+=
"
)
\n"
;
rtn
+=
"\n"
;
return
rtn
;
}
...
...
lab/16-18/src/main/java/play/parser/LRParser.java
0 → 100644
浏览文件 @
b660b479
此差异已折叠。
点击以展开。
lab/16-18/src/main/java/play/parser/Lexer.java
浏览文件 @
b660b479
...
...
@@ -45,7 +45,7 @@ public class Lexer extends Regex{
List
<
DFAState
>
dfaStates
=
NFA2DFA
(
nfaStates
[
0
],
CharSet
.
ascii
);
List
<
Token
>
tokens
=
tokenize
(
str
,
dfaStates
.
get
(
0
),
lexerGrammar
);
//加上结束符号
tokens
.
add
(
new
Token
(
"$"
,
"$"
)
);
tokens
.
add
(
Token
.
EOF
);
return
tokens
;
}
...
...
lab/16-18/src/main/java/play/parser/SampleGrammar.java
浏览文件 @
b660b479
...
...
@@ -197,6 +197,7 @@ public class SampleGrammar {
return
exp
;
}
/**
* 带有左递归的简化版的语法规则:
* add : mul | add '+' mul ;
...
...
@@ -230,6 +231,78 @@ public class SampleGrammar {
return
add
;
}
/**
* 带有左递归的语法规则:
* expression : assign ;
* assign : equal | assign '=' equal ;
* equal : rel | equal ('==' | '!=') rel ;
* rel : add | rel ('>=' | '>' | '<=' | '<') add ;
* add : mul | add ('+' | '-') mul ;
* mul : pri | mul ('*' | '/') pri ;
* pri : ID | INT_LITERAL | LPAREN expression RPAREN ;
*
* @return
*/
public
static
GrammarNode
fullLeftRecursiveExpressionGrammar
()
{
//expression
GrammarNode
exp
=
new
GrammarNode
(
"expression"
,
GrammarNodeType
.
And
);
//assign
GrammarNode
assign
=
exp
.
createChild
(
"assign"
,
GrammarNodeType
.
Or
);
GrammarNode
equal
=
assign
.
createChild
(
"equal"
,
GrammarNodeType
.
Or
);
GrammarNode
assign_2
=
assign
.
createChild
(
GrammarNodeType
.
And
);
assign_2
.
addChild
(
assign
);
//左递归
GrammarNode
assignOp
=
assign_2
.
createChild
(
new
Token
(
"ASSIGN"
,
"="
));
assign_2
.
addChild
(
equal
);
//TODO 这里是否可以改为expresssion
//equal
GrammarNode
rel
=
equal
.
createChild
(
"rel"
,
GrammarNodeType
.
Or
);
GrammarNode
equal_2
=
equal
.
createChild
(
GrammarNodeType
.
And
);
equal_2
.
addChild
(
equal
);
//左递归
GrammarNode
equalOp
=
equal_2
.
createChild
(
GrammarNodeType
.
Or
);
equalOp
.
createChild
(
new
Token
(
"EQUAL"
,
"=="
));
equalOp
.
createChild
(
new
Token
(
"NOTEQUAL"
,
"!="
));
equal_2
.
addChild
(
rel
);
//rel
GrammarNode
add
=
rel
.
createChild
(
"add"
,
GrammarNodeType
.
Or
);
GrammarNode
rel_2
=
rel
.
createChild
(
GrammarNodeType
.
And
);
rel_2
.
addChild
(
rel
);
//左递归
GrammarNode
relOp
=
rel_2
.
createChild
(
GrammarNodeType
.
Or
);
relOp
.
createChild
(
new
Token
(
"GE"
,
">="
));
relOp
.
createChild
(
new
Token
(
"GT"
,
">"
));
relOp
.
createChild
(
new
Token
(
"LE"
,
"<="
));
relOp
.
createChild
(
new
Token
(
"LT"
,
"<"
));
rel_2
.
addChild
(
add
);
//add
GrammarNode
mul
=
add
.
createChild
(
"mul"
,
GrammarNodeType
.
Or
);
GrammarNode
add_2
=
add
.
createChild
(
GrammarNodeType
.
And
);
add_2
.
addChild
(
add
);
//左递归
GrammarNode
addOp
=
add_2
.
createChild
(
GrammarNodeType
.
Or
);
addOp
.
createChild
(
new
Token
(
"ADD"
,
"+"
));
addOp
.
createChild
(
new
Token
(
"SUB"
,
"-"
));
add_2
.
addChild
(
mul
);
//mul
GrammarNode
pri
=
mul
.
createChild
(
"pri"
,
GrammarNodeType
.
Or
);
GrammarNode
mul_2
=
mul
.
createChild
(
GrammarNodeType
.
And
);
mul_2
.
addChild
(
mul
);
GrammarNode
mulOp
=
mul_2
.
createChild
(
GrammarNodeType
.
Or
);
mulOp
.
createChild
(
new
Token
(
"MUL"
,
"*"
));
mulOp
.
createChild
(
new
Token
(
"DIV"
,
"/"
));
mul_2
.
addChild
(
pri
);
//pri
pri
.
createChild
(
new
Token
(
"ID"
));
pri
.
createChild
(
new
Token
(
"INT_LITERAL"
));
GrammarNode
pri_3
=
pri
.
createChild
(
GrammarNodeType
.
And
);
pri_3
.
createChild
(
new
Token
(
"LPAREN"
));
pri_3
.
addChild
(
exp
);
pri_3
.
createChild
(
new
Token
(
"RPAREN"
));
return
exp
;
}
/**
* 创建一个示例用词法规则,支持:
...
...
lab/16-18/src/main/java/play/parser/Token.java
浏览文件 @
b660b479
...
...
@@ -21,6 +21,9 @@ public class Token {
private
int
startColumn
=
0
;
private
int
endColumn
=
0
;
//程序结束符号
protected
static
Token
EOF
=
new
Token
(
"$"
);
public
Token
(
String
type
){
this
.
type
=
type
;
}
...
...
lab/16-18/src/main/java/play/parser/TokenReader.java
浏览文件 @
b660b479
...
...
@@ -10,12 +10,18 @@ import java.util.List;
public
class
TokenReader
{
List
<
Token
>
tokens
=
null
;
//当前指针位置。
int
pos
=
0
;
public
TokenReader
(
List
<
Token
>
tokens
)
{
this
.
tokens
=
tokens
;
}
/**
* 读取一个Token,并移动指针。
* @return 如果已经读完,则返回null。
*/
public
Token
read
()
{
if
(
pos
<
tokens
.
size
())
{
return
tokens
.
get
(
pos
++);
...
...
@@ -23,6 +29,10 @@ public class TokenReader {
return
null
;
}
/**
* 预读一个Token。
* @return 如果已经读完,则返回null。
*/
public
Token
peek
()
{
if
(
pos
<
tokens
.
size
())
{
return
tokens
.
get
(
pos
);
...
...
@@ -30,16 +40,27 @@ public class TokenReader {
return
null
;
}
/**
* 回溯一个Token。
*/
public
void
unread
()
{
if
(
pos
>
0
)
{
pos
--;
}
}
/**
* 获取当前指针位置。
* @return
*/
public
int
getPosition
()
{
return
pos
;
}
/**
* 设置指针位置。用于回溯。
* @param position
*/
public
void
setPosition
(
int
position
)
{
if
(
position
>=
0
&&
position
<
tokens
.
size
()){
pos
=
position
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录