syntax.mx raw
1 package main
2
3 import (
4 "fmt"
5 "io"
6 "os"
7 )
8
9 type Mode uint
10
11 const (
12 CheckBranches Mode = 1 << iota
13 )
14
15 type Error struct {
16 Pos Pos
17 Msg string
18 }
19
20 func (err Error) Error() string {
21 return fmt.Sprintf("%s: %s", err.Pos, err.Msg)
22 }
23
24 var _ error = Error{}
25
26 type ErrorHandler func(err error)
27
28 type Pragma interface{}
29
30 type PragmaHandler func(pos Pos, blank bool, text string, current Pragma) Pragma
31
32 func Parse(base *PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) {
33 defer func() {
34 if p := recover(); p != nil {
35 if err, ok := p.(Error); ok {
36 first = err
37 return
38 }
39 panic(p)
40 }
41 }()
42
43 var p Parser
44 p.init(base, src, errh, pragh, mode)
45 p.Next()
46 return p.fileOrNil(), p.First
47 }
48
49 func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
50 f, err := os.Open(filename)
51 if err != nil {
52 if errh != nil {
53 errh(err)
54 }
55 return nil, err
56 }
57 defer f.Close()
58 return Parse(NewFileBase(filename), f, errh, pragh, mode)
59 }
60