From 2041732e28bedf8af46b5bcc4eb6f77ea34f6751 Mon Sep 17 00:00:00 2001 From: Ed94 Date: Sun, 17 Jul 2022 10:18:24 -0400 Subject: [PATCH] Fleshed out the UI for RegM, fixes to SRegEx --- .../Styles/Editor.SytleBoxFlat.Inactive.tres | 4 + App/Assets/Styles/EditorTheme.tres | 4 +- App/RegM/Lectures/Lecture.9.Notes.md | 28 +++++ App/RegM/RegM_Viewer.tscn | 94 ++++++++++++++- App/RegM/Scripts/FiniteAutomata.gd | 4 +- App/RegM/Scripts/RegM_Viewer.gd | 22 ++++ App/RegM/Scripts/SRegex.Notes.md | 109 +++++++++++++++++- App/RegM/Scripts/SRegex.gd | 41 ++++--- 8 files changed, 281 insertions(+), 25 deletions(-) create mode 100644 App/Assets/Styles/Editor.SytleBoxFlat.Inactive.tres create mode 100644 App/RegM/Scripts/RegM_Viewer.gd diff --git a/App/Assets/Styles/Editor.SytleBoxFlat.Inactive.tres b/App/Assets/Styles/Editor.SytleBoxFlat.Inactive.tres new file mode 100644 index 0000000..e1cd1a0 --- /dev/null +++ b/App/Assets/Styles/Editor.SytleBoxFlat.Inactive.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=2] + +[resource] +bg_color = Color( 0.101961, 0.101961, 0.101961, 1 ) diff --git a/App/Assets/Styles/EditorTheme.tres b/App/Assets/Styles/EditorTheme.tres index 0f4ffba..d6a0929 100644 --- a/App/Assets/Styles/EditorTheme.tres +++ b/App/Assets/Styles/EditorTheme.tres @@ -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/Fonts/DF_RecMonoSemiCasul.tres" type="DynamicFont" id=2] +[ext_resource path="res://Assets/Styles/Editor.SytleBoxFlat.Inactive.tres" type="StyleBox" id=3] [resource] +Button/styles/disabled = ExtResource( 3 ) TextEdit/colors/font_color = Color( 1, 1, 1, 1 ) TextEdit/colors/font_color_readonly = Color( 1, 1, 1, 1 ) TextEdit/fonts/font = ExtResource( 2 ) diff --git a/App/RegM/Lectures/Lecture.9.Notes.md b/App/RegM/Lectures/Lecture.9.Notes.md index 3e76a52..badd399 100644 --- a/App/RegM/Lectures/Lecture.9.Notes.md +++ b/App/RegM/Lectures/Lecture.9.Notes.md @@ -9,3 +9,31 @@ SRegEx: `a.repeat(1-) | set(0-3)` `A?` === `A|ε` === `A.repeat(0-1)` `[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 ----> (o) + .......... +``` + + diff --git a/App/RegM/RegM_Viewer.tscn b/App/RegM/RegM_Viewer.tscn index 34952f3..c1d1030 100644 --- a/App/RegM/RegM_Viewer.tscn +++ b/App/RegM/RegM_Viewer.tscn @@ -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"] anchor_right = 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" diff --git a/App/RegM/Scripts/FiniteAutomata.gd b/App/RegM/Scripts/FiniteAutomata.gd index 9e0ade8..685a008 100644 --- a/App/RegM/Scripts/FiniteAutomata.gd +++ b/App/RegM/Scripts/FiniteAutomata.gd @@ -11,7 +11,7 @@ class State : func _init(accepting : bool): self.accepting = accepting - transitionMap[epsilon] = Array.new() + transitionMap[epsilon] = [] func add_Transition(symbol : string, state : State): if symbol == epsilon : @@ -63,7 +63,7 @@ func glyph(symbol : string): return NFA.new(start, accepting) -func repeat(entry : NFA) +func repeat(entry : NFA): var start = State.new(false) var accepting = State.new(true) diff --git a/App/RegM/Scripts/RegM_Viewer.gd b/App/RegM/Scripts/RegM_Viewer.gd new file mode 100644 index 0000000..23b2132 --- /dev/null +++ b/App/RegM/Scripts/RegM_Viewer.gd @@ -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") diff --git a/App/RegM/Scripts/SRegex.Notes.md b/App/RegM/Scripts/SRegex.Notes.md index a6e7f99..c44f679 100644 --- a/App/RegM/Scripts/SRegex.Notes.md +++ b/App/RegM/Scripts/SRegex.Notes.md @@ -38,8 +38,111 @@ a? a.repeat(0-1) a{5} a.repeat(5) a{2,} a.repeat(2-) a{1,3} a.repeat(1-3) -a{5} a.repeat.lazy +a{5} a.repeat(0-).lazy a{2,}? a.repeat(2-).lazy ab|cd ab | cd -/^\/\*[\s\S]*?\*\// start /* set(whitespace !whitespace).lazy.repeat */ -``` \ No newline at end of file +/^\/\*[\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-) diff --git a/App/RegM/Scripts/SRegex.gd b/App/RegM/Scripts/SRegex.gd index 084db35..5985ec0 100644 --- a/App/RegM/Scripts/SRegex.gd +++ b/App/RegM/Scripts/SRegex.gd @@ -364,10 +364,10 @@ func is_RegExToken() : # : expression | expression .. # | expression # ; -func parse_OpUnion(endToken : Token): +func parse_OpUnion(endToken): var expression = parse_Expression(endToken) - if NextToken == null || NextToken.Type != TokenType.union : + if NextToken == null || NextToken.Type != TokenType.op_union : return expression eat(TokenType.op_union) @@ -383,17 +383,16 @@ func parse_OpUnion(endToken : Token): # Expression # : EVERYTHING (Almost) # ; -func parse_Expression(endToken : Token): +func parse_Expression(endToken): var \ node = ASTNode.new() node.Type = NodeType.expression node.Value = [] - - var sentinel = endToken != null - if sentinel : - sentinel = NextToken.Type == endToken.Type - while NextToken != null && !sentinel : + while NextToken != null && NextToken.Type != TokenType.op_union : + if endToken != null && NextToken.Type == endToken : + break + match NextToken.Type : TokenType.str_start : node.Value.append( parse_StrStart() ) @@ -718,6 +717,8 @@ func parse_OpLook(): node = ASTNode.new() node.Type = NodeType.look node.Value = parse_CaptureGroup() + + return node # > Expression # OpNot @@ -789,7 +790,7 @@ func parse_OpRepeat(): return node func parse_Backreference(): - eat(TokenType.Backreference) + eat(TokenType.ref) var \ node = ASTNode.new() @@ -800,8 +801,9 @@ func parse_Backreference(): var assertStrTmplt = "Error when parsing a backreference expression: Expected digit but got: {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 + eat(TokenType.glyph) eat(TokenType.expr_PEnd) @@ -870,7 +872,8 @@ func transiple_Union(node : ASTNode): var expressionLeft = node.Value if node.Type == NodeType.union : - expressionLeft = node.Value[0] + expressionLeft = node.Value[0].Value + for entry in expressionLeft : match entry.Type : @@ -931,11 +934,11 @@ func transpile_LookAhead(node : ASTNode, negate : bool): var result = "" if negate : - result += "(?=" - else : result += "(?!" + else : + result += "(?=" - result += transiple_Union(node.Value) + result += transiple_Union(node.Value.Value) result += ")" return result @@ -956,13 +959,15 @@ func transpile_Repeat(node : ASTNode): if vrange.Value.size() == 1 : if vrange.Value[0].Value == "0" : result += "*" - if vrange.Value[0].Value == "1" : + elif vrange.Value[0].Value == "1" : result += "+" + else : + result += "{" + vrange.Value[0].Value + "," + "}" if vrange.Value.size() == 2 : if vrange.Value[0].Value == "0" && vrange.Value[1].Value == "1" : result += "?" else : - result += "{" + vrange.Value[0].Value[0] + "," + vrange.Value[0].Value[1] + "}" + result += "{" + vrange.Value[0].Value + "," + vrange.Value[1].Value + "}" else : result += "{" + vrange.Value[0] + "}" @@ -983,9 +988,9 @@ func transpile_Set(node : ASTNode, negate : bool): if entry.Type == NodeType.op_not : result += transpile_OpNot(entry) elif entry.Type == NodeType.between : - result += entry.Value[0] + result += entry.Value[0].Value result += "-" - result += entry.Value[1] + result += entry.Value[1].Value else : result += entry.Value