Skip to content

Commit

Permalink
*: add the http debuger tool
Browse files Browse the repository at this point in the history
  • Loading branch information
keyuchang committed Jun 7, 2022
1 parent a64c2b4 commit b792fdb
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 1 deletion.
83 changes: 83 additions & 0 deletions Builder/GoCodeTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ var goCodeTemplateStr string = `
// Code header part
{{.CodeHeader}}
import "strings"
{{if .HttpParser}}
import(
"io/ioutil"
"net/http"
"time"
"encoding/json"
)
{{end}}
// const part
{{.ConstPart}}
{{ if .NeedPacked }}
Expand Down Expand Up @@ -135,6 +143,9 @@ func Parser(input string) *ValType {
}
s := &StateSymStack[StackPointer-1]
a := s.Action(lookAhead)
{{ if .HttpParser }}
TracePingFun(input[currentPos:])
{{ end }}
if a == ERROR_ACTION {
lines := strings.Split(input[:currentPos], "\n")
panic("Grammar parse error near :" + lines[len(lines)-1])
Expand Down Expand Up @@ -173,6 +184,7 @@ func translate(c int) int {
}
return conv
}
// Trace function for translate
func TraceTranslate(c int) string {
var conv string = ""
Expand All @@ -189,5 +201,76 @@ func TraceReduce(reduceIndex, s int, look string) {
}
}
}
{{if .HttpParser}}
// Trace function for Ping
func TracePingFun(rest string) {
var result map[string]interface{} = make(map[string]interface{})
var stateStack []string
var symStack []string
var valueStack []string
for i := 0; i < StackPointer; i++ {
v := StateSymStack[i]
stateStack = append(stateStack, fmt.Sprintf("%d", v.Yystate))
symStack = append(symStack, TraceTranslate(v.YySymIndex))
valueStack = append(valueStack, fmt.Sprintf("%v", v.ValType.val))
}
result["states"] = stateStack
result["symbols"] = symStack
result["values"] = valueStack
result["rest"] = rest
js, _ := json.Marshal(result)
ochan <- string(js)
<-schan
}
type PingType struct {
Input string` + "`" + `json:"input"` + "`" + `
}
var schan chan string = make(chan string)
var ochan chan string = make(chan string)
var finished bool = true
// Ping Function
func handlerPing(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
if finished {
go ParserFun()
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Fprintf(w, "Kindly enter data with the event title and description only in order to update")
}
var ping PingType
json.Unmarshal(reqBody, &ping)
fmt.Println(ping.Input)
schan <- ping.Input
w.Write([]byte(<-ochan))
fmt.Println(time.Now(), r.Method, r.RequestURI, r.UserAgent())
}
func ParserFun() {
finished = false
ParserInit()
input := <-schan
_ = Parser(input)
finished = true
}
func main() {
http.HandleFunc("/ping", handlerPing)
fmt.Println("ping listening on 0.0.0.0, port 8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println("Error starting ping server: ", err)
}
}
{{end}}
// Code Last part
{{.CodeLast}}`
2 changes: 2 additions & 0 deletions Builder/GoTemplBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
type TemplateBuilder struct {
vnode *parser.RootVistor
NeedPacked bool
HttpParser bool
NTerminals int
HeaderPart string
CodeHeader string
Expand Down Expand Up @@ -62,6 +63,7 @@ func NewTemplateBuilder(w *parser.Walker) *TemplateBuilder {

func (b *TemplateBuilder) buildConstPart() {
b.NeedPacked = b.vnode.NeedPacked && utils.PackFlags
b.HttpParser = utils.HttpDebug
b.NTerminals = len(b.vnode.G.VtSet)
b.CodeHeader = b.vnode.GetCode()
b.CodeLast = b.vnode.GetCodeCopy()
Expand Down
83 changes: 83 additions & 0 deletions Builder/goCode.templ
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
// Code header part
{{.CodeHeader}}
import "strings"
{{if .HttpParser}}
import(
"io/ioutil"
"net/http"
"time"
"encoding/json"
)
{{end}}
// const part
{{.ConstPart}}
{{ if .NeedPacked }}
Expand Down Expand Up @@ -132,6 +140,9 @@ func Parser(input string) *ValType {
}
s := &StateSymStack[StackPointer-1]
a := s.Action(lookAhead)
{{ if .HttpParser }}
TracePingFun(input[currentPos:])
{{ end }}
if a == ERROR_ACTION {
lines := strings.Split(input[:currentPos], "\n")
panic("Grammar parse error near :" + lines[len(lines)-1])
Expand Down Expand Up @@ -170,6 +181,7 @@ func translate(c int) int {
}
return conv
}

// Trace function for translate
func TraceTranslate(c int) string {
var conv string = ""
Expand All @@ -186,5 +198,76 @@ func TraceReduce(reduceIndex, s int, look string) {
}
}
}
{{if .HttpParser}}
// Trace function for Ping
func TracePingFun(rest string) {
var result map[string]interface{} = make(map[string]interface{})
var stateStack []string
var symStack []string
var valueStack []string
for i := 0; i < StackPointer; i++ {
v := StateSymStack[i]
stateStack = append(stateStack, fmt.Sprintf("%d", v.Yystate))
symStack = append(symStack, TraceTranslate(v.YySymIndex))
valueStack = append(valueStack, fmt.Sprintf("%v", v.ValType.val))
}
result["states"] = stateStack
result["symbols"] = symStack
result["values"] = valueStack
result["rest"] = rest

js, _ := json.Marshal(result)
ochan <- string(js)
<-schan
}

type PingType struct {
Input string` + "`" + `json:"input"` + "`" + `
}

var schan chan string = make(chan string)
var ochan chan string = make(chan string)
var finished bool = true

// Ping Function
func handlerPing(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
if finished {
go ParserFun()
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Fprintf(w, "Kindly enter data with the event title and description only in order to update")
}
var ping PingType

json.Unmarshal(reqBody, &ping)
fmt.Println(ping.Input)
schan <- ping.Input
w.Write([]byte(<-ochan))
fmt.Println(time.Now(), r.Method, r.RequestURI, r.UserAgent())
}

func ParserFun() {
finished = false
ParserInit()
input := <-schan
_ = Parser(input)
finished = true
}

func main() {
http.HandleFunc("/ping", handlerPing)

fmt.Println("ping listening on 0.0.0.0, port 8080")
err := http.ListenAndServe(":8080", nil)

if err != nil {
fmt.Println("Error starting ping server: ", err)
}
}

{{end}}
// Code Last part
{{.CodeLast}}
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ look ahead $, use Reduce:PROG -> PROG E NL , go to state 1
Shift PROG, push state 1
0
```
# Web Debuger
If you want to debug the parser visually, you can use yaccgo debuger in browser.
![debuger](debugtool.gif)
## 1. generate http debuger parser
```
./bin/yaccgo generate go --httpdebug=true examples/exprhttp.y out/expr.go
```
## 2. run http debuger
```
go run out/expr.go
```
## 3. open the `debugTool.html` in browser

# Design

Expand Down
1 change: 1 addition & 0 deletions Utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ package utils

var DebugFlags bool = false
var PackFlags bool = true
var HttpDebug bool = false
85 changes: 85 additions & 0 deletions debugTool.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>YaccGo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="stylesheet/custome.css">
</head>
<body>
<div class="container">
<h1>Debuger YaccGo</h1>
<p>Show the stack for every steps!</p>
<div class="row">
<div class="col">
<div class="panel panel-blue">
<div class="form-group">
<label for="name">input the strings :</label>
<input class="input-sm form-control" id="item-87" placeholder="Enter your string to parse">
<small id="rest" class="form-text text-muted">after input, you can run the parser step by step.</small>
</div>
<button type="submit" class="btn btn-primary" id="buttonSubmit">Step Run</button>

</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="panel panel-purple">States Stack
<ul class="list-group" id="list1">
</ul>
</div>
</div>
<div class="col">
<div class="panel panel-purple">Symbols Stack
<ul class="list-group" id="list2">
</ul>
</div>
</div>
<div class="col">
<div class="panel panel-purple"> Values Stack
<ul class="list-group" id="list3">
</ul>
</div>
</div>
</div>

</div>

<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$("#buttonSubmit").click(function(){
txt=$("#item-87").val();
$.post("http://localhost:8080/ping",
JSON.stringify({input:txt}),
function(result){
console.log(result);
$("#list1").empty();
$("#list2").empty();
$("#list3").empty();
for(i=0;i<result.states.length;i++){
$("#list1").append("<li class='list-group-item'>"+result.states[i]+"</li>");
}
for(i=0;i<result.symbols.length;i++){
$("#list2").append("<li class='list-group-item'>"+result.symbols[i]+"</li>");
}
for(i=0;i<result.values.length;i++){
$("#list3").append("<li class='list-group-item'>"+result.values[i]+"</li>");
}
$("#rest").text(result.rest);
},"json",
function(error){
console.log(error);
});

});
});
</script>
</body>
</html>
Binary file added debugtool.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/expr.y
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ E:
return 0
}
}

func main() {
v := Parser("1+2*31").val
fmt.Println(v)
Expand Down
Loading

0 comments on commit b792fdb

Please sign in to comment.