aboutsummaryrefslogtreecommitdiffstats
path: root/sysgen/parser.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-10-12 10:16:57 +0200
committerDmitry Vyukov <dvyukov@google.com>2015-10-12 10:16:57 +0200
commit874c5754bb22dbf77d6b600ff91f0f4f1fc5073a (patch)
tree0075fbd088046ad5c86e6e972235701d68b3ce7c /sysgen/parser.go
initial commit
Diffstat (limited to 'sysgen/parser.go')
-rw-r--r--sysgen/parser.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/sysgen/parser.go b/sysgen/parser.go
new file mode 100644
index 000000000..92c27c58a
--- /dev/null
+++ b/sysgen/parser.go
@@ -0,0 +1,92 @@
+// Copyright 2015 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+)
+
+type Parser struct {
+ r *bufio.Scanner
+ s string
+ i int
+ l int
+}
+
+func NewParser(r io.Reader) *Parser {
+ return &Parser{r: bufio.NewScanner(r)}
+}
+
+func (p *Parser) Scan() bool {
+ if !p.r.Scan() {
+ if err := p.r.Err(); err != nil {
+ failf("failed to read input file: %v", err)
+ }
+ return false
+ }
+ p.s = p.r.Text()
+ p.i = 0
+ p.l++
+ return true
+}
+
+func (p *Parser) Str() string {
+ return p.s
+}
+
+func (p *Parser) EOF() bool {
+ return p.i == len(p.s)
+}
+
+func (p *Parser) Char() byte {
+ if p.EOF() {
+ p.failf("unexpected eof")
+ }
+ return p.s[p.i]
+}
+
+func (p *Parser) Parse(ch byte) {
+ if p.EOF() {
+ p.failf("want %s, got EOF", string(ch))
+ }
+ if p.s[p.i] != ch {
+ p.failf("want '%v', got '%v'", string(ch), string(p.s[p.i]))
+ }
+ p.i++
+ p.SkipWs()
+}
+
+func (p *Parser) SkipWs() {
+ for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
+ p.i++
+ }
+}
+
+func (p *Parser) Ident() string {
+ i := p.i
+ for p.i < len(p.s) &&
+ (p.s[p.i] >= 'a' && p.s[p.i] <= 'z' ||
+ p.s[p.i] >= 'A' && p.s[p.i] <= 'Z' ||
+ p.s[p.i] >= '0' && p.s[p.i] <= '9' ||
+ p.s[p.i] == '_' || p.s[p.i] == '$') { // $ is for n-way syscalls (like ptrace$peek)
+ p.i++
+ }
+ if i == p.i {
+ p.failf("failed to parse identifier at pos %v", i)
+ }
+ if ch := p.s[i]; ch >= '0' && ch <= '9' {
+ // p.failf("identifier starts with a digit at pos %v", i)
+ }
+ s := p.s[i:p.i]
+ p.SkipWs()
+ return s
+}
+
+func (p *Parser) failf(msg string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, "line #%v: %v\n", p.l, p.s)
+ failf(msg, args...)
+}