Fleshed out the UI for RegM, fixes to SRegEx

This commit is contained in:
Edward R. Gonzalez 2022-07-17 10:18:24 -04:00
parent 77e9e0431e
commit 2041732e28
8 changed files with 281 additions and 25 deletions

View File

@ -0,0 +1,4 @@
[gd_resource type="StyleBoxFlat" format=2]
[resource]
bg_color = Color( 0.101961, 0.101961, 0.101961, 1 )

View File

@ -1,9 +1,11 @@
[gd_resource type="Theme" load_steps=3 format=2] [gd_resource type="Theme" load_steps=4 format=2]
[ext_resource path="res://Assets/Styles/Editor.SytleBoxFlat.tres" type="StyleBox" id=1] [ext_resource path="res://Assets/Styles/Editor.SytleBoxFlat.tres" type="StyleBox" id=1]
[ext_resource path="res://Assets/Fonts/DF_RecMonoSemiCasul.tres" type="DynamicFont" id=2] [ext_resource path="res://Assets/Fonts/DF_RecMonoSemiCasul.tres" type="DynamicFont" id=2]
[ext_resource path="res://Assets/Styles/Editor.SytleBoxFlat.Inactive.tres" type="StyleBox" id=3]
[resource] [resource]
Button/styles/disabled = ExtResource( 3 )
TextEdit/colors/font_color = Color( 1, 1, 1, 1 ) TextEdit/colors/font_color = Color( 1, 1, 1, 1 )
TextEdit/colors/font_color_readonly = Color( 1, 1, 1, 1 ) TextEdit/colors/font_color_readonly = Color( 1, 1, 1, 1 )
TextEdit/fonts/font = ExtResource( 2 ) TextEdit/fonts/font = ExtResource( 2 )

View File

@ -9,3 +9,31 @@ SRegEx: `a.repeat(1-) | set(0-3)`
`A?` === `A|ε` === `A.repeat(0-1)` `A?` === `A|ε` === `A.repeat(0-1)`
`[0-9]` === `0|1|2|3|4|5|6|7|8|9` === `set(0-9)` `[0-9]` === `0|1|2|3|4|5|6|7|8|9` === `set(0-9)`
# NFA Optimizations
Ex:
RegEx : `/[0-2]+/`
SRegEx: `set(0-2).repeat(1-)`
Machine (Optimized):
```
|<-epsi-<|
->o -0-> (o)
\--1-->/
\-2->/
```
A* (Optimized)
```
->o -A--> (o)
\-epsi->/
```
`[characters]`
```
->o --<num>--> (o)
..........
```

View File

@ -1,5 +1,97 @@
[gd_scene format=2] [gd_scene load_steps=4 format=2]
[ext_resource path="res://Assets/Branding/RegM_Class_cover_small.png" type="Texture" id=1]
[ext_resource path="res://Assets/Styles/EditorTheme.tres" type="Theme" id=2]
[ext_resource path="res://RegM/Scripts/RegM_Viewer.gd" type="Script" id=3]
[node name="RegM_Panel" type="Panel"] [node name="RegM_Panel" type="Panel"]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
theme = ExtResource( 2 )
script = ExtResource( 3 )
[node name="CourseBrand" type="TextureRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_scale = Vector2( 0.2, 0.2 )
texture = ExtResource( 1 )
expand = true
stretch_mode = 6
[node name="RegEx_TEdit" type="TextEdit" parent="."]
anchor_left = 0.2
anchor_right = 0.526
anchor_bottom = 1.0
margin_left = 1.2
margin_right = 0.375977
grow_horizontal = 0
theme = ExtResource( 2 )
highlight_current_line = true
show_line_numbers = true
[node name="SRegEx_TEdit" type="TextEdit" parent="."]
anchor_left = 0.525
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 1.83997
grow_horizontal = 0
theme = ExtResource( 2 )
highlight_current_line = true
show_line_numbers = true
minimap_draw = true
[node name="Letter_FDialog" type="FileDialog" parent="."]
anchor_left = 0.35
anchor_top = 0.15
anchor_right = 0.45
anchor_bottom = 0.25
margin_right = 356.0
margin_bottom = 373.0
theme = ExtResource( 2 )
popup_exclusive = true
window_title = "Open a File"
mode = 0
access = 2
[node name="VBox" type="VBoxContainer" parent="."]
anchor_top = 0.196
anchor_right = 0.2
anchor_bottom = 1.0
margin_top = 2.39999
margin_right = -1.8
margin_bottom = -2.0
[node name="ToRegEx_Btn" type="Button" parent="VBox"]
margin_right = 203.0
margin_bottom = 30.0
focus_neighbour_top = NodePath("../../CourseBrand")
size_flags_vertical = 3
size_flags_stretch_ratio = 0.08
theme = ExtResource( 2 )
text = "To RegEx"
[node name="ToSRegEx_Btn" type="Button" parent="VBox"]
margin_top = 34.0
margin_right = 203.0
margin_bottom = 64.0
focus_neighbour_top = NodePath("../../CourseBrand")
size_flags_vertical = 3
size_flags_stretch_ratio = 0.08
theme = ExtResource( 2 )
disabled = true
text = "To SRegEx"
[node name="Separator" type="HSeparator" parent="VBox"]
modulate = Color( 0.145098, 0.145098, 0.164706, 0 )
margin_top = 68.0
margin_right = 203.0
margin_bottom = 443.0
size_flags_vertical = 15
[node name="Back_Btn" type="Button" parent="VBox"]
margin_top = 447.0
margin_right = 203.0
margin_bottom = 478.0
size_flags_vertical = 3
size_flags_stretch_ratio = 0.08
text = "Course Directory"

View File

@ -11,7 +11,7 @@ class State :
func _init(accepting : bool): func _init(accepting : bool):
self.accepting = accepting self.accepting = accepting
transitionMap[epsilon] = Array.new() transitionMap[epsilon] = []
func add_Transition(symbol : string, state : State): func add_Transition(symbol : string, state : State):
if symbol == epsilon : if symbol == epsilon :
@ -63,7 +63,7 @@ func glyph(symbol : string):
return NFA.new(start, accepting) return NFA.new(start, accepting)
func repeat(entry : NFA) func repeat(entry : NFA):
var start = State.new(false) var start = State.new(false)
var accepting = State.new(true) var accepting = State.new(true)

View File

@ -0,0 +1,22 @@
extends Node
var SRegEx = preload("SRegEx.gd").new()
onready var RegEx_TEdit = get_node("RegEx_TEdit")
onready var SRegEx_TEdit = get_node("SRegEx_TEdit")
onready var ToRegEx_Btn = get_node("VBox/ToRegEx_Btn")
onready var Back_Btn = get_node("VBox/Back_Btn")
func to_RegExBtn_pressed():
RegEx_TEdit.text = SRegEx.transpile(SRegEx_TEdit.text)
# for line in SRegEx_TEdit.text.split("\n") :
# RegEx_TEdit.text += SRegEx.transpile( line ) + "\n"
func backBtn_pressed():
queue_free()
# Called when the node enters the scene tree for the first time.
func _ready():
Back_Btn.connect("pressed", self, "backBtn_pressed")
ToRegEx_Btn.connect("pressed", self, "to_RegExBtn_pressed")

View File

@ -38,8 +38,111 @@ a? a.repeat(0-1)
a{5} a.repeat(5) a{5} a.repeat(5)
a{2,} a.repeat(2-) a{2,} a.repeat(2-)
a{1,3} a.repeat(1-3) a{1,3} a.repeat(1-3)
a{5} a.repeat.lazy a{5} a.repeat(0-).lazy
a{2,}? a.repeat(2-).lazy a{2,}? a.repeat(2-).lazy
ab|cd ab | cd ab|cd ab | cd
/^\/\*[\s\S]*?\*\// start /* set(whitespace !whitespace).lazy.repeat */ /^\/\*[\s\S]*?\*\// start /* set(whitespace !whitespace).repeat(0-).lazy */
``` ```
```
inline
word
digit
whitespace
!word
!digit
!whitespace
set(abc)
!set(abc)
set(a-g)
start abc end
"string"
!"not this string"
\-
\.
\!
\|
\(
\)
\"
\t
\n
\r
( abc )
backref(1)
!( abc )
look(abc)
!look(abc)
a.repeat(0-)
a.repeat(1-)
a.repeat(0-1)
a.repeat(5)
a.repeat(2-)
a.repeat(1-3)
a.repeat(0-).lazy
a.repeat(2-).lazy
ab | cd
start whitespace
start "start"
start "end"
start \" !set( \" ).repeat(0-) "\
start \ \(
start \ \)
start \(
start \)
start \-
start "digt"
start "inline"
start "word"
start "whitespace"
start "lazy"
start \."repeat"
start \\ \-
start \\ \.
start \\ \!
start \\ \|
start \\ \"
start "look"
start \!
start \|
start "backref"
start "set"
start !set(whitespace)
start // inline.repeat(0-)
start /* set(whitespace !whitespace).repeat(0-).lazy */ start
start whitespace.repeat(1-)
start ,
start \.
start ;
start {
start }
start "let"
start "class"
start "while"
start "do"
start "for"
start "def"
start "return"
start "if"
start "else"
start "new"
start "extends"
start "super"
start set(> <) =.repeat(0-1)
start set(= \!) =
start &&
start \| \|
start \!
start set( * / + \- ) =
start =
start set(+ \-)
start set( * / )
start "true"
start "false"
start digit.repeat(1-)
start \" !set( \" ).repeat(0-) \"
start "null"
start "this"
start word.repeat(1-)

View File

@ -364,10 +364,10 @@ func is_RegExToken() :
# : expression | expression .. # : expression | expression ..
# | expression # | expression
# ; # ;
func parse_OpUnion(endToken : Token): func parse_OpUnion(endToken):
var expression = parse_Expression(endToken) var expression = parse_Expression(endToken)
if NextToken == null || NextToken.Type != TokenType.union : if NextToken == null || NextToken.Type != TokenType.op_union :
return expression return expression
eat(TokenType.op_union) eat(TokenType.op_union)
@ -383,17 +383,16 @@ func parse_OpUnion(endToken : Token):
# Expression # Expression
# : EVERYTHING (Almost) # : EVERYTHING (Almost)
# ; # ;
func parse_Expression(endToken : Token): func parse_Expression(endToken):
var \ var \
node = ASTNode.new() node = ASTNode.new()
node.Type = NodeType.expression node.Type = NodeType.expression
node.Value = [] node.Value = []
var sentinel = endToken != null while NextToken != null && NextToken.Type != TokenType.op_union :
if sentinel : if endToken != null && NextToken.Type == endToken :
sentinel = NextToken.Type == endToken.Type break
while NextToken != null && !sentinel :
match NextToken.Type : match NextToken.Type :
TokenType.str_start : TokenType.str_start :
node.Value.append( parse_StrStart() ) node.Value.append( parse_StrStart() )
@ -719,6 +718,8 @@ func parse_OpLook():
node.Type = NodeType.look node.Type = NodeType.look
node.Value = parse_CaptureGroup() node.Value = parse_CaptureGroup()
return node
# > Expression # > Expression
# OpNot # OpNot
# : ! # : !
@ -789,7 +790,7 @@ func parse_OpRepeat():
return node return node
func parse_Backreference(): func parse_Backreference():
eat(TokenType.Backreference) eat(TokenType.ref)
var \ var \
node = ASTNode.new() node = ASTNode.new()
@ -800,8 +801,9 @@ func parse_Backreference():
var assertStrTmplt = "Error when parsing a backreference expression: Expected digit but got: {value}" var assertStrTmplt = "Error when parsing a backreference expression: Expected digit but got: {value}"
var assertStr = assertStrTmplt.format({"value" : NextToken.Value}) var assertStr = assertStrTmplt.format({"value" : NextToken.Value})
assert(NextToken.Type == TokenType.glyph_digit, assertStr) assert(NextToken.Type == TokenType.glyph, assertStr)
node.Value = NextToken.Value node.Value = NextToken.Value
eat(TokenType.glyph)
eat(TokenType.expr_PEnd) eat(TokenType.expr_PEnd)
@ -870,7 +872,8 @@ func transiple_Union(node : ASTNode):
var expressionLeft = node.Value var expressionLeft = node.Value
if node.Type == NodeType.union : if node.Type == NodeType.union :
expressionLeft = node.Value[0] expressionLeft = node.Value[0].Value
for entry in expressionLeft : for entry in expressionLeft :
match entry.Type : match entry.Type :
@ -931,11 +934,11 @@ func transpile_LookAhead(node : ASTNode, negate : bool):
var result = "" var result = ""
if negate : if negate :
result += "(?="
else :
result += "(?!" result += "(?!"
else :
result += "(?="
result += transiple_Union(node.Value) result += transiple_Union(node.Value.Value)
result += ")" result += ")"
return result return result
@ -956,13 +959,15 @@ func transpile_Repeat(node : ASTNode):
if vrange.Value.size() == 1 : if vrange.Value.size() == 1 :
if vrange.Value[0].Value == "0" : if vrange.Value[0].Value == "0" :
result += "*" result += "*"
if vrange.Value[0].Value == "1" : elif vrange.Value[0].Value == "1" :
result += "+" result += "+"
else :
result += "{" + vrange.Value[0].Value + "," + "}"
if vrange.Value.size() == 2 : if vrange.Value.size() == 2 :
if vrange.Value[0].Value == "0" && vrange.Value[1].Value == "1" : if vrange.Value[0].Value == "0" && vrange.Value[1].Value == "1" :
result += "?" result += "?"
else : else :
result += "{" + vrange.Value[0].Value[0] + "," + vrange.Value[0].Value[1] + "}" result += "{" + vrange.Value[0].Value + "," + vrange.Value[1].Value + "}"
else : else :
result += "{" + vrange.Value[0] + "}" result += "{" + vrange.Value[0] + "}"
@ -983,9 +988,9 @@ func transpile_Set(node : ASTNode, negate : bool):
if entry.Type == NodeType.op_not : if entry.Type == NodeType.op_not :
result += transpile_OpNot(entry) result += transpile_OpNot(entry)
elif entry.Type == NodeType.between : elif entry.Type == NodeType.between :
result += entry.Value[0] result += entry.Value[0].Value
result += "-" result += "-"
result += entry.Value[1] result += entry.Value[1].Value
else : else :
result += entry.Value result += entry.Value