├── .gitignore ├── .travis.yml ├── README.md ├── UNLICENSE ├── cmd └── gon │ ├── eval.go │ ├── eval_test.go │ ├── hash.go │ ├── main.go │ └── parse.go ├── default.nix ├── deps.nix ├── go.mod ├── go.sum ├── internal └── error.go └── nix ├── eval ├── derivation.go ├── eval.go ├── symbol.go └── value.go ├── nixhash ├── base32.go ├── dump.go ├── hash.go ├── hash_test.go ├── sink.go └── store.go ├── parser ├── lexer.go ├── lexer_test.go ├── machine.go ├── machine.rl ├── nix.y ├── nodetype.go ├── parser.go ├── parser_test.go ├── path.go ├── path_test.go └── y.go └── util └── walk.go /.gitignore: -------------------------------------------------------------------------------- 1 | y.output 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: nix 2 | script: 3 | - nix-build 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/orivej/go-nix.svg?branch=master)](https://travis-ci.org/orivej/go-nix) 2 | 3 | # Overview 4 | 5 | This repository contains: 6 | 7 | - `nix/parser` - a Nix parser. Optimized for speed, it parses all Nixpkgs in 2 seconds. It preserves comments and source positions and can be used to implement Nix files formatting. 8 | - `nix/nixhash` - Nix-compatible hasher for store paths. 9 | - `nix/eval` - an incomplete Nix evaluator. It can't evaluate realistic Nix files, but it's a start. 10 | - `cmd/gon` - an utility that exposes these libraries from the command line. 11 | 12 | # Development 13 | 14 | ## How to build 15 | 16 | ```sh 17 | $ nix-build 18 | ``` 19 | 20 | ## Build cmd/gon 21 | 22 | ```sh 23 | $ result-bin/bin/gon help 24 | ``` 25 | 26 | ## Get a development environment 27 | 28 | ```sh 29 | $ nix-shell 30 | $ go build ./... 31 | ``` 32 | 33 | ## Run tests 34 | 35 | ```sh 36 | $ go test ./... 37 | ``` 38 | 39 | # Credits 40 | 41 | - [ragel](https://www.colm.net/open-source/ragel/) generates the Nix lexer 42 | - [goyacc](https://godoc.org/golang.org/x/tools/cmd/goyacc) generates the Nix parser 43 | - [kingpin](https://github.com/alecthomas/kingpin) powers the CLI 44 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /cmd/gon/eval.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/alecthomas/kingpin" 7 | "github.com/orivej/e" 8 | "github.com/orivej/go-nix/nix/eval" 9 | "github.com/orivej/go-nix/nix/parser" 10 | ) 11 | 12 | var ( 13 | evalCmd = kingpin.Command("eval", "Eval Nix expression.") 14 | evalExprArg = evalCmd.Arg("expr", "Expression.").Required().String() 15 | ) 16 | 17 | var evalMain = register("eval", func() { 18 | pr, err := parser.ParseString(*evalExprArg) 19 | e.Exit(err) 20 | fmt.Println(eval.ValueString(eval.ParseResult(pr))) 21 | }) 22 | -------------------------------------------------------------------------------- /cmd/gon/eval_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/alecthomas/assert" 7 | "github.com/orivej/go-nix/nix/eval" 8 | "github.com/orivej/go-nix/nix/parser" 9 | ) 10 | 11 | func TestEval(t *testing.T) { 12 | for _, test := range [][2]string{ 13 | {`{ "abc" = 1; }`, `{ abc = ...; }`}, 14 | {`{ abc = 1; }`, `{ abc = ...; }`}, 15 | {`{ a = 1; }.a`, `1`}, 16 | {`{ a."b".${"c"} = 1; }."${"a"}".${"b"}.c`, `1`}, 17 | } { 18 | pr, err := parser.ParseString(test[0]) 19 | assert.NoError(t, err) 20 | s := eval.ValueString(eval.ParseResult(pr)) 21 | assert.Equal(t, test[1], s) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cmd/gon/hash.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/alecthomas/kingpin" 7 | "github.com/orivej/go-nix/nix/nixhash" 8 | ) 9 | 10 | var ( 11 | hashCmd = kingpin.Command("hash", "Hash a path.") 12 | hashPath = hashCmd.Arg("path", "path").Required().String() 13 | hashName = hashCmd.Flag("name", "Name in store.").Short('n').String() 14 | ) 15 | 16 | var hashMain = register("hash", func() { 17 | fmt.Println(nixhash.StorePath(*hashPath, *hashName)) 18 | }) 19 | -------------------------------------------------------------------------------- /cmd/gon/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/alecthomas/kingpin" 8 | "github.com/orivej/go-nix/internal" 9 | "github.com/pkg/profile" 10 | ) 11 | 12 | var ( 13 | actions = map[string]func(){} 14 | prof = kingpin.Flag("profile", "Profile performance.").Bool() 15 | ) 16 | 17 | func register(name string, f func()) func() { 18 | actions[name] = f 19 | return f 20 | } 21 | 22 | func main() { 23 | kingpin.HelpFlag.Short('h') 24 | action := kingpin.Parse() 25 | if *prof { 26 | defer profile.Start(profile.ProfilePath(".")).Stop() 27 | } 28 | defer handlePanic() 29 | actions[action]() 30 | } 31 | 32 | func handlePanic() { 33 | if v := recover(); v != nil { 34 | if e, ok := v.(internal.Error); ok { 35 | fmt.Fprintln(os.Stderr, "error:", e) 36 | } else { 37 | panic(v) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cmd/gon/parse.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/alecthomas/kingpin" 7 | "github.com/orivej/e" 8 | "github.com/orivej/go-nix/nix/parser" 9 | ) 10 | 11 | var ( 12 | parseCmd = kingpin.Command("parse", "Parse Nix expression.") 13 | parseExprArg = parseCmd.Arg("expr", "Expression.").Required().String() 14 | parseFile = parseCmd.Flag("file", "Parse file.").Short('f').Bool() 15 | ) 16 | 17 | var parseMain = register("parse", func() { 18 | f := parser.ParseString 19 | if *parseFile { 20 | f = parser.ParseFile 21 | } 22 | pr, err := f(*parseExprArg) 23 | e.Exit(err) 24 | fmt.Println(pr.LispResult()) 25 | }) 26 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | 3 | let 4 | goyacc = buildGoPackage rec { 5 | name = "goyacc-${version}"; 6 | version = "2018-06-20"; 7 | rev = "25b95b48224cce18163c7d49dcfb89a2d5ecd209"; 8 | 9 | goPackagePath = "golang.org/x/tools"; 10 | subPackages = [ "cmd/goyacc" ]; 11 | 12 | src = fetchgit { 13 | inherit rev; 14 | url = "https://go.googlesource.com/tools"; 15 | sha256 = "0xa340bz8r3s88k91dldags32f3js8gqmcjsrsrn0p514kiacjsn"; 16 | }; 17 | }; 18 | in buildGoPackage rec { 19 | name = "go-nix"; 20 | goPackagePath = "github.com/orivej/go-nix"; 21 | src = ./.; 22 | # generated with https://github.com/adisbladis/vgo2nix 23 | goDeps = ./deps.nix; 24 | buildInputs = [ 25 | ragel 26 | goyacc 27 | ]; 28 | doCheck = true; 29 | checkPhase = '' 30 | NIX_PATH=nixpkgs=${lib.cleanSource path} \ 31 | GOPATH=$NIX_BUILD_TOP/go \ 32 | go test -v ${goPackagePath}/... 33 | ''; 34 | } 35 | -------------------------------------------------------------------------------- /deps.nix: -------------------------------------------------------------------------------- 1 | [ 2 | 3 | { 4 | goPackagePath = "github.com/alecthomas/assert"; 5 | fetch = { 6 | type = "git"; 7 | url = "https://github.com/alecthomas/assert"; 8 | rev = "405dbfeb8e38"; 9 | sha256 = "1l567pi17k593nrd1qlbmiq8z9jy3qs60px2a16fdpzjsizwqx8l"; 10 | }; 11 | } 12 | 13 | { 14 | goPackagePath = "github.com/alecthomas/colour"; 15 | fetch = { 16 | type = "git"; 17 | url = "https://github.com/alecthomas/colour"; 18 | rev = "60882d9e2721"; 19 | sha256 = "0iq566534gbzkd16ixg7fk298wd766821vvs80838yifx9yml5vs"; 20 | }; 21 | } 22 | 23 | { 24 | goPackagePath = "github.com/alecthomas/kingpin"; 25 | fetch = { 26 | type = "git"; 27 | url = "https://github.com/alecthomas/kingpin"; 28 | rev = "947dcec5ba9c"; 29 | sha256 = "0mndnv3hdngr3bxp7yxfd47cas4prv98sqw534mx7vp38gd88n5r"; 30 | }; 31 | } 32 | 33 | { 34 | goPackagePath = "github.com/alecthomas/repr"; 35 | fetch = { 36 | type = "git"; 37 | url = "https://github.com/alecthomas/repr"; 38 | rev = "117648cd9897"; 39 | sha256 = "05v1rgzdqc8razf702laagrvhvx68xd9yxxmzd3dyz0d6425pdrp"; 40 | }; 41 | } 42 | 43 | { 44 | goPackagePath = "github.com/alecthomas/template"; 45 | fetch = { 46 | type = "git"; 47 | url = "https://github.com/alecthomas/template"; 48 | rev = "a0175ee3bccc"; 49 | sha256 = "0qjgvvh26vk1cyfq9fadyhfgdj36f1iapbmr5xp6zqipldz8ffxj"; 50 | }; 51 | } 52 | 53 | { 54 | goPackagePath = "github.com/alecthomas/units"; 55 | fetch = { 56 | type = "git"; 57 | url = "https://github.com/alecthomas/units"; 58 | rev = "2efee857e7cf"; 59 | sha256 = "1j65b91qb9sbrml9cpabfrcf07wmgzzghrl7809hjjhrmbzri5bl"; 60 | }; 61 | } 62 | 63 | { 64 | goPackagePath = "github.com/davecgh/go-spew"; 65 | fetch = { 66 | type = "git"; 67 | url = "https://github.com/davecgh/go-spew"; 68 | rev = "v1.1.1"; 69 | sha256 = "0hka6hmyvp701adzag2g26cxdj47g21x6jz4sc6jjz1mn59d474y"; 70 | }; 71 | } 72 | 73 | { 74 | goPackagePath = "github.com/mattn/go-isatty"; 75 | fetch = { 76 | type = "git"; 77 | url = "https://github.com/mattn/go-isatty"; 78 | rev = "v0.0.3"; 79 | sha256 = "06w45aqz2a6yrk25axbly2k5wmsccv8cspb94bfmz4izvw8h927n"; 80 | }; 81 | } 82 | 83 | { 84 | goPackagePath = "github.com/orivej/e"; 85 | fetch = { 86 | type = "git"; 87 | url = "https://github.com/orivej/e"; 88 | rev = "ac3492690fda"; 89 | sha256 = "11jizr28kfkr6zscjxg95pqi6cjp08aqnhs41sdhc98nww78ilkr"; 90 | }; 91 | } 92 | 93 | { 94 | goPackagePath = "github.com/pkg/profile"; 95 | fetch = { 96 | type = "git"; 97 | url = "https://github.com/pkg/profile"; 98 | rev = "v1.2.1"; 99 | sha256 = "0blqmvgqvdbqmh3fp9pfdxc9w1qfshrr0zy9whj0sn372bw64qnr"; 100 | }; 101 | } 102 | 103 | { 104 | goPackagePath = "github.com/pmezard/go-difflib"; 105 | fetch = { 106 | type = "git"; 107 | url = "https://github.com/pmezard/go-difflib"; 108 | rev = "v1.0.0"; 109 | sha256 = "0c1cn55m4rypmscgf0rrb88pn58j3ysvc2d0432dp3c6fqg6cnzw"; 110 | }; 111 | } 112 | 113 | { 114 | goPackagePath = "github.com/sergi/go-diff"; 115 | fetch = { 116 | type = "git"; 117 | url = "https://github.com/sergi/go-diff"; 118 | rev = "v1.0.0"; 119 | sha256 = "0swiazj8wphs2zmk1qgq75xza6m19snif94h2m6fi8dqkwqdl7c7"; 120 | }; 121 | } 122 | 123 | { 124 | goPackagePath = "github.com/stretchr/testify"; 125 | fetch = { 126 | type = "git"; 127 | url = "https://github.com/stretchr/testify"; 128 | rev = "v1.2.2"; 129 | sha256 = "0dlszlshlxbmmfxj5hlwgv3r22x0y1af45gn1vd198nvvs3pnvfs"; 130 | }; 131 | } 132 | 133 | { 134 | goPackagePath = "golang.org/x/sys"; 135 | fetch = { 136 | type = "git"; 137 | url = "https://go.googlesource.com/sys"; 138 | rev = "d99a578cf41b"; 139 | sha256 = "10q9xx4pmnq92qn6ff4xp7n1hx766wvw2rf7pqcd6rx5plgwz8cm"; 140 | }; 141 | } 142 | ] 143 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/orivej/go-nix 2 | 3 | require ( 4 | github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 5 | github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect 6 | github.com/alecthomas/kingpin v2.2.6+incompatible 7 | github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 // indirect 8 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect 9 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect 10 | github.com/davecgh/go-spew v1.1.1 // indirect 11 | github.com/mattn/go-isatty v0.0.3 // indirect 12 | github.com/orivej/e v0.0.0-20180728214217-ac3492690fda 13 | github.com/pkg/profile v1.2.1 14 | github.com/pmezard/go-difflib v1.0.0 // indirect 15 | github.com/sergi/go-diff v1.0.0 // indirect 16 | github.com/stretchr/testify v1.2.2 // indirect 17 | golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= 2 | github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= 3 | github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= 4 | github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= 5 | github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= 6 | github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= 7 | github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= 8 | github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= 9 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= 10 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 11 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= 12 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 13 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 14 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 15 | github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= 16 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 17 | github.com/orivej/e v0.0.0-20180728214217-ac3492690fda h1:fqLgbcmo9qKecZOH8lByuxi9XXoIhNYBpRJEo4rDEUQ= 18 | github.com/orivej/e v0.0.0-20180728214217-ac3492690fda/go.mod h1:eOxOguJBxQH6q/o7CZvmR+fh5v1LHH1sfohtgISSSFA= 19 | github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE= 20 | github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 21 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 22 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 23 | github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 24 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 25 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 26 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 27 | golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b h1:cmOZLU2i7CLArKNViO+ZCQ47wqYFyKEIpbGWp+b6Uoc= 28 | golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 29 | -------------------------------------------------------------------------------- /internal/error.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import "fmt" 4 | 5 | type Error string 6 | 7 | func Panic(v string) { 8 | panic(Error(v)) 9 | } 10 | 11 | func Panicf(format string, a ...interface{}) { 12 | Panic(fmt.Sprintf(format, a...)) 13 | } 14 | 15 | func Check(err error) { 16 | if err != nil { 17 | Panic(err.Error()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /nix/eval/derivation.go: -------------------------------------------------------------------------------- 1 | package eval 2 | 3 | type Derivation struct { 4 | System string // e.g. "x86_64-linux" 5 | Name string 6 | Builder interface{} // a Derivation or an ast.Path 7 | Attrs map[Sym]interface{} 8 | } 9 | -------------------------------------------------------------------------------- /nix/eval/eval.go: -------------------------------------------------------------------------------- 1 | package eval 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | 8 | "github.com/orivej/e" 9 | p "github.com/orivej/go-nix/nix/parser" 10 | ) 11 | 12 | type Scope struct { 13 | Binds Set 14 | LowPrio bool 15 | Parent *Scope 16 | } 17 | 18 | func (scope *Scope) Subscope(binds Set, lowPrio bool) *Scope { 19 | return &Scope{Binds: binds, LowPrio: lowPrio, Parent: scope} 20 | } 21 | 22 | type Expression struct { 23 | Value Value 24 | Scope *Scope 25 | Parser *p.Parser 26 | Node *p.Node 27 | Sym Sym 28 | } 29 | 30 | func (x *Expression) String() string { 31 | return ValueString(x.Value) 32 | } 33 | 34 | func (x *Expression) WithNode(n *p.Node) *Expression { 35 | y := *x 36 | y.Node = n 37 | return &y 38 | } 39 | 40 | func (x *Expression) WithScoped(n *p.Node, scope *Scope) *Expression { 41 | y := *x 42 | y.Scope = scope 43 | y.Node = n 44 | return &y 45 | } 46 | 47 | func (x *Expression) Eval() Value { 48 | if x.Value == nil { 49 | x.Value = x.force() 50 | x.Scope = nil 51 | } 52 | return x.Value 53 | } 54 | 55 | func (x *Expression) tokenString(i int) string { 56 | return x.Parser.TokenString(x.Node.Tokens[i]) 57 | } 58 | 59 | func (x *Expression) force() (val Value) { 60 | var err error 61 | pr := x.Parser 62 | n := x.Node 63 | nt := x.Node.Type 64 | if x.Sym != 0 { 65 | nt = p.IDNode 66 | } 67 | switch nt { 68 | default: 69 | panic(fmt.Sprintln("unsupported node type:", n.Type)) 70 | case p.URINode: 71 | return URI(x.tokenString(0)) 72 | case p.PathNode: 73 | return Path(x.tokenString(0)) 74 | case p.FloatNode: 75 | val, err = strconv.ParseFloat(x.tokenString(0), 64) 76 | noerr(err) 77 | case p.IntNode: 78 | val, err = strconv.Atoi(x.tokenString(0)) 79 | noerr(err) 80 | 81 | case p.StringNode, p.IStringNode: 82 | parts := make([]string, len(n.Nodes)) 83 | for i, c := range n.Nodes { 84 | switch c.Type { 85 | default: 86 | panic(fmt.Sprintln("unsupported string part type:", c.Type)) 87 | case p.TextNode: 88 | parts[i] = pr.TokenString(c.Tokens[0]) 89 | case p.InterpNode: 90 | y := x.WithNode(c.Nodes[0]) 91 | parts[i] = InterpString(y.Eval()) 92 | } 93 | } 94 | return strings.Join(parts, "") 95 | 96 | case p.ParensNode: 97 | return x.WithNode(n.Nodes[0]).Eval() 98 | 99 | case p.ListNode: 100 | parts := make(List, len(n.Nodes)) 101 | for i, c := range n.Nodes { 102 | parts[i] = x.WithNode(c) 103 | } 104 | return parts 105 | 106 | case p.SetNode, p.RecSetNode: 107 | set := make(Set, len(n.Nodes)) // Inheriting makes it larger than this. 108 | scope := x.Scope 109 | if nt == p.RecSetNode { 110 | scope = scope.Subscope(set, false) 111 | } 112 | for _, c := range n.Nodes { 113 | switch c.Type { 114 | case p.BindNode: 115 | attrpath := x.WithScoped(c.Nodes[0], scope).evalAttrpath() 116 | set.Bind(attrpath, x.WithScoped(c.Nodes[1], scope)) 117 | case p.InheritNode: 118 | for _, interpid := range c.Nodes[0].Nodes { 119 | y := x.WithNode(interpid) 120 | y.Sym = Intern(y.attrString()) 121 | set.Bind1(y.Sym, y) 122 | } 123 | case p.InheritFromNode: 124 | // This is not as lazy as it can be. 125 | from := x.WithScoped(c.Nodes[0], scope) 126 | for _, interpid := range c.Nodes[1].Nodes { 127 | sym := Intern(x.WithNode(interpid).attrString()) 128 | set.Bind1(sym, from.Select1(sym)) 129 | } 130 | } 131 | } 132 | return set 133 | 134 | case p.SelectNode, p.SelectOrNode: 135 | attrpath := x.WithNode(n.Nodes[1]).evalAttrpath() 136 | var or *Expression 137 | if nt == p.SelectOrNode { 138 | or = x.WithNode(n.Nodes[2]) 139 | } 140 | return x.WithNode(n.Nodes[0]).Select(attrpath, or).Eval() 141 | } 142 | 143 | return 144 | } 145 | 146 | func (x *Expression) Select1(sym Sym) *Expression { 147 | return x.Eval().(Set)[sym] 148 | } 149 | 150 | func (x *Expression) Select(syms []Sym, or *Expression) *Expression { 151 | for _, sym := range syms { 152 | val := x.Eval() 153 | if set, ok := val.(Set); ok { 154 | if y, ok := set[sym]; ok { 155 | x = y 156 | } else if or != nil { 157 | return or 158 | } else { 159 | throw(fmt.Errorf("%v does not contain %v", y, sym)) 160 | } 161 | } else { 162 | throw(fmt.Errorf("%v is not a set", val)) 163 | } 164 | } 165 | return x 166 | } 167 | 168 | func (x *Expression) evalAttrpath() []Sym { 169 | attrs := make([]Sym, len(x.Node.Nodes)) 170 | for i, c := range x.Node.Nodes { 171 | y := x.WithNode(c) 172 | switch c.Type { 173 | case p.IDNode: 174 | attrs[i] = Intern(y.tokenString(0)) 175 | case p.StringNode: 176 | attrs[i] = Intern(InterpString(y.Eval())) 177 | case p.InterpNode: 178 | attrs[i] = Intern(InterpString(y.WithNode(y.Node.Nodes[0]).Eval())) 179 | default: 180 | panic(fmt.Errorf("unsupported attrpath node %v", c.Type)) 181 | } 182 | } 183 | return attrs 184 | } 185 | 186 | func (x *Expression) attrString() string { 187 | switch x.Node.Type { 188 | case p.IDNode: 189 | return x.tokenString(0) 190 | case p.StringNode: 191 | return x.Eval().(string) 192 | case p.InterpNode: 193 | return InterpString(x.WithNode(x.Node.Nodes[0]).Eval()) 194 | default: 195 | panic(fmt.Errorf("unsupported attr type %v", x.Node.Type)) 196 | } 197 | } 198 | 199 | func ParseResult(pr *p.Parser) Value { 200 | x := Expression{Parser: pr, Node: pr.Result} 201 | return x.Eval() 202 | } 203 | 204 | func throw(err error) { 205 | if err != nil { 206 | panic(err) 207 | } 208 | } 209 | 210 | func noerr(err error) { 211 | e.Exit(err) 212 | } 213 | -------------------------------------------------------------------------------- /nix/eval/symbol.go: -------------------------------------------------------------------------------- 1 | package eval 2 | 3 | type Sym int 4 | 5 | type Symtab struct { 6 | names []string 7 | syms map[string]Sym 8 | } 9 | 10 | func NewSymtab() *Symtab { 11 | return &Symtab{names: []string{""}, syms: map[string]Sym{"": 0}} 12 | } 13 | 14 | func (st *Symtab) Intern(name string) Sym { 15 | if sym, ok := st.syms[name]; ok { 16 | return sym 17 | } 18 | sym := Sym(len(st.names)) 19 | st.names = append(st.names, name) 20 | st.syms[name] = sym 21 | return sym 22 | } 23 | 24 | func (st *Symtab) Name(sym Sym) string { 25 | return st.names[sym] 26 | } 27 | 28 | var globalSymtab = NewSymtab() 29 | 30 | func Intern(name string) Sym { 31 | return globalSymtab.Intern(name) 32 | } 33 | 34 | func (sym Sym) String() string { 35 | return globalSymtab.Name(sym) 36 | } 37 | -------------------------------------------------------------------------------- /nix/eval/value.go: -------------------------------------------------------------------------------- 1 | package eval 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | // Value is one of: int, float64, string, URI, Path, List, Set 10 | type Value interface{} 11 | 12 | type URI string 13 | type Path string 14 | type List []*Expression 15 | type Set map[Sym]*Expression 16 | 17 | func (set Set) Bind1(sym Sym, x *Expression) { 18 | if _, ok := set[sym]; ok { 19 | throw(fmt.Errorf("%v is already defined", sym)) 20 | } 21 | set[sym] = x 22 | } 23 | 24 | func (set Set) Bind(syms []Sym, x *Expression) { 25 | last := len(syms) - 1 26 | for _, sym := range syms[:last] { 27 | if subset, ok := set[sym]; ok { 28 | set = subset.Value.(Set) 29 | } else { 30 | subset := Set{} 31 | set[sym] = &Expression{Value: subset} 32 | set = subset 33 | } 34 | } 35 | set.Bind1(syms[last], x) 36 | } 37 | 38 | func ValueString(val Value) string { 39 | switch v := val.(type) { 40 | case nil: 41 | return "..." 42 | case int: 43 | return strconv.Itoa(v) 44 | case float64: 45 | return strconv.FormatFloat(v, 'g', -1, 64) 46 | case string: 47 | return v 48 | case URI: 49 | return string(v) 50 | case Path: 51 | return string(v) 52 | case List: 53 | last := len(v) + 1 54 | parts := make([]string, last+1) 55 | parts[0], parts[last] = "[", "]" 56 | for i, x := range v { 57 | parts[i+1] = x.String() 58 | } 59 | return strings.Join(parts, " ") 60 | case Set: 61 | last := len(v) + 1 62 | parts := make([]string, last+1) 63 | parts[0], parts[last] = "{", "}" 64 | i := 1 65 | for sym, x := range v { 66 | parts[i] = fmt.Sprintf("%s = %s;", sym, x) 67 | i++ 68 | } 69 | return strings.Join(parts, " ") 70 | default: 71 | panic(fmt.Errorf("can not coerce %v to a string", val)) 72 | } 73 | } 74 | 75 | func InterpString(val Value) string { 76 | switch v := val.(type) { 77 | case string: 78 | return v 79 | case URI: 80 | return string(v) 81 | case Path: 82 | return string(v) 83 | default: 84 | panic(fmt.Errorf("can not coerce %v to a string", val)) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /nix/nixhash/base32.go: -------------------------------------------------------------------------------- 1 | package nixhash 2 | 3 | const base32Chars = "0123456789abcdfghijklmnpqrsvwxyz" 4 | 5 | func base32Encode(data []byte) []byte { 6 | s := make([]byte, (len(data)*8+4)/5) 7 | n, i, j := len(data)-1, len(data), len(s)*5%8 8 | for k := range s { 9 | j -= 5 10 | if j < 0 { 11 | i, j = i-1, j+8 12 | } 13 | c := data[i] >> uint8(j) 14 | if i < n { 15 | c |= data[i+1] << uint8(8-j) 16 | } 17 | s[k] = base32Chars[c&0x1f] 18 | } 19 | return s 20 | } 21 | -------------------------------------------------------------------------------- /nix/nixhash/dump.go: -------------------------------------------------------------------------------- 1 | package nixhash 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "os" 7 | "path" 8 | "sort" 9 | 10 | "github.com/orivej/e" 11 | "github.com/orivej/go-nix/internal" 12 | ) 13 | 14 | func dump(p string, sink Sink) { 15 | fi, err := os.Lstat(p) 16 | e.Exit(err) 17 | sink.S("(") 18 | switch { 19 | case fi.Mode().IsRegular(): 20 | sink.S("type", "regular") 21 | if fi.Mode()&0100 != 0 { 22 | sink.S("executable", "") 23 | } 24 | dumpContents(p, fi.Size(), sink) 25 | case fi.IsDir(): 26 | sink.S("type", "directory") 27 | for _, name := range readDirectory(p) { 28 | sink.S("entry", "(", "name", name, "node") 29 | dump(path.Join(p, name), sink) 30 | sink.S(")") 31 | } 32 | case fi.Mode()&os.ModeSymlink != 0: 33 | target, err := os.Readlink(p) 34 | e.Exit(err) 35 | sink.S("type", "symlink", "target", target) 36 | default: 37 | internal.Panicf("illegal file: %q", path.Join(p, fi.Name())) 38 | } 39 | sink.S(")") 40 | } 41 | 42 | func dumpContents(p string, size int64, sink Sink) { 43 | sink.S("contents") 44 | f, err := os.Open(p) 45 | e.Exit(err) 46 | e.Exit(sink.Begin(size)) 47 | _, err = io.Copy(sink, f) 48 | e.Exit(err) 49 | e.Exit(sink.End()) 50 | e.Exit(f.Close()) 51 | } 52 | 53 | func readDirectory(p string) []string { 54 | fis, err := ioutil.ReadDir(p) 55 | internal.Check(err) 56 | names := make([]string, 0, len(fis)) 57 | for _, fi := range fis { 58 | name := fi.Name() 59 | if name != "" { 60 | names = append(names, name) 61 | } 62 | } 63 | sort.Strings(names) 64 | return names 65 | } 66 | -------------------------------------------------------------------------------- /nix/nixhash/hash.go: -------------------------------------------------------------------------------- 1 | // Package nixhash implements nix derivation hashing. 2 | package nixhash 3 | 4 | import ( 5 | "crypto/sha256" 6 | "encoding/base64" 7 | "encoding/hex" 8 | "io" 9 | "os" 10 | 11 | "github.com/orivej/e" 12 | ) 13 | 14 | var narVersionMagic1 = []byte("nix-archive-1") 15 | 16 | type Hash []byte 17 | 18 | // String sha256. 19 | func String(s string) Hash { 20 | b := sha256.Sum256([]byte(s)) 21 | return Hash(b[:]) 22 | } 23 | 24 | // File sha256. 25 | func File(path string) Hash { 26 | f, err := os.Open(path) 27 | e.Exit(err) 28 | defer e.CloseOrExit(f) 29 | 30 | h := sha256.New() 31 | _, err = io.Copy(h, f) 32 | e.Exit(err) 33 | 34 | return Hash(h.Sum(nil)) 35 | } 36 | 37 | // Path hash. 38 | func Path(path string) Hash { 39 | h := sha256.New() 40 | hs := NewSink(h) 41 | _, err := hs.Write(narVersionMagic1) 42 | e.Exit(err) 43 | dump(path, hs) 44 | 45 | return Hash(h.Sum(nil)) 46 | } 47 | 48 | // Compress the hash down to size bytes. 49 | func (h Hash) Compress(size int) Hash { 50 | r := make([]byte, size) 51 | for i, b := range h { 52 | r[i%size] ^= b 53 | } 54 | return Hash(r) 55 | } 56 | 57 | // String encodes the hash to a string in a given base (16, 32 or 64). 58 | func (h Hash) String(base int) string { 59 | switch base { 60 | case 16: 61 | return hex.EncodeToString(h) 62 | case 32: 63 | return string(base32Encode(h)) 64 | case 64: 65 | return base64.StdEncoding.EncodeToString(h) 66 | default: 67 | panic("unsupported base") 68 | } 69 | } 70 | 71 | // TypeString prepends "sha256:" to String. 72 | func (h Hash) TypeString(base int) string { 73 | return "sha256:" + h.String(base) 74 | } 75 | -------------------------------------------------------------------------------- /nix/nixhash/hash_test.go: -------------------------------------------------------------------------------- 1 | package nixhash 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path/filepath" 7 | "testing" 8 | 9 | "github.com/alecthomas/assert" 10 | "github.com/orivej/e" 11 | ) 12 | 13 | func TestHash(t *testing.T) { 14 | dir, err := ioutil.TempDir("", "TestHash") 15 | e.Panic(err) 16 | defer func() { e.Panic(os.RemoveAll(dir)) }() 17 | 18 | file := filepath.Join(dir, "name") 19 | err = ioutil.WriteFile(file, []byte("text\n"), 0644) 20 | e.Panic(err) 21 | 22 | assert.Equal(t, "/nix/store/a68bcimav7hwazsfk1iiabv7fxyr3dh4-name", 23 | StorePath(file, "")) 24 | } 25 | -------------------------------------------------------------------------------- /nix/nixhash/sink.go: -------------------------------------------------------------------------------- 1 | package nixhash 2 | 3 | import ( 4 | "encoding/binary" 5 | "io" 6 | 7 | "github.com/orivej/e" 8 | ) 9 | 10 | var sinkPad = make([]byte, 8) 11 | 12 | // Sink encodes writes as: 13 | // - 8 bytes size 14 | // - data 15 | // - pad to 8 bytes with zeroes 16 | type Sink interface { 17 | Begin(int64) error 18 | End() error 19 | io.Writer 20 | B([]byte) 21 | S(...string) 22 | } 23 | 24 | func NewSink(w io.Writer) Sink { 25 | return &sink{w: w, n: -1} 26 | } 27 | 28 | type sink struct { 29 | w io.Writer 30 | n int64 31 | } 32 | 33 | func (sink *sink) Begin(size int64) error { 34 | sink.n = size 35 | return binary.Write(sink.w, binary.LittleEndian, size) 36 | } 37 | 38 | func (sink *sink) End() error { 39 | _, err := sink.w.Write(sinkPad[:uint64(-sink.n)%8]) 40 | sink.n = -1 41 | return err 42 | } 43 | 44 | func (sink *sink) Write(data []byte) (int, error) { 45 | atomic := sink.n == -1 46 | if atomic { 47 | err := sink.Begin(int64(len(data))) 48 | if err != nil { 49 | return 0, err 50 | } 51 | } 52 | n, err := sink.w.Write(data) 53 | if err != nil { 54 | return n, err 55 | } 56 | if atomic { 57 | err = sink.End() 58 | if err != nil { 59 | return n, err 60 | } 61 | } 62 | return n, nil 63 | } 64 | 65 | func (sink *sink) B(data []byte) { 66 | _, err := sink.Write(data) 67 | e.Exit(err) 68 | } 69 | 70 | func (sink *sink) S(ss ...string) { 71 | for _, s := range ss { 72 | sink.B([]byte(s)) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /nix/nixhash/store.go: -------------------------------------------------------------------------------- 1 | package nixhash 2 | 3 | import ( 4 | "path" 5 | "regexp" 6 | 7 | "github.com/orivej/go-nix/internal" 8 | ) 9 | 10 | const storeDir = "/nix/store" 11 | 12 | var rxStoreName = regexp.MustCompile(`^[A-Za-z0-9+._?=-]+$`) 13 | 14 | // StorePath returns nix store path of the pathname. 15 | func StorePath(pathname, basename string) string { 16 | if basename == "" { 17 | basename = path.Base(pathname) 18 | } 19 | checkStoreName(basename) 20 | h := Path(pathname) 21 | return fixedOutputPath(true, h, basename) 22 | } 23 | 24 | func fixedOutputPath(recursive bool, contentHash Hash, name string) string { 25 | if recursive { 26 | return makeStorePath("source", contentHash, name) 27 | } 28 | h := String("fixed:out" + contentHash.TypeString(16) + ":") 29 | return makeStorePath("output:out", h, name) 30 | } 31 | 32 | func makeStorePath(pathType string, h Hash, name string) string { 33 | s := pathType + ":" + h.TypeString(16) + ":" + storeDir + ":" + name 34 | return storeDir + "/" + String(s).Compress(20).String(32) + "-" + name 35 | } 36 | 37 | func checkStoreName(name string) { 38 | if !rxStoreName.MatchString(name) || name[0] == '.' { 39 | internal.Panicf("illegal name: %q", name) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nix/parser/lexer.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | //go:generate ragel -Z -G2 machine.rl 4 | 5 | import ( 6 | "fmt" 7 | "go/token" 8 | "io/ioutil" 9 | ) 10 | 11 | type lexerToken struct{ sym, pos, end, prev int } 12 | 13 | type lexResult struct { 14 | file *token.File 15 | data []byte 16 | tokens []lexerToken 17 | comments []lexerToken 18 | } 19 | 20 | var fileset = token.NewFileSet() 21 | 22 | func newLexResult(path string, size int) *lexResult { 23 | if path == "" { 24 | path = "(string)" 25 | } 26 | return &lexResult{file: fileset.AddFile(path, -1, size)} 27 | } 28 | 29 | func (r *lexResult) At(offset int) string { 30 | p := r.file.Position(r.file.Pos(offset)) 31 | return fmt.Sprintf("%s:%d:%d: ", p.Filename, p.Line, p.Column) 32 | } 33 | 34 | func (r *lexResult) TokenBytes(i int) []byte { 35 | tok := r.tokens[i] 36 | return r.data[tok.pos:tok.end] 37 | } 38 | 39 | func (r *lexResult) TokenString(i int) string { 40 | return string(r.TokenBytes(i)) 41 | } 42 | 43 | func (r *lexResult) Last() string { 44 | tok := r.tokens[len(r.tokens)-1] 45 | return r.At(tok.pos) + symString(tok.sym) 46 | } 47 | 48 | func (r *lexResult) Errorf(format string, a ...interface{}) error { 49 | return fmt.Errorf("%s "+format, append([]interface{}{r.Last()}, a...)) 50 | } 51 | 52 | func symString(sym int) string { 53 | if sym >= yyPrivate-1 && sym < yyPrivate+len(yyToknames) { 54 | return yyToknames[sym-yyPrivate+1] 55 | } 56 | return fmt.Sprintf("'%c'", sym) 57 | } 58 | 59 | func (tok lexerToken) String() string { 60 | return fmt.Sprintf("%d-%d:%s", tok.pos, tok.end, symString(tok.sym)) 61 | } 62 | 63 | func lex(data []byte, path string) (r *lexResult, err error) { 64 | r = newLexResult(path, len(data)) 65 | err = lexData(data, r) 66 | return 67 | } 68 | 69 | func lexFile(path string) (r *lexResult, err error) { 70 | data, err := ioutil.ReadFile(path) 71 | if err != nil { 72 | return 73 | } 74 | return lex(data, path) 75 | } 76 | 77 | type Backrefs [][2]int 78 | 79 | func (stack *Backrefs) Push(i, fin int) { 80 | *stack = append(*stack, [2]int{i, fin}) 81 | } 82 | 83 | func (stack *Backrefs) Pop() (i, fin int) { 84 | backref := (*stack)[len(*stack)-1] 85 | *stack = (*stack)[:len(*stack)-1] 86 | return backref[0], backref[1] 87 | } 88 | -------------------------------------------------------------------------------- /nix/parser/lexer_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "io/ioutil" 5 | "sort" 6 | "testing" 7 | 8 | "github.com/alecthomas/assert" 9 | "github.com/orivej/e" 10 | "github.com/orivej/go-nix/nix/util" 11 | ) 12 | 13 | func TestLexOne(t *testing.T) { 14 | skipWithoutNixPath(t) 15 | path := attrsets 16 | data, err := ioutil.ReadFile(path) 17 | e.Exit(err) 18 | r, err := lex(data, path) 19 | t.Log(r.tokens) 20 | t.Log(r.comments) 21 | t.Log(r.Last()) 22 | assert.NoError(t, err) 23 | } 24 | 25 | func TestLexAll(t *testing.T) { 26 | if testing.Short() { 27 | t.SkipNow() 28 | } 29 | skipWithoutNixPath(t) 30 | hist := map[int]int{} 31 | err := util.WalkNix(nixpkgs, func(path string) error { 32 | r, err := lexFile(path) 33 | assert.NoError(t, err, path) 34 | for _, tok := range r.tokens { 35 | hist[tok.sym]++ 36 | } 37 | for _, tok := range r.comments { 38 | hist[tok.sym]++ 39 | } 40 | return nil 41 | }) 42 | assert.NoError(t, err) 43 | printSymHist(t, hist) 44 | } 45 | 46 | func BenchmarkLex(b *testing.B) { 47 | path := allPackages 48 | data, err := ioutil.ReadFile(path) 49 | e.Exit(err) 50 | 51 | for i := 0; i < b.N; i++ { 52 | _, err = lex(data, path) 53 | assert.NoError(b, err) 54 | } 55 | } 56 | 57 | func printSymHist(t *testing.T, hist map[int]int) { 58 | t.Helper() 59 | keys := make([]int, 0, len(hist)) 60 | for k := range hist { 61 | keys = append(keys, k) 62 | } 63 | sort.Slice(keys, func(i, j int) bool { return hist[keys[i]] < hist[keys[j]] }) 64 | for _, k := range keys { 65 | t.Log(hist[k], symString(k)) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /nix/parser/machine.go: -------------------------------------------------------------------------------- 1 | 2 | //line machine.rl:1 3 | // compile-command: "ragel -Z -G2 machine.rl" 4 | 5 | package parser 6 | 7 | import "fmt" 8 | 9 | const maxstack = 64 10 | 11 | 12 | //line machine.rl:99 13 | 14 | 15 | 16 | //line machine.go:17 17 | const expr_start int = 22 18 | const expr_first_final int = 22 19 | const expr_error int = 0 20 | 21 | const expr_en_qstring int = 79 22 | const expr_en_istring int = 82 23 | const expr_en_expr int = 22 24 | 25 | 26 | //line machine.rl:102 27 | 28 | func lexData(data []byte, r *lexResult) (err error) { 29 | var cs, act, ts, te, top int 30 | var stack [maxstack]int 31 | p, pe := 0, len(data) 32 | eof := pe 33 | 34 | //line machine.go:35 35 | { 36 | cs = expr_start 37 | top = 0 38 | ts = 0 39 | te = 0 40 | act = 0 41 | } 42 | 43 | //line machine.rl:109 44 | _, _, _, _, _ = expr_first_final, expr_error, expr_en_qstring, expr_en_istring, expr_en_expr 45 | if r.file == nil { 46 | r.file = fileset.AddFile("(string)", -1, len(data)) 47 | } 48 | if r.data == nil { 49 | r.data = data 50 | } else { 51 | r.data = append(r.data, data...) 52 | } 53 | nostack := func() bool { 54 | if top != maxstack { 55 | return false 56 | } 57 | err = r.Errorf("exceeds recursion limit") 58 | return true 59 | } 60 | tok := func(sym int) { r.tokens = append(r.tokens, lexerToken{sym: sym, pos: ts, end: te}) } 61 | tokcomment := func(sym int) { r.comments = append(r.comments, lexerToken{sym: sym, pos: ts, end: te}) } 62 | var backrefs Backrefs 63 | tokenter := func(sym, fin int) { backrefs.Push(len(r.tokens), fin); tok(sym); } 64 | tokleave := func(sym int) bool { 65 | tok(sym) 66 | if top == 0 || len(backrefs) == 0 { 67 | err = r.Errorf("does not close anything") 68 | return false 69 | } 70 | iprev, prevsym := backrefs.Pop() 71 | if prevsym != sym { 72 | err = r.Errorf("does not close %v", r.tokens[iprev]) 73 | return false 74 | } 75 | r.tokens[len(r.tokens)-1].prev = iprev 76 | return true 77 | } 78 | tokarg := func() bool { 79 | tok(int(data[ts])) 80 | if len(r.tokens) == 1 { 81 | err = r.Errorf("does not follow anything") 82 | return false 83 | } 84 | prev := &r.tokens[len(r.tokens)-2] 85 | switch prev.sym { 86 | case id: 87 | prev.sym = argID 88 | case '}': 89 | r.tokens[prev.prev].sym = argBracket 90 | default: 91 | err = r.Errorf("does not follow an argument of a function") 92 | return false 93 | } 94 | return true 95 | } 96 | addLines := func() { 97 | for i := ts; i < te; i++ { 98 | if data[i] == '\n' { 99 | r.file.AddLine(i) 100 | } 101 | } 102 | } 103 | 104 | 105 | //line machine.go:106 106 | { 107 | if p == pe { 108 | goto _test_eof 109 | } 110 | goto _resume 111 | 112 | _again: 113 | switch cs { 114 | case 22: 115 | goto st22 116 | case 23: 117 | goto st23 118 | case 1: 119 | goto st1 120 | case 24: 121 | goto st24 122 | case 2: 123 | goto st2 124 | case 3: 125 | goto st3 126 | case 25: 127 | goto st25 128 | case 26: 129 | goto st26 130 | case 27: 131 | goto st27 132 | case 28: 133 | goto st28 134 | case 29: 135 | goto st29 136 | case 30: 137 | goto st30 138 | case 31: 139 | goto st31 140 | case 32: 141 | goto st32 142 | case 33: 143 | goto st33 144 | case 4: 145 | goto st4 146 | case 5: 147 | goto st5 148 | case 34: 149 | goto st34 150 | case 35: 151 | goto st35 152 | case 36: 153 | goto st36 154 | case 37: 155 | goto st37 156 | case 6: 157 | goto st6 158 | case 38: 159 | goto st38 160 | case 7: 161 | goto st7 162 | case 8: 163 | goto st8 164 | case 39: 165 | goto st39 166 | case 40: 167 | goto st40 168 | case 9: 169 | goto st9 170 | case 10: 171 | goto st10 172 | case 41: 173 | goto st41 174 | case 42: 175 | goto st42 176 | case 43: 177 | goto st43 178 | case 44: 179 | goto st44 180 | case 45: 181 | goto st45 182 | case 11: 183 | goto st11 184 | case 12: 185 | goto st12 186 | case 46: 187 | goto st46 188 | case 47: 189 | goto st47 190 | case 48: 191 | goto st48 192 | case 13: 193 | goto st13 194 | case 14: 195 | goto st14 196 | case 49: 197 | goto st49 198 | case 50: 199 | goto st50 200 | case 51: 201 | goto st51 202 | case 52: 203 | goto st52 204 | case 53: 205 | goto st53 206 | case 54: 207 | goto st54 208 | case 55: 209 | goto st55 210 | case 56: 211 | goto st56 212 | case 57: 213 | goto st57 214 | case 58: 215 | goto st58 216 | case 59: 217 | goto st59 218 | case 60: 219 | goto st60 220 | case 61: 221 | goto st61 222 | case 62: 223 | goto st62 224 | case 63: 225 | goto st63 226 | case 64: 227 | goto st64 228 | case 65: 229 | goto st65 230 | case 66: 231 | goto st66 232 | case 67: 233 | goto st67 234 | case 68: 235 | goto st68 236 | case 69: 237 | goto st69 238 | case 70: 239 | goto st70 240 | case 71: 241 | goto st71 242 | case 72: 243 | goto st72 244 | case 73: 245 | goto st73 246 | case 74: 247 | goto st74 248 | case 75: 249 | goto st75 250 | case 76: 251 | goto st76 252 | case 15: 253 | goto st15 254 | case 77: 255 | goto st77 256 | case 78: 257 | goto st78 258 | case 79: 259 | goto st79 260 | case 80: 261 | goto st80 262 | case 16: 263 | goto st16 264 | case 17: 265 | goto st17 266 | case 81: 267 | goto st81 268 | case 82: 269 | goto st82 270 | case 83: 271 | goto st83 272 | case 18: 273 | goto st18 274 | case 19: 275 | goto st19 276 | case 20: 277 | goto st20 278 | case 21: 279 | goto st21 280 | case 84: 281 | goto st84 282 | case 85: 283 | goto st85 284 | case 86: 285 | goto st86 286 | case 0: 287 | goto st0 288 | } 289 | 290 | if p++; p == pe { 291 | goto _test_eof 292 | } 293 | _resume: 294 | switch cs { 295 | case 22: 296 | goto st_case_22 297 | case 23: 298 | goto st_case_23 299 | case 1: 300 | goto st_case_1 301 | case 24: 302 | goto st_case_24 303 | case 2: 304 | goto st_case_2 305 | case 3: 306 | goto st_case_3 307 | case 25: 308 | goto st_case_25 309 | case 26: 310 | goto st_case_26 311 | case 27: 312 | goto st_case_27 313 | case 28: 314 | goto st_case_28 315 | case 29: 316 | goto st_case_29 317 | case 30: 318 | goto st_case_30 319 | case 31: 320 | goto st_case_31 321 | case 32: 322 | goto st_case_32 323 | case 33: 324 | goto st_case_33 325 | case 4: 326 | goto st_case_4 327 | case 5: 328 | goto st_case_5 329 | case 34: 330 | goto st_case_34 331 | case 35: 332 | goto st_case_35 333 | case 36: 334 | goto st_case_36 335 | case 37: 336 | goto st_case_37 337 | case 6: 338 | goto st_case_6 339 | case 38: 340 | goto st_case_38 341 | case 7: 342 | goto st_case_7 343 | case 8: 344 | goto st_case_8 345 | case 39: 346 | goto st_case_39 347 | case 40: 348 | goto st_case_40 349 | case 9: 350 | goto st_case_9 351 | case 10: 352 | goto st_case_10 353 | case 41: 354 | goto st_case_41 355 | case 42: 356 | goto st_case_42 357 | case 43: 358 | goto st_case_43 359 | case 44: 360 | goto st_case_44 361 | case 45: 362 | goto st_case_45 363 | case 11: 364 | goto st_case_11 365 | case 12: 366 | goto st_case_12 367 | case 46: 368 | goto st_case_46 369 | case 47: 370 | goto st_case_47 371 | case 48: 372 | goto st_case_48 373 | case 13: 374 | goto st_case_13 375 | case 14: 376 | goto st_case_14 377 | case 49: 378 | goto st_case_49 379 | case 50: 380 | goto st_case_50 381 | case 51: 382 | goto st_case_51 383 | case 52: 384 | goto st_case_52 385 | case 53: 386 | goto st_case_53 387 | case 54: 388 | goto st_case_54 389 | case 55: 390 | goto st_case_55 391 | case 56: 392 | goto st_case_56 393 | case 57: 394 | goto st_case_57 395 | case 58: 396 | goto st_case_58 397 | case 59: 398 | goto st_case_59 399 | case 60: 400 | goto st_case_60 401 | case 61: 402 | goto st_case_61 403 | case 62: 404 | goto st_case_62 405 | case 63: 406 | goto st_case_63 407 | case 64: 408 | goto st_case_64 409 | case 65: 410 | goto st_case_65 411 | case 66: 412 | goto st_case_66 413 | case 67: 414 | goto st_case_67 415 | case 68: 416 | goto st_case_68 417 | case 69: 418 | goto st_case_69 419 | case 70: 420 | goto st_case_70 421 | case 71: 422 | goto st_case_71 423 | case 72: 424 | goto st_case_72 425 | case 73: 426 | goto st_case_73 427 | case 74: 428 | goto st_case_74 429 | case 75: 430 | goto st_case_75 431 | case 76: 432 | goto st_case_76 433 | case 15: 434 | goto st_case_15 435 | case 77: 436 | goto st_case_77 437 | case 78: 438 | goto st_case_78 439 | case 79: 440 | goto st_case_79 441 | case 80: 442 | goto st_case_80 443 | case 16: 444 | goto st_case_16 445 | case 17: 446 | goto st_case_17 447 | case 81: 448 | goto st_case_81 449 | case 82: 450 | goto st_case_82 451 | case 83: 452 | goto st_case_83 453 | case 18: 454 | goto st_case_18 455 | case 19: 456 | goto st_case_19 457 | case 20: 458 | goto st_case_20 459 | case 21: 460 | goto st_case_21 461 | case 84: 462 | goto st_case_84 463 | case 85: 464 | goto st_case_85 465 | case 86: 466 | goto st_case_86 467 | case 0: 468 | goto st_case_0 469 | } 470 | goto st_out 471 | tr0: 472 | //line machine.rl:95 473 | p = (te) - 1 474 | { tok(int(data[ts])) } 475 | goto st22 476 | tr2: 477 | //line machine.rl:69 478 | p = (te) - 1 479 | { tok(float) } 480 | goto st22 481 | tr5: 482 | //line NONE:1 483 | switch act { 484 | case 9: 485 | {p = (te) - 1 486 | tok(assert_) } 487 | case 10: 488 | {p = (te) - 1 489 | tok(else_) } 490 | case 11: 491 | {p = (te) - 1 492 | tok(if_) } 493 | case 12: 494 | {p = (te) - 1 495 | tok(in) } 496 | case 13: 497 | {p = (te) - 1 498 | tok(inherit) } 499 | case 14: 500 | {p = (te) - 1 501 | tok(let) } 502 | case 15: 503 | {p = (te) - 1 504 | tok(or_) } 505 | case 16: 506 | {p = (te) - 1 507 | tok(rec) } 508 | case 17: 509 | {p = (te) - 1 510 | tok(then) } 511 | case 18: 512 | {p = (te) - 1 513 | tok(with) } 514 | case 27: 515 | {p = (te) - 1 516 | tok(float) } 517 | case 28: 518 | {p = (te) - 1 519 | tok(int_) } 520 | case 29: 521 | {p = (te) - 1 522 | tok(id) } 523 | case 30: 524 | {p = (te) - 1 525 | tok(ellipsis) } 526 | case 39: 527 | {p = (te) - 1 528 | tok(concat) } 529 | case 48: 530 | {p = (te) - 1 531 | tok(int(data[ts])) } 532 | } 533 | 534 | goto st22 535 | tr14: 536 | //line machine.rl:64 537 | te = p+1 538 | { tokcomment(comment); addLines() } 539 | goto st22 540 | tr17: 541 | //line machine.rl:68 542 | te = p+1 543 | { tok(path) } 544 | goto st22 545 | tr31: 546 | //line machine.rl:95 547 | te = p+1 548 | { tok(int(data[ts])) } 549 | goto st22 550 | tr33: 551 | //line machine.rl:62 552 | te = p+1 553 | { r.file.AddLine(ts) } 554 | goto st22 555 | tr35: 556 | //line machine.rl:84 557 | te = p+1 558 | { tokenter('"', '"'); { if nostack() { return }; {stack[top] = 22; top++; goto st79 }} } 559 | goto st22 560 | tr40: 561 | //line machine.rl:88 562 | te = p+1 563 | { tokenter('(', ')'); { if nostack() { return }; {stack[top] = 22; top++; goto st22 }} } 564 | goto st22 565 | tr41: 566 | //line machine.rl:91 567 | te = p+1 568 | { if !tokleave(int(data[ts])) { return }; {top--; cs = stack[top];goto _again } } 569 | goto st22 570 | tr48: 571 | //line machine.rl:93 572 | te = p+1 573 | { if !tokarg() { return }; } 574 | goto st22 575 | tr53: 576 | //line machine.rl:89 577 | te = p+1 578 | { tokenter('[', ']'); { if nostack() { return }; {stack[top] = 22; top++; goto st22 }} } 579 | goto st22 580 | tr63: 581 | //line machine.rl:90 582 | te = p+1 583 | { tokenter('{', '}'); { if nostack() { return }; {stack[top] = 22; top++; goto st22 }} } 584 | goto st22 585 | tr66: 586 | //line machine.rl:95 587 | te = p 588 | p-- 589 | { tok(int(data[ts])) } 590 | goto st22 591 | tr68: 592 | //line machine.rl:69 593 | te = p 594 | p-- 595 | { tok(float) } 596 | goto st22 597 | tr70: 598 | //line machine.rl:61 599 | te = p 600 | p-- 601 | 602 | goto st22 603 | tr71: 604 | //line machine.rl:78 605 | te = p+1 606 | { tok(neq) } 607 | goto st22 608 | tr72: 609 | //line machine.rl:63 610 | te = p 611 | p-- 612 | { tokcomment(comment) } 613 | goto st22 614 | tr73: 615 | //line machine.rl:87 616 | te = p+1 617 | { tokenter(interp, '}'); { if nostack() { return }; {stack[top] = 22; top++; goto st22 }} } 618 | goto st22 619 | tr74: 620 | //line machine.rl:76 621 | te = p+1 622 | { tok(and) } 623 | goto st22 624 | tr75: 625 | //line machine.rl:85 626 | te = p+1 627 | { tokenter(ii, ii); { if nostack() { return }; {stack[top] = 22; top++; goto st82 }} } 628 | goto st22 629 | tr77: 630 | //line machine.rl:66 631 | te = p 632 | p-- 633 | { tok(path) } 634 | goto st22 635 | tr79: 636 | //line machine.rl:74 637 | te = p+1 638 | { tok(impl) } 639 | goto st22 640 | tr83: 641 | //line machine.rl:81 642 | te = p+1 643 | { tok(update) } 644 | goto st22 645 | tr84: 646 | //line machine.rl:70 647 | te = p 648 | p-- 649 | { tok(int_) } 650 | goto st22 651 | tr86: 652 | //line machine.rl:71 653 | te = p 654 | p-- 655 | { tok(id) } 656 | goto st22 657 | tr87: 658 | //line machine.rl:79 659 | te = p+1 660 | { tok(leq) } 661 | goto st22 662 | tr88: 663 | //line machine.rl:77 664 | te = p+1 665 | { tok(eq) } 666 | goto st22 667 | tr89: 668 | //line machine.rl:80 669 | te = p+1 670 | { tok(geq) } 671 | goto st22 672 | tr90: 673 | //line machine.rl:65 674 | te = p 675 | p-- 676 | { tok(uri) } 677 | goto st22 678 | tr101: 679 | //line machine.rl:53 680 | te = p 681 | p-- 682 | { tok(in) } 683 | goto st22 684 | tr118: 685 | //line machine.rl:75 686 | te = p+1 687 | { tok(or) } 688 | goto st22 689 | tr120: 690 | //line machine.rl:67 691 | te = p 692 | p-- 693 | { tok(path) } 694 | goto st22 695 | st22: 696 | //line NONE:1 697 | ts = 0 698 | 699 | if p++; p == pe { 700 | goto _test_eof22 701 | } 702 | st_case_22: 703 | //line NONE:1 704 | ts = p 705 | 706 | //line machine.go:707 707 | switch data[p] { 708 | case 0: 709 | goto tr30 710 | case 9: 711 | goto st26 712 | case 10: 713 | goto tr33 714 | case 13: 715 | goto st26 716 | case 32: 717 | goto st26 718 | case 33: 719 | goto st27 720 | case 34: 721 | goto tr35 722 | case 35: 723 | goto st28 724 | case 36: 725 | goto st29 726 | case 38: 727 | goto st30 728 | case 39: 729 | goto st31 730 | case 40: 731 | goto tr40 732 | case 41: 733 | goto tr41 734 | case 43: 735 | goto tr42 736 | case 45: 737 | goto tr43 738 | case 46: 739 | goto tr44 740 | case 47: 741 | goto tr45 742 | case 48: 743 | goto tr46 744 | case 58: 745 | goto tr48 746 | case 60: 747 | goto tr49 748 | case 61: 749 | goto st46 750 | case 62: 751 | goto st47 752 | case 64: 753 | goto tr48 754 | case 91: 755 | goto tr53 756 | case 93: 757 | goto tr41 758 | case 95: 759 | goto tr54 760 | case 97: 761 | goto tr55 762 | case 101: 763 | goto tr56 764 | case 105: 765 | goto tr57 766 | case 108: 767 | goto tr58 768 | case 111: 769 | goto tr59 770 | case 114: 771 | goto tr60 772 | case 116: 773 | goto tr61 774 | case 119: 775 | goto tr62 776 | case 123: 777 | goto tr63 778 | case 124: 779 | goto st75 780 | case 125: 781 | goto tr41 782 | case 126: 783 | goto tr65 784 | } 785 | switch { 786 | case data[p] < 65: 787 | if 49 <= data[p] && data[p] <= 57 { 788 | goto tr47 789 | } 790 | case data[p] > 90: 791 | if 98 <= data[p] && data[p] <= 122 { 792 | goto tr52 793 | } 794 | default: 795 | goto tr52 796 | } 797 | goto tr31 798 | tr30: 799 | //line NONE:1 800 | te = p+1 801 | 802 | goto st23 803 | st23: 804 | if p++; p == pe { 805 | goto _test_eof23 806 | } 807 | st_case_23: 808 | //line machine.go:809 809 | if data[p] == 46 { 810 | goto st1 811 | } 812 | goto tr66 813 | st1: 814 | if p++; p == pe { 815 | goto _test_eof1 816 | } 817 | st_case_1: 818 | if 48 <= data[p] && data[p] <= 57 { 819 | goto tr1 820 | } 821 | goto tr0 822 | tr1: 823 | //line NONE:1 824 | te = p+1 825 | 826 | goto st24 827 | st24: 828 | if p++; p == pe { 829 | goto _test_eof24 830 | } 831 | st_case_24: 832 | //line machine.go:833 833 | switch data[p] { 834 | case 69: 835 | goto st2 836 | case 101: 837 | goto st2 838 | } 839 | if 48 <= data[p] && data[p] <= 57 { 840 | goto tr1 841 | } 842 | goto tr68 843 | st2: 844 | if p++; p == pe { 845 | goto _test_eof2 846 | } 847 | st_case_2: 848 | switch data[p] { 849 | case 43: 850 | goto st3 851 | case 45: 852 | goto st3 853 | } 854 | if 48 <= data[p] && data[p] <= 57 { 855 | goto st25 856 | } 857 | goto tr2 858 | st3: 859 | if p++; p == pe { 860 | goto _test_eof3 861 | } 862 | st_case_3: 863 | if 48 <= data[p] && data[p] <= 57 { 864 | goto st25 865 | } 866 | goto tr2 867 | st25: 868 | if p++; p == pe { 869 | goto _test_eof25 870 | } 871 | st_case_25: 872 | if 48 <= data[p] && data[p] <= 57 { 873 | goto st25 874 | } 875 | goto tr68 876 | st26: 877 | if p++; p == pe { 878 | goto _test_eof26 879 | } 880 | st_case_26: 881 | switch data[p] { 882 | case 9: 883 | goto st26 884 | case 13: 885 | goto st26 886 | case 32: 887 | goto st26 888 | } 889 | goto tr70 890 | st27: 891 | if p++; p == pe { 892 | goto _test_eof27 893 | } 894 | st_case_27: 895 | if data[p] == 61 { 896 | goto tr71 897 | } 898 | goto tr66 899 | st28: 900 | if p++; p == pe { 901 | goto _test_eof28 902 | } 903 | st_case_28: 904 | switch data[p] { 905 | case 10: 906 | goto tr72 907 | case 13: 908 | goto tr72 909 | } 910 | goto st28 911 | st29: 912 | if p++; p == pe { 913 | goto _test_eof29 914 | } 915 | st_case_29: 916 | if data[p] == 123 { 917 | goto tr73 918 | } 919 | goto tr66 920 | st30: 921 | if p++; p == pe { 922 | goto _test_eof30 923 | } 924 | st_case_30: 925 | if data[p] == 38 { 926 | goto tr74 927 | } 928 | goto tr66 929 | st31: 930 | if p++; p == pe { 931 | goto _test_eof31 932 | } 933 | st_case_31: 934 | if data[p] == 39 { 935 | goto tr75 936 | } 937 | goto tr66 938 | tr42: 939 | //line NONE:1 940 | te = p+1 941 | 942 | //line machine.rl:95 943 | act = 48; 944 | goto st32 945 | st32: 946 | if p++; p == pe { 947 | goto _test_eof32 948 | } 949 | st_case_32: 950 | //line machine.go:951 951 | switch data[p] { 952 | case 43: 953 | goto tr76 954 | case 47: 955 | goto st5 956 | case 95: 957 | goto st4 958 | } 959 | switch { 960 | case data[p] < 65: 961 | if 45 <= data[p] && data[p] <= 57 { 962 | goto st4 963 | } 964 | case data[p] > 90: 965 | if 97 <= data[p] && data[p] <= 122 { 966 | goto st4 967 | } 968 | default: 969 | goto st4 970 | } 971 | goto tr66 972 | tr9: 973 | //line NONE:1 974 | te = p+1 975 | 976 | //line machine.rl:73 977 | act = 30; 978 | goto st33 979 | tr76: 980 | //line NONE:1 981 | te = p+1 982 | 983 | //line machine.rl:82 984 | act = 39; 985 | goto st33 986 | st33: 987 | if p++; p == pe { 988 | goto _test_eof33 989 | } 990 | st_case_33: 991 | //line machine.go:992 992 | switch data[p] { 993 | case 43: 994 | goto st4 995 | case 47: 996 | goto st5 997 | case 95: 998 | goto st4 999 | } 1000 | switch { 1001 | case data[p] < 65: 1002 | if 45 <= data[p] && data[p] <= 57 { 1003 | goto st4 1004 | } 1005 | case data[p] > 90: 1006 | if 97 <= data[p] && data[p] <= 122 { 1007 | goto st4 1008 | } 1009 | default: 1010 | goto st4 1011 | } 1012 | goto tr5 1013 | st4: 1014 | if p++; p == pe { 1015 | goto _test_eof4 1016 | } 1017 | st_case_4: 1018 | switch data[p] { 1019 | case 43: 1020 | goto st4 1021 | case 47: 1022 | goto st5 1023 | case 95: 1024 | goto st4 1025 | } 1026 | switch { 1027 | case data[p] < 65: 1028 | if 45 <= data[p] && data[p] <= 57 { 1029 | goto st4 1030 | } 1031 | case data[p] > 90: 1032 | if 97 <= data[p] && data[p] <= 122 { 1033 | goto st4 1034 | } 1035 | default: 1036 | goto st4 1037 | } 1038 | goto tr5 1039 | st5: 1040 | if p++; p == pe { 1041 | goto _test_eof5 1042 | } 1043 | st_case_5: 1044 | switch data[p] { 1045 | case 43: 1046 | goto st34 1047 | case 95: 1048 | goto st34 1049 | } 1050 | switch { 1051 | case data[p] < 48: 1052 | if 45 <= data[p] && data[p] <= 46 { 1053 | goto st34 1054 | } 1055 | case data[p] > 57: 1056 | switch { 1057 | case data[p] > 90: 1058 | if 97 <= data[p] && data[p] <= 122 { 1059 | goto st34 1060 | } 1061 | case data[p] >= 65: 1062 | goto st34 1063 | } 1064 | default: 1065 | goto st34 1066 | } 1067 | goto tr5 1068 | st34: 1069 | if p++; p == pe { 1070 | goto _test_eof34 1071 | } 1072 | st_case_34: 1073 | switch data[p] { 1074 | case 43: 1075 | goto st34 1076 | case 47: 1077 | goto st35 1078 | case 95: 1079 | goto st34 1080 | } 1081 | switch { 1082 | case data[p] < 65: 1083 | if 45 <= data[p] && data[p] <= 57 { 1084 | goto st34 1085 | } 1086 | case data[p] > 90: 1087 | if 97 <= data[p] && data[p] <= 122 { 1088 | goto st34 1089 | } 1090 | default: 1091 | goto st34 1092 | } 1093 | goto tr77 1094 | st35: 1095 | if p++; p == pe { 1096 | goto _test_eof35 1097 | } 1098 | st_case_35: 1099 | switch data[p] { 1100 | case 43: 1101 | goto st34 1102 | case 95: 1103 | goto st34 1104 | } 1105 | switch { 1106 | case data[p] < 48: 1107 | if 45 <= data[p] && data[p] <= 46 { 1108 | goto st34 1109 | } 1110 | case data[p] > 57: 1111 | switch { 1112 | case data[p] > 90: 1113 | if 97 <= data[p] && data[p] <= 122 { 1114 | goto st34 1115 | } 1116 | case data[p] >= 65: 1117 | goto st34 1118 | } 1119 | default: 1120 | goto st34 1121 | } 1122 | goto tr77 1123 | tr43: 1124 | //line NONE:1 1125 | te = p+1 1126 | 1127 | //line machine.rl:95 1128 | act = 48; 1129 | goto st36 1130 | st36: 1131 | if p++; p == pe { 1132 | goto _test_eof36 1133 | } 1134 | st_case_36: 1135 | //line machine.go:1136 1136 | switch data[p] { 1137 | case 43: 1138 | goto st4 1139 | case 47: 1140 | goto st5 1141 | case 62: 1142 | goto tr79 1143 | case 95: 1144 | goto st4 1145 | } 1146 | switch { 1147 | case data[p] < 65: 1148 | if 45 <= data[p] && data[p] <= 57 { 1149 | goto st4 1150 | } 1151 | case data[p] > 90: 1152 | if 97 <= data[p] && data[p] <= 122 { 1153 | goto st4 1154 | } 1155 | default: 1156 | goto st4 1157 | } 1158 | goto tr66 1159 | tr44: 1160 | //line NONE:1 1161 | te = p+1 1162 | 1163 | //line machine.rl:95 1164 | act = 48; 1165 | goto st37 1166 | st37: 1167 | if p++; p == pe { 1168 | goto _test_eof37 1169 | } 1170 | st_case_37: 1171 | //line machine.go:1172 1172 | switch data[p] { 1173 | case 43: 1174 | goto st4 1175 | case 45: 1176 | goto st4 1177 | case 46: 1178 | goto st6 1179 | case 47: 1180 | goto st5 1181 | case 95: 1182 | goto st4 1183 | } 1184 | switch { 1185 | case data[p] < 65: 1186 | if 48 <= data[p] && data[p] <= 57 { 1187 | goto tr81 1188 | } 1189 | case data[p] > 90: 1190 | if 97 <= data[p] && data[p] <= 122 { 1191 | goto st4 1192 | } 1193 | default: 1194 | goto st4 1195 | } 1196 | goto tr66 1197 | st6: 1198 | if p++; p == pe { 1199 | goto _test_eof6 1200 | } 1201 | st_case_6: 1202 | switch data[p] { 1203 | case 43: 1204 | goto st4 1205 | case 46: 1206 | goto tr9 1207 | case 47: 1208 | goto st5 1209 | case 95: 1210 | goto st4 1211 | } 1212 | switch { 1213 | case data[p] < 65: 1214 | if 45 <= data[p] && data[p] <= 57 { 1215 | goto st4 1216 | } 1217 | case data[p] > 90: 1218 | if 97 <= data[p] && data[p] <= 122 { 1219 | goto st4 1220 | } 1221 | default: 1222 | goto st4 1223 | } 1224 | goto tr0 1225 | tr81: 1226 | //line NONE:1 1227 | te = p+1 1228 | 1229 | //line machine.rl:69 1230 | act = 27; 1231 | goto st38 1232 | st38: 1233 | if p++; p == pe { 1234 | goto _test_eof38 1235 | } 1236 | st_case_38: 1237 | //line machine.go:1238 1238 | switch data[p] { 1239 | case 43: 1240 | goto st4 1241 | case 47: 1242 | goto st5 1243 | case 69: 1244 | goto st7 1245 | case 95: 1246 | goto st4 1247 | case 101: 1248 | goto st7 1249 | } 1250 | switch { 1251 | case data[p] < 48: 1252 | if 45 <= data[p] && data[p] <= 46 { 1253 | goto st4 1254 | } 1255 | case data[p] > 57: 1256 | switch { 1257 | case data[p] > 90: 1258 | if 97 <= data[p] && data[p] <= 122 { 1259 | goto st4 1260 | } 1261 | case data[p] >= 65: 1262 | goto st4 1263 | } 1264 | default: 1265 | goto tr81 1266 | } 1267 | goto tr68 1268 | st7: 1269 | if p++; p == pe { 1270 | goto _test_eof7 1271 | } 1272 | st_case_7: 1273 | switch data[p] { 1274 | case 43: 1275 | goto st8 1276 | case 45: 1277 | goto st8 1278 | case 46: 1279 | goto st4 1280 | case 47: 1281 | goto st5 1282 | case 95: 1283 | goto st4 1284 | } 1285 | switch { 1286 | case data[p] < 65: 1287 | if 48 <= data[p] && data[p] <= 57 { 1288 | goto tr11 1289 | } 1290 | case data[p] > 90: 1291 | if 97 <= data[p] && data[p] <= 122 { 1292 | goto st4 1293 | } 1294 | default: 1295 | goto st4 1296 | } 1297 | goto tr2 1298 | st8: 1299 | if p++; p == pe { 1300 | goto _test_eof8 1301 | } 1302 | st_case_8: 1303 | switch data[p] { 1304 | case 43: 1305 | goto st4 1306 | case 47: 1307 | goto st5 1308 | case 95: 1309 | goto st4 1310 | } 1311 | switch { 1312 | case data[p] < 48: 1313 | if 45 <= data[p] && data[p] <= 46 { 1314 | goto st4 1315 | } 1316 | case data[p] > 57: 1317 | switch { 1318 | case data[p] > 90: 1319 | if 97 <= data[p] && data[p] <= 122 { 1320 | goto st4 1321 | } 1322 | case data[p] >= 65: 1323 | goto st4 1324 | } 1325 | default: 1326 | goto tr11 1327 | } 1328 | goto tr2 1329 | tr11: 1330 | //line NONE:1 1331 | te = p+1 1332 | 1333 | //line machine.rl:69 1334 | act = 27; 1335 | goto st39 1336 | st39: 1337 | if p++; p == pe { 1338 | goto _test_eof39 1339 | } 1340 | st_case_39: 1341 | //line machine.go:1342 1342 | switch data[p] { 1343 | case 43: 1344 | goto st4 1345 | case 47: 1346 | goto st5 1347 | case 95: 1348 | goto st4 1349 | } 1350 | switch { 1351 | case data[p] < 48: 1352 | if 45 <= data[p] && data[p] <= 46 { 1353 | goto st4 1354 | } 1355 | case data[p] > 57: 1356 | switch { 1357 | case data[p] > 90: 1358 | if 97 <= data[p] && data[p] <= 122 { 1359 | goto st4 1360 | } 1361 | case data[p] >= 65: 1362 | goto st4 1363 | } 1364 | default: 1365 | goto tr11 1366 | } 1367 | goto tr68 1368 | tr45: 1369 | //line NONE:1 1370 | te = p+1 1371 | 1372 | goto st40 1373 | st40: 1374 | if p++; p == pe { 1375 | goto _test_eof40 1376 | } 1377 | st_case_40: 1378 | //line machine.go:1379 1379 | switch data[p] { 1380 | case 42: 1381 | goto st9 1382 | case 43: 1383 | goto st34 1384 | case 47: 1385 | goto tr83 1386 | case 95: 1387 | goto st34 1388 | } 1389 | switch { 1390 | case data[p] < 65: 1391 | if 45 <= data[p] && data[p] <= 57 { 1392 | goto st34 1393 | } 1394 | case data[p] > 90: 1395 | if 97 <= data[p] && data[p] <= 122 { 1396 | goto st34 1397 | } 1398 | default: 1399 | goto st34 1400 | } 1401 | goto tr66 1402 | st9: 1403 | if p++; p == pe { 1404 | goto _test_eof9 1405 | } 1406 | st_case_9: 1407 | if data[p] == 42 { 1408 | goto st10 1409 | } 1410 | goto st9 1411 | st10: 1412 | if p++; p == pe { 1413 | goto _test_eof10 1414 | } 1415 | st_case_10: 1416 | switch data[p] { 1417 | case 42: 1418 | goto st10 1419 | case 47: 1420 | goto tr14 1421 | } 1422 | goto st9 1423 | tr46: 1424 | //line NONE:1 1425 | te = p+1 1426 | 1427 | //line machine.rl:70 1428 | act = 28; 1429 | goto st41 1430 | st41: 1431 | if p++; p == pe { 1432 | goto _test_eof41 1433 | } 1434 | st_case_41: 1435 | //line machine.go:1436 1436 | switch data[p] { 1437 | case 39: 1438 | goto st42 1439 | case 43: 1440 | goto st4 1441 | case 45: 1442 | goto tr54 1443 | case 46: 1444 | goto st4 1445 | case 47: 1446 | goto st5 1447 | case 95: 1448 | goto tr54 1449 | } 1450 | switch { 1451 | case data[p] < 65: 1452 | if 48 <= data[p] && data[p] <= 57 { 1453 | goto tr46 1454 | } 1455 | case data[p] > 90: 1456 | if 97 <= data[p] && data[p] <= 122 { 1457 | goto tr54 1458 | } 1459 | default: 1460 | goto tr54 1461 | } 1462 | goto tr84 1463 | st42: 1464 | if p++; p == pe { 1465 | goto _test_eof42 1466 | } 1467 | st_case_42: 1468 | switch data[p] { 1469 | case 39: 1470 | goto st42 1471 | case 45: 1472 | goto st42 1473 | case 95: 1474 | goto st42 1475 | } 1476 | switch { 1477 | case data[p] < 65: 1478 | if 48 <= data[p] && data[p] <= 57 { 1479 | goto st42 1480 | } 1481 | case data[p] > 90: 1482 | if 97 <= data[p] && data[p] <= 122 { 1483 | goto st42 1484 | } 1485 | default: 1486 | goto st42 1487 | } 1488 | goto tr86 1489 | tr54: 1490 | //line NONE:1 1491 | te = p+1 1492 | 1493 | //line machine.rl:71 1494 | act = 29; 1495 | goto st43 1496 | st43: 1497 | if p++; p == pe { 1498 | goto _test_eof43 1499 | } 1500 | st_case_43: 1501 | //line machine.go:1502 1502 | switch data[p] { 1503 | case 39: 1504 | goto st42 1505 | case 43: 1506 | goto st4 1507 | case 46: 1508 | goto st4 1509 | case 47: 1510 | goto st5 1511 | case 95: 1512 | goto tr54 1513 | } 1514 | switch { 1515 | case data[p] < 65: 1516 | if 45 <= data[p] && data[p] <= 57 { 1517 | goto tr54 1518 | } 1519 | case data[p] > 90: 1520 | if 97 <= data[p] && data[p] <= 122 { 1521 | goto tr54 1522 | } 1523 | default: 1524 | goto tr54 1525 | } 1526 | goto tr86 1527 | tr47: 1528 | //line NONE:1 1529 | te = p+1 1530 | 1531 | //line machine.rl:70 1532 | act = 28; 1533 | goto st44 1534 | st44: 1535 | if p++; p == pe { 1536 | goto _test_eof44 1537 | } 1538 | st_case_44: 1539 | //line machine.go:1540 1540 | switch data[p] { 1541 | case 39: 1542 | goto st42 1543 | case 43: 1544 | goto st4 1545 | case 45: 1546 | goto tr54 1547 | case 46: 1548 | goto tr81 1549 | case 47: 1550 | goto st5 1551 | case 95: 1552 | goto tr54 1553 | } 1554 | switch { 1555 | case data[p] < 65: 1556 | if 48 <= data[p] && data[p] <= 57 { 1557 | goto tr47 1558 | } 1559 | case data[p] > 90: 1560 | if 97 <= data[p] && data[p] <= 122 { 1561 | goto tr54 1562 | } 1563 | default: 1564 | goto tr54 1565 | } 1566 | goto tr84 1567 | tr49: 1568 | //line NONE:1 1569 | te = p+1 1570 | 1571 | goto st45 1572 | st45: 1573 | if p++; p == pe { 1574 | goto _test_eof45 1575 | } 1576 | st_case_45: 1577 | //line machine.go:1578 1578 | switch data[p] { 1579 | case 43: 1580 | goto st11 1581 | case 61: 1582 | goto tr87 1583 | case 95: 1584 | goto st11 1585 | } 1586 | switch { 1587 | case data[p] < 48: 1588 | if 45 <= data[p] && data[p] <= 46 { 1589 | goto st11 1590 | } 1591 | case data[p] > 57: 1592 | switch { 1593 | case data[p] > 90: 1594 | if 97 <= data[p] && data[p] <= 122 { 1595 | goto st11 1596 | } 1597 | case data[p] >= 65: 1598 | goto st11 1599 | } 1600 | default: 1601 | goto st11 1602 | } 1603 | goto tr66 1604 | st11: 1605 | if p++; p == pe { 1606 | goto _test_eof11 1607 | } 1608 | st_case_11: 1609 | switch data[p] { 1610 | case 43: 1611 | goto st11 1612 | case 47: 1613 | goto st12 1614 | case 62: 1615 | goto tr17 1616 | case 95: 1617 | goto st11 1618 | } 1619 | switch { 1620 | case data[p] < 65: 1621 | if 45 <= data[p] && data[p] <= 57 { 1622 | goto st11 1623 | } 1624 | case data[p] > 90: 1625 | if 97 <= data[p] && data[p] <= 122 { 1626 | goto st11 1627 | } 1628 | default: 1629 | goto st11 1630 | } 1631 | goto tr0 1632 | st12: 1633 | if p++; p == pe { 1634 | goto _test_eof12 1635 | } 1636 | st_case_12: 1637 | switch data[p] { 1638 | case 43: 1639 | goto st11 1640 | case 95: 1641 | goto st11 1642 | } 1643 | switch { 1644 | case data[p] < 48: 1645 | if 45 <= data[p] && data[p] <= 46 { 1646 | goto st11 1647 | } 1648 | case data[p] > 57: 1649 | switch { 1650 | case data[p] > 90: 1651 | if 97 <= data[p] && data[p] <= 122 { 1652 | goto st11 1653 | } 1654 | case data[p] >= 65: 1655 | goto st11 1656 | } 1657 | default: 1658 | goto st11 1659 | } 1660 | goto tr0 1661 | st46: 1662 | if p++; p == pe { 1663 | goto _test_eof46 1664 | } 1665 | st_case_46: 1666 | if data[p] == 61 { 1667 | goto tr88 1668 | } 1669 | goto tr66 1670 | st47: 1671 | if p++; p == pe { 1672 | goto _test_eof47 1673 | } 1674 | st_case_47: 1675 | if data[p] == 61 { 1676 | goto tr89 1677 | } 1678 | goto tr66 1679 | tr52: 1680 | //line NONE:1 1681 | te = p+1 1682 | 1683 | //line machine.rl:71 1684 | act = 29; 1685 | goto st48 1686 | tr95: 1687 | //line NONE:1 1688 | te = p+1 1689 | 1690 | //line machine.rl:50 1691 | act = 9; 1692 | goto st48 1693 | tr98: 1694 | //line NONE:1 1695 | te = p+1 1696 | 1697 | //line machine.rl:51 1698 | act = 10; 1699 | goto st48 1700 | tr99: 1701 | //line NONE:1 1702 | te = p+1 1703 | 1704 | //line machine.rl:52 1705 | act = 11; 1706 | goto st48 1707 | tr106: 1708 | //line NONE:1 1709 | te = p+1 1710 | 1711 | //line machine.rl:54 1712 | act = 13; 1713 | goto st48 1714 | tr108: 1715 | //line NONE:1 1716 | te = p+1 1717 | 1718 | //line machine.rl:55 1719 | act = 14; 1720 | goto st48 1721 | tr109: 1722 | //line NONE:1 1723 | te = p+1 1724 | 1725 | //line machine.rl:56 1726 | act = 15; 1727 | goto st48 1728 | tr111: 1729 | //line NONE:1 1730 | te = p+1 1731 | 1732 | //line machine.rl:57 1733 | act = 16; 1734 | goto st48 1735 | tr114: 1736 | //line NONE:1 1737 | te = p+1 1738 | 1739 | //line machine.rl:58 1740 | act = 17; 1741 | goto st48 1742 | tr117: 1743 | //line NONE:1 1744 | te = p+1 1745 | 1746 | //line machine.rl:59 1747 | act = 18; 1748 | goto st48 1749 | st48: 1750 | if p++; p == pe { 1751 | goto _test_eof48 1752 | } 1753 | st_case_48: 1754 | //line machine.go:1755 1755 | switch data[p] { 1756 | case 39: 1757 | goto st42 1758 | case 43: 1759 | goto st13 1760 | case 46: 1761 | goto st13 1762 | case 47: 1763 | goto st5 1764 | case 58: 1765 | goto st14 1766 | case 95: 1767 | goto tr54 1768 | } 1769 | switch { 1770 | case data[p] < 65: 1771 | if 45 <= data[p] && data[p] <= 57 { 1772 | goto tr52 1773 | } 1774 | case data[p] > 90: 1775 | if 97 <= data[p] && data[p] <= 122 { 1776 | goto tr52 1777 | } 1778 | default: 1779 | goto tr52 1780 | } 1781 | goto tr5 1782 | st13: 1783 | if p++; p == pe { 1784 | goto _test_eof13 1785 | } 1786 | st_case_13: 1787 | switch data[p] { 1788 | case 43: 1789 | goto st13 1790 | case 47: 1791 | goto st5 1792 | case 58: 1793 | goto st14 1794 | case 95: 1795 | goto st4 1796 | } 1797 | switch { 1798 | case data[p] < 65: 1799 | if 45 <= data[p] && data[p] <= 57 { 1800 | goto st13 1801 | } 1802 | case data[p] > 90: 1803 | if 97 <= data[p] && data[p] <= 122 { 1804 | goto st13 1805 | } 1806 | default: 1807 | goto st13 1808 | } 1809 | goto tr5 1810 | st14: 1811 | if p++; p == pe { 1812 | goto _test_eof14 1813 | } 1814 | st_case_14: 1815 | switch data[p] { 1816 | case 33: 1817 | goto st49 1818 | case 61: 1819 | goto st49 1820 | case 95: 1821 | goto st49 1822 | case 126: 1823 | goto st49 1824 | } 1825 | switch { 1826 | case data[p] < 42: 1827 | if 36 <= data[p] && data[p] <= 39 { 1828 | goto st49 1829 | } 1830 | case data[p] > 58: 1831 | switch { 1832 | case data[p] > 90: 1833 | if 97 <= data[p] && data[p] <= 122 { 1834 | goto st49 1835 | } 1836 | case data[p] >= 63: 1837 | goto st49 1838 | } 1839 | default: 1840 | goto st49 1841 | } 1842 | goto tr5 1843 | st49: 1844 | if p++; p == pe { 1845 | goto _test_eof49 1846 | } 1847 | st_case_49: 1848 | switch data[p] { 1849 | case 33: 1850 | goto st49 1851 | case 61: 1852 | goto st49 1853 | case 95: 1854 | goto st49 1855 | case 126: 1856 | goto st49 1857 | } 1858 | switch { 1859 | case data[p] < 42: 1860 | if 36 <= data[p] && data[p] <= 39 { 1861 | goto st49 1862 | } 1863 | case data[p] > 58: 1864 | switch { 1865 | case data[p] > 90: 1866 | if 97 <= data[p] && data[p] <= 122 { 1867 | goto st49 1868 | } 1869 | case data[p] >= 63: 1870 | goto st49 1871 | } 1872 | default: 1873 | goto st49 1874 | } 1875 | goto tr90 1876 | tr55: 1877 | //line NONE:1 1878 | te = p+1 1879 | 1880 | //line machine.rl:71 1881 | act = 29; 1882 | goto st50 1883 | st50: 1884 | if p++; p == pe { 1885 | goto _test_eof50 1886 | } 1887 | st_case_50: 1888 | //line machine.go:1889 1889 | switch data[p] { 1890 | case 39: 1891 | goto st42 1892 | case 43: 1893 | goto st13 1894 | case 46: 1895 | goto st13 1896 | case 47: 1897 | goto st5 1898 | case 58: 1899 | goto st14 1900 | case 95: 1901 | goto tr54 1902 | case 115: 1903 | goto tr91 1904 | } 1905 | switch { 1906 | case data[p] < 65: 1907 | if 45 <= data[p] && data[p] <= 57 { 1908 | goto tr52 1909 | } 1910 | case data[p] > 90: 1911 | if 97 <= data[p] && data[p] <= 122 { 1912 | goto tr52 1913 | } 1914 | default: 1915 | goto tr52 1916 | } 1917 | goto tr86 1918 | tr91: 1919 | //line NONE:1 1920 | te = p+1 1921 | 1922 | //line machine.rl:71 1923 | act = 29; 1924 | goto st51 1925 | st51: 1926 | if p++; p == pe { 1927 | goto _test_eof51 1928 | } 1929 | st_case_51: 1930 | //line machine.go:1931 1931 | switch data[p] { 1932 | case 39: 1933 | goto st42 1934 | case 43: 1935 | goto st13 1936 | case 46: 1937 | goto st13 1938 | case 47: 1939 | goto st5 1940 | case 58: 1941 | goto st14 1942 | case 95: 1943 | goto tr54 1944 | case 115: 1945 | goto tr92 1946 | } 1947 | switch { 1948 | case data[p] < 65: 1949 | if 45 <= data[p] && data[p] <= 57 { 1950 | goto tr52 1951 | } 1952 | case data[p] > 90: 1953 | if 97 <= data[p] && data[p] <= 122 { 1954 | goto tr52 1955 | } 1956 | default: 1957 | goto tr52 1958 | } 1959 | goto tr86 1960 | tr92: 1961 | //line NONE:1 1962 | te = p+1 1963 | 1964 | //line machine.rl:71 1965 | act = 29; 1966 | goto st52 1967 | st52: 1968 | if p++; p == pe { 1969 | goto _test_eof52 1970 | } 1971 | st_case_52: 1972 | //line machine.go:1973 1973 | switch data[p] { 1974 | case 39: 1975 | goto st42 1976 | case 43: 1977 | goto st13 1978 | case 46: 1979 | goto st13 1980 | case 47: 1981 | goto st5 1982 | case 58: 1983 | goto st14 1984 | case 95: 1985 | goto tr54 1986 | case 101: 1987 | goto tr93 1988 | } 1989 | switch { 1990 | case data[p] < 65: 1991 | if 45 <= data[p] && data[p] <= 57 { 1992 | goto tr52 1993 | } 1994 | case data[p] > 90: 1995 | if 97 <= data[p] && data[p] <= 122 { 1996 | goto tr52 1997 | } 1998 | default: 1999 | goto tr52 2000 | } 2001 | goto tr86 2002 | tr93: 2003 | //line NONE:1 2004 | te = p+1 2005 | 2006 | //line machine.rl:71 2007 | act = 29; 2008 | goto st53 2009 | st53: 2010 | if p++; p == pe { 2011 | goto _test_eof53 2012 | } 2013 | st_case_53: 2014 | //line machine.go:2015 2015 | switch data[p] { 2016 | case 39: 2017 | goto st42 2018 | case 43: 2019 | goto st13 2020 | case 46: 2021 | goto st13 2022 | case 47: 2023 | goto st5 2024 | case 58: 2025 | goto st14 2026 | case 95: 2027 | goto tr54 2028 | case 114: 2029 | goto tr94 2030 | } 2031 | switch { 2032 | case data[p] < 65: 2033 | if 45 <= data[p] && data[p] <= 57 { 2034 | goto tr52 2035 | } 2036 | case data[p] > 90: 2037 | if 97 <= data[p] && data[p] <= 122 { 2038 | goto tr52 2039 | } 2040 | default: 2041 | goto tr52 2042 | } 2043 | goto tr86 2044 | tr94: 2045 | //line NONE:1 2046 | te = p+1 2047 | 2048 | //line machine.rl:71 2049 | act = 29; 2050 | goto st54 2051 | st54: 2052 | if p++; p == pe { 2053 | goto _test_eof54 2054 | } 2055 | st_case_54: 2056 | //line machine.go:2057 2057 | switch data[p] { 2058 | case 39: 2059 | goto st42 2060 | case 43: 2061 | goto st13 2062 | case 46: 2063 | goto st13 2064 | case 47: 2065 | goto st5 2066 | case 58: 2067 | goto st14 2068 | case 95: 2069 | goto tr54 2070 | case 116: 2071 | goto tr95 2072 | } 2073 | switch { 2074 | case data[p] < 65: 2075 | if 45 <= data[p] && data[p] <= 57 { 2076 | goto tr52 2077 | } 2078 | case data[p] > 90: 2079 | if 97 <= data[p] && data[p] <= 122 { 2080 | goto tr52 2081 | } 2082 | default: 2083 | goto tr52 2084 | } 2085 | goto tr86 2086 | tr56: 2087 | //line NONE:1 2088 | te = p+1 2089 | 2090 | //line machine.rl:71 2091 | act = 29; 2092 | goto st55 2093 | st55: 2094 | if p++; p == pe { 2095 | goto _test_eof55 2096 | } 2097 | st_case_55: 2098 | //line machine.go:2099 2099 | switch data[p] { 2100 | case 39: 2101 | goto st42 2102 | case 43: 2103 | goto st13 2104 | case 46: 2105 | goto st13 2106 | case 47: 2107 | goto st5 2108 | case 58: 2109 | goto st14 2110 | case 95: 2111 | goto tr54 2112 | case 108: 2113 | goto tr96 2114 | } 2115 | switch { 2116 | case data[p] < 65: 2117 | if 45 <= data[p] && data[p] <= 57 { 2118 | goto tr52 2119 | } 2120 | case data[p] > 90: 2121 | if 97 <= data[p] && data[p] <= 122 { 2122 | goto tr52 2123 | } 2124 | default: 2125 | goto tr52 2126 | } 2127 | goto tr86 2128 | tr96: 2129 | //line NONE:1 2130 | te = p+1 2131 | 2132 | //line machine.rl:71 2133 | act = 29; 2134 | goto st56 2135 | st56: 2136 | if p++; p == pe { 2137 | goto _test_eof56 2138 | } 2139 | st_case_56: 2140 | //line machine.go:2141 2141 | switch data[p] { 2142 | case 39: 2143 | goto st42 2144 | case 43: 2145 | goto st13 2146 | case 46: 2147 | goto st13 2148 | case 47: 2149 | goto st5 2150 | case 58: 2151 | goto st14 2152 | case 95: 2153 | goto tr54 2154 | case 115: 2155 | goto tr97 2156 | } 2157 | switch { 2158 | case data[p] < 65: 2159 | if 45 <= data[p] && data[p] <= 57 { 2160 | goto tr52 2161 | } 2162 | case data[p] > 90: 2163 | if 97 <= data[p] && data[p] <= 122 { 2164 | goto tr52 2165 | } 2166 | default: 2167 | goto tr52 2168 | } 2169 | goto tr86 2170 | tr97: 2171 | //line NONE:1 2172 | te = p+1 2173 | 2174 | //line machine.rl:71 2175 | act = 29; 2176 | goto st57 2177 | st57: 2178 | if p++; p == pe { 2179 | goto _test_eof57 2180 | } 2181 | st_case_57: 2182 | //line machine.go:2183 2183 | switch data[p] { 2184 | case 39: 2185 | goto st42 2186 | case 43: 2187 | goto st13 2188 | case 46: 2189 | goto st13 2190 | case 47: 2191 | goto st5 2192 | case 58: 2193 | goto st14 2194 | case 95: 2195 | goto tr54 2196 | case 101: 2197 | goto tr98 2198 | } 2199 | switch { 2200 | case data[p] < 65: 2201 | if 45 <= data[p] && data[p] <= 57 { 2202 | goto tr52 2203 | } 2204 | case data[p] > 90: 2205 | if 97 <= data[p] && data[p] <= 122 { 2206 | goto tr52 2207 | } 2208 | default: 2209 | goto tr52 2210 | } 2211 | goto tr86 2212 | tr57: 2213 | //line NONE:1 2214 | te = p+1 2215 | 2216 | //line machine.rl:71 2217 | act = 29; 2218 | goto st58 2219 | st58: 2220 | if p++; p == pe { 2221 | goto _test_eof58 2222 | } 2223 | st_case_58: 2224 | //line machine.go:2225 2225 | switch data[p] { 2226 | case 39: 2227 | goto st42 2228 | case 43: 2229 | goto st13 2230 | case 46: 2231 | goto st13 2232 | case 47: 2233 | goto st5 2234 | case 58: 2235 | goto st14 2236 | case 95: 2237 | goto tr54 2238 | case 102: 2239 | goto tr99 2240 | case 110: 2241 | goto tr100 2242 | } 2243 | switch { 2244 | case data[p] < 65: 2245 | if 45 <= data[p] && data[p] <= 57 { 2246 | goto tr52 2247 | } 2248 | case data[p] > 90: 2249 | if 97 <= data[p] && data[p] <= 122 { 2250 | goto tr52 2251 | } 2252 | default: 2253 | goto tr52 2254 | } 2255 | goto tr86 2256 | tr100: 2257 | //line NONE:1 2258 | te = p+1 2259 | 2260 | //line machine.rl:53 2261 | act = 12; 2262 | goto st59 2263 | st59: 2264 | if p++; p == pe { 2265 | goto _test_eof59 2266 | } 2267 | st_case_59: 2268 | //line machine.go:2269 2269 | switch data[p] { 2270 | case 39: 2271 | goto st42 2272 | case 43: 2273 | goto st13 2274 | case 46: 2275 | goto st13 2276 | case 47: 2277 | goto st5 2278 | case 58: 2279 | goto st14 2280 | case 95: 2281 | goto tr54 2282 | case 104: 2283 | goto tr102 2284 | } 2285 | switch { 2286 | case data[p] < 65: 2287 | if 45 <= data[p] && data[p] <= 57 { 2288 | goto tr52 2289 | } 2290 | case data[p] > 90: 2291 | if 97 <= data[p] && data[p] <= 122 { 2292 | goto tr52 2293 | } 2294 | default: 2295 | goto tr52 2296 | } 2297 | goto tr101 2298 | tr102: 2299 | //line NONE:1 2300 | te = p+1 2301 | 2302 | //line machine.rl:71 2303 | act = 29; 2304 | goto st60 2305 | st60: 2306 | if p++; p == pe { 2307 | goto _test_eof60 2308 | } 2309 | st_case_60: 2310 | //line machine.go:2311 2311 | switch data[p] { 2312 | case 39: 2313 | goto st42 2314 | case 43: 2315 | goto st13 2316 | case 46: 2317 | goto st13 2318 | case 47: 2319 | goto st5 2320 | case 58: 2321 | goto st14 2322 | case 95: 2323 | goto tr54 2324 | case 101: 2325 | goto tr103 2326 | } 2327 | switch { 2328 | case data[p] < 65: 2329 | if 45 <= data[p] && data[p] <= 57 { 2330 | goto tr52 2331 | } 2332 | case data[p] > 90: 2333 | if 97 <= data[p] && data[p] <= 122 { 2334 | goto tr52 2335 | } 2336 | default: 2337 | goto tr52 2338 | } 2339 | goto tr86 2340 | tr103: 2341 | //line NONE:1 2342 | te = p+1 2343 | 2344 | //line machine.rl:71 2345 | act = 29; 2346 | goto st61 2347 | st61: 2348 | if p++; p == pe { 2349 | goto _test_eof61 2350 | } 2351 | st_case_61: 2352 | //line machine.go:2353 2353 | switch data[p] { 2354 | case 39: 2355 | goto st42 2356 | case 43: 2357 | goto st13 2358 | case 46: 2359 | goto st13 2360 | case 47: 2361 | goto st5 2362 | case 58: 2363 | goto st14 2364 | case 95: 2365 | goto tr54 2366 | case 114: 2367 | goto tr104 2368 | } 2369 | switch { 2370 | case data[p] < 65: 2371 | if 45 <= data[p] && data[p] <= 57 { 2372 | goto tr52 2373 | } 2374 | case data[p] > 90: 2375 | if 97 <= data[p] && data[p] <= 122 { 2376 | goto tr52 2377 | } 2378 | default: 2379 | goto tr52 2380 | } 2381 | goto tr86 2382 | tr104: 2383 | //line NONE:1 2384 | te = p+1 2385 | 2386 | //line machine.rl:71 2387 | act = 29; 2388 | goto st62 2389 | st62: 2390 | if p++; p == pe { 2391 | goto _test_eof62 2392 | } 2393 | st_case_62: 2394 | //line machine.go:2395 2395 | switch data[p] { 2396 | case 39: 2397 | goto st42 2398 | case 43: 2399 | goto st13 2400 | case 46: 2401 | goto st13 2402 | case 47: 2403 | goto st5 2404 | case 58: 2405 | goto st14 2406 | case 95: 2407 | goto tr54 2408 | case 105: 2409 | goto tr105 2410 | } 2411 | switch { 2412 | case data[p] < 65: 2413 | if 45 <= data[p] && data[p] <= 57 { 2414 | goto tr52 2415 | } 2416 | case data[p] > 90: 2417 | if 97 <= data[p] && data[p] <= 122 { 2418 | goto tr52 2419 | } 2420 | default: 2421 | goto tr52 2422 | } 2423 | goto tr86 2424 | tr105: 2425 | //line NONE:1 2426 | te = p+1 2427 | 2428 | //line machine.rl:71 2429 | act = 29; 2430 | goto st63 2431 | st63: 2432 | if p++; p == pe { 2433 | goto _test_eof63 2434 | } 2435 | st_case_63: 2436 | //line machine.go:2437 2437 | switch data[p] { 2438 | case 39: 2439 | goto st42 2440 | case 43: 2441 | goto st13 2442 | case 46: 2443 | goto st13 2444 | case 47: 2445 | goto st5 2446 | case 58: 2447 | goto st14 2448 | case 95: 2449 | goto tr54 2450 | case 116: 2451 | goto tr106 2452 | } 2453 | switch { 2454 | case data[p] < 65: 2455 | if 45 <= data[p] && data[p] <= 57 { 2456 | goto tr52 2457 | } 2458 | case data[p] > 90: 2459 | if 97 <= data[p] && data[p] <= 122 { 2460 | goto tr52 2461 | } 2462 | default: 2463 | goto tr52 2464 | } 2465 | goto tr86 2466 | tr58: 2467 | //line NONE:1 2468 | te = p+1 2469 | 2470 | //line machine.rl:71 2471 | act = 29; 2472 | goto st64 2473 | st64: 2474 | if p++; p == pe { 2475 | goto _test_eof64 2476 | } 2477 | st_case_64: 2478 | //line machine.go:2479 2479 | switch data[p] { 2480 | case 39: 2481 | goto st42 2482 | case 43: 2483 | goto st13 2484 | case 46: 2485 | goto st13 2486 | case 47: 2487 | goto st5 2488 | case 58: 2489 | goto st14 2490 | case 95: 2491 | goto tr54 2492 | case 101: 2493 | goto tr107 2494 | } 2495 | switch { 2496 | case data[p] < 65: 2497 | if 45 <= data[p] && data[p] <= 57 { 2498 | goto tr52 2499 | } 2500 | case data[p] > 90: 2501 | if 97 <= data[p] && data[p] <= 122 { 2502 | goto tr52 2503 | } 2504 | default: 2505 | goto tr52 2506 | } 2507 | goto tr86 2508 | tr107: 2509 | //line NONE:1 2510 | te = p+1 2511 | 2512 | //line machine.rl:71 2513 | act = 29; 2514 | goto st65 2515 | st65: 2516 | if p++; p == pe { 2517 | goto _test_eof65 2518 | } 2519 | st_case_65: 2520 | //line machine.go:2521 2521 | switch data[p] { 2522 | case 39: 2523 | goto st42 2524 | case 43: 2525 | goto st13 2526 | case 46: 2527 | goto st13 2528 | case 47: 2529 | goto st5 2530 | case 58: 2531 | goto st14 2532 | case 95: 2533 | goto tr54 2534 | case 116: 2535 | goto tr108 2536 | } 2537 | switch { 2538 | case data[p] < 65: 2539 | if 45 <= data[p] && data[p] <= 57 { 2540 | goto tr52 2541 | } 2542 | case data[p] > 90: 2543 | if 97 <= data[p] && data[p] <= 122 { 2544 | goto tr52 2545 | } 2546 | default: 2547 | goto tr52 2548 | } 2549 | goto tr86 2550 | tr59: 2551 | //line NONE:1 2552 | te = p+1 2553 | 2554 | //line machine.rl:71 2555 | act = 29; 2556 | goto st66 2557 | st66: 2558 | if p++; p == pe { 2559 | goto _test_eof66 2560 | } 2561 | st_case_66: 2562 | //line machine.go:2563 2563 | switch data[p] { 2564 | case 39: 2565 | goto st42 2566 | case 43: 2567 | goto st13 2568 | case 46: 2569 | goto st13 2570 | case 47: 2571 | goto st5 2572 | case 58: 2573 | goto st14 2574 | case 95: 2575 | goto tr54 2576 | case 114: 2577 | goto tr109 2578 | } 2579 | switch { 2580 | case data[p] < 65: 2581 | if 45 <= data[p] && data[p] <= 57 { 2582 | goto tr52 2583 | } 2584 | case data[p] > 90: 2585 | if 97 <= data[p] && data[p] <= 122 { 2586 | goto tr52 2587 | } 2588 | default: 2589 | goto tr52 2590 | } 2591 | goto tr86 2592 | tr60: 2593 | //line NONE:1 2594 | te = p+1 2595 | 2596 | //line machine.rl:71 2597 | act = 29; 2598 | goto st67 2599 | st67: 2600 | if p++; p == pe { 2601 | goto _test_eof67 2602 | } 2603 | st_case_67: 2604 | //line machine.go:2605 2605 | switch data[p] { 2606 | case 39: 2607 | goto st42 2608 | case 43: 2609 | goto st13 2610 | case 46: 2611 | goto st13 2612 | case 47: 2613 | goto st5 2614 | case 58: 2615 | goto st14 2616 | case 95: 2617 | goto tr54 2618 | case 101: 2619 | goto tr110 2620 | } 2621 | switch { 2622 | case data[p] < 65: 2623 | if 45 <= data[p] && data[p] <= 57 { 2624 | goto tr52 2625 | } 2626 | case data[p] > 90: 2627 | if 97 <= data[p] && data[p] <= 122 { 2628 | goto tr52 2629 | } 2630 | default: 2631 | goto tr52 2632 | } 2633 | goto tr86 2634 | tr110: 2635 | //line NONE:1 2636 | te = p+1 2637 | 2638 | //line machine.rl:71 2639 | act = 29; 2640 | goto st68 2641 | st68: 2642 | if p++; p == pe { 2643 | goto _test_eof68 2644 | } 2645 | st_case_68: 2646 | //line machine.go:2647 2647 | switch data[p] { 2648 | case 39: 2649 | goto st42 2650 | case 43: 2651 | goto st13 2652 | case 46: 2653 | goto st13 2654 | case 47: 2655 | goto st5 2656 | case 58: 2657 | goto st14 2658 | case 95: 2659 | goto tr54 2660 | case 99: 2661 | goto tr111 2662 | } 2663 | switch { 2664 | case data[p] < 65: 2665 | if 45 <= data[p] && data[p] <= 57 { 2666 | goto tr52 2667 | } 2668 | case data[p] > 90: 2669 | if 97 <= data[p] && data[p] <= 122 { 2670 | goto tr52 2671 | } 2672 | default: 2673 | goto tr52 2674 | } 2675 | goto tr86 2676 | tr61: 2677 | //line NONE:1 2678 | te = p+1 2679 | 2680 | //line machine.rl:71 2681 | act = 29; 2682 | goto st69 2683 | st69: 2684 | if p++; p == pe { 2685 | goto _test_eof69 2686 | } 2687 | st_case_69: 2688 | //line machine.go:2689 2689 | switch data[p] { 2690 | case 39: 2691 | goto st42 2692 | case 43: 2693 | goto st13 2694 | case 46: 2695 | goto st13 2696 | case 47: 2697 | goto st5 2698 | case 58: 2699 | goto st14 2700 | case 95: 2701 | goto tr54 2702 | case 104: 2703 | goto tr112 2704 | } 2705 | switch { 2706 | case data[p] < 65: 2707 | if 45 <= data[p] && data[p] <= 57 { 2708 | goto tr52 2709 | } 2710 | case data[p] > 90: 2711 | if 97 <= data[p] && data[p] <= 122 { 2712 | goto tr52 2713 | } 2714 | default: 2715 | goto tr52 2716 | } 2717 | goto tr86 2718 | tr112: 2719 | //line NONE:1 2720 | te = p+1 2721 | 2722 | //line machine.rl:71 2723 | act = 29; 2724 | goto st70 2725 | st70: 2726 | if p++; p == pe { 2727 | goto _test_eof70 2728 | } 2729 | st_case_70: 2730 | //line machine.go:2731 2731 | switch data[p] { 2732 | case 39: 2733 | goto st42 2734 | case 43: 2735 | goto st13 2736 | case 46: 2737 | goto st13 2738 | case 47: 2739 | goto st5 2740 | case 58: 2741 | goto st14 2742 | case 95: 2743 | goto tr54 2744 | case 101: 2745 | goto tr113 2746 | } 2747 | switch { 2748 | case data[p] < 65: 2749 | if 45 <= data[p] && data[p] <= 57 { 2750 | goto tr52 2751 | } 2752 | case data[p] > 90: 2753 | if 97 <= data[p] && data[p] <= 122 { 2754 | goto tr52 2755 | } 2756 | default: 2757 | goto tr52 2758 | } 2759 | goto tr86 2760 | tr113: 2761 | //line NONE:1 2762 | te = p+1 2763 | 2764 | //line machine.rl:71 2765 | act = 29; 2766 | goto st71 2767 | st71: 2768 | if p++; p == pe { 2769 | goto _test_eof71 2770 | } 2771 | st_case_71: 2772 | //line machine.go:2773 2773 | switch data[p] { 2774 | case 39: 2775 | goto st42 2776 | case 43: 2777 | goto st13 2778 | case 46: 2779 | goto st13 2780 | case 47: 2781 | goto st5 2782 | case 58: 2783 | goto st14 2784 | case 95: 2785 | goto tr54 2786 | case 110: 2787 | goto tr114 2788 | } 2789 | switch { 2790 | case data[p] < 65: 2791 | if 45 <= data[p] && data[p] <= 57 { 2792 | goto tr52 2793 | } 2794 | case data[p] > 90: 2795 | if 97 <= data[p] && data[p] <= 122 { 2796 | goto tr52 2797 | } 2798 | default: 2799 | goto tr52 2800 | } 2801 | goto tr86 2802 | tr62: 2803 | //line NONE:1 2804 | te = p+1 2805 | 2806 | //line machine.rl:71 2807 | act = 29; 2808 | goto st72 2809 | st72: 2810 | if p++; p == pe { 2811 | goto _test_eof72 2812 | } 2813 | st_case_72: 2814 | //line machine.go:2815 2815 | switch data[p] { 2816 | case 39: 2817 | goto st42 2818 | case 43: 2819 | goto st13 2820 | case 46: 2821 | goto st13 2822 | case 47: 2823 | goto st5 2824 | case 58: 2825 | goto st14 2826 | case 95: 2827 | goto tr54 2828 | case 105: 2829 | goto tr115 2830 | } 2831 | switch { 2832 | case data[p] < 65: 2833 | if 45 <= data[p] && data[p] <= 57 { 2834 | goto tr52 2835 | } 2836 | case data[p] > 90: 2837 | if 97 <= data[p] && data[p] <= 122 { 2838 | goto tr52 2839 | } 2840 | default: 2841 | goto tr52 2842 | } 2843 | goto tr86 2844 | tr115: 2845 | //line NONE:1 2846 | te = p+1 2847 | 2848 | //line machine.rl:71 2849 | act = 29; 2850 | goto st73 2851 | st73: 2852 | if p++; p == pe { 2853 | goto _test_eof73 2854 | } 2855 | st_case_73: 2856 | //line machine.go:2857 2857 | switch data[p] { 2858 | case 39: 2859 | goto st42 2860 | case 43: 2861 | goto st13 2862 | case 46: 2863 | goto st13 2864 | case 47: 2865 | goto st5 2866 | case 58: 2867 | goto st14 2868 | case 95: 2869 | goto tr54 2870 | case 116: 2871 | goto tr116 2872 | } 2873 | switch { 2874 | case data[p] < 65: 2875 | if 45 <= data[p] && data[p] <= 57 { 2876 | goto tr52 2877 | } 2878 | case data[p] > 90: 2879 | if 97 <= data[p] && data[p] <= 122 { 2880 | goto tr52 2881 | } 2882 | default: 2883 | goto tr52 2884 | } 2885 | goto tr86 2886 | tr116: 2887 | //line NONE:1 2888 | te = p+1 2889 | 2890 | //line machine.rl:71 2891 | act = 29; 2892 | goto st74 2893 | st74: 2894 | if p++; p == pe { 2895 | goto _test_eof74 2896 | } 2897 | st_case_74: 2898 | //line machine.go:2899 2899 | switch data[p] { 2900 | case 39: 2901 | goto st42 2902 | case 43: 2903 | goto st13 2904 | case 46: 2905 | goto st13 2906 | case 47: 2907 | goto st5 2908 | case 58: 2909 | goto st14 2910 | case 95: 2911 | goto tr54 2912 | case 104: 2913 | goto tr117 2914 | } 2915 | switch { 2916 | case data[p] < 65: 2917 | if 45 <= data[p] && data[p] <= 57 { 2918 | goto tr52 2919 | } 2920 | case data[p] > 90: 2921 | if 97 <= data[p] && data[p] <= 122 { 2922 | goto tr52 2923 | } 2924 | default: 2925 | goto tr52 2926 | } 2927 | goto tr86 2928 | st75: 2929 | if p++; p == pe { 2930 | goto _test_eof75 2931 | } 2932 | st_case_75: 2933 | if data[p] == 124 { 2934 | goto tr118 2935 | } 2936 | goto tr66 2937 | tr65: 2938 | //line NONE:1 2939 | te = p+1 2940 | 2941 | goto st76 2942 | st76: 2943 | if p++; p == pe { 2944 | goto _test_eof76 2945 | } 2946 | st_case_76: 2947 | //line machine.go:2948 2948 | if data[p] == 47 { 2949 | goto st15 2950 | } 2951 | goto tr66 2952 | st15: 2953 | if p++; p == pe { 2954 | goto _test_eof15 2955 | } 2956 | st_case_15: 2957 | switch data[p] { 2958 | case 43: 2959 | goto st77 2960 | case 95: 2961 | goto st77 2962 | } 2963 | switch { 2964 | case data[p] < 48: 2965 | if 45 <= data[p] && data[p] <= 46 { 2966 | goto st77 2967 | } 2968 | case data[p] > 57: 2969 | switch { 2970 | case data[p] > 90: 2971 | if 97 <= data[p] && data[p] <= 122 { 2972 | goto st77 2973 | } 2974 | case data[p] >= 65: 2975 | goto st77 2976 | } 2977 | default: 2978 | goto st77 2979 | } 2980 | goto tr0 2981 | st77: 2982 | if p++; p == pe { 2983 | goto _test_eof77 2984 | } 2985 | st_case_77: 2986 | switch data[p] { 2987 | case 43: 2988 | goto st77 2989 | case 47: 2990 | goto st78 2991 | case 95: 2992 | goto st77 2993 | } 2994 | switch { 2995 | case data[p] < 65: 2996 | if 45 <= data[p] && data[p] <= 57 { 2997 | goto st77 2998 | } 2999 | case data[p] > 90: 3000 | if 97 <= data[p] && data[p] <= 122 { 3001 | goto st77 3002 | } 3003 | default: 3004 | goto st77 3005 | } 3006 | goto tr120 3007 | st78: 3008 | if p++; p == pe { 3009 | goto _test_eof78 3010 | } 3011 | st_case_78: 3012 | switch data[p] { 3013 | case 43: 3014 | goto st77 3015 | case 95: 3016 | goto st77 3017 | } 3018 | switch { 3019 | case data[p] < 48: 3020 | if 45 <= data[p] && data[p] <= 46 { 3021 | goto st77 3022 | } 3023 | case data[p] > 57: 3024 | switch { 3025 | case data[p] > 90: 3026 | if 97 <= data[p] && data[p] <= 122 { 3027 | goto st77 3028 | } 3029 | case data[p] >= 65: 3030 | goto st77 3031 | } 3032 | default: 3033 | goto st77 3034 | } 3035 | goto tr120 3036 | tr22: 3037 | //line machine.rl:32 3038 | p = (te) - 1 3039 | { tok(text); addLines() } 3040 | goto st79 3041 | tr24: 3042 | //line NONE:1 3043 | switch act { 3044 | case 0: 3045 | {{goto st0 }} 3046 | case 3: 3047 | {p = (te) - 1 3048 | tok(text); addLines() } 3049 | } 3050 | 3051 | goto st79 3052 | tr122: 3053 | //line machine.rl:30 3054 | te = p+1 3055 | { if !tokleave('"') { return }; {top--; cs = stack[top];goto _again } } 3056 | goto st79 3057 | tr125: 3058 | //line machine.rl:32 3059 | te = p 3060 | p-- 3061 | { tok(text); addLines() } 3062 | goto st79 3063 | tr127: 3064 | //line machine.rl:33 3065 | te = p 3066 | p-- 3067 | { tok(text) } 3068 | goto st79 3069 | tr128: 3070 | //line machine.rl:31 3071 | te = p+1 3072 | { tokenter(interp, '}'); { if nostack() { return }; {stack[top] = 79; top++; goto st22 }} } 3073 | goto st79 3074 | st79: 3075 | //line NONE:1 3076 | ts = 0 3077 | 3078 | //line NONE:1 3079 | act = 0 3080 | 3081 | if p++; p == pe { 3082 | goto _test_eof79 3083 | } 3084 | st_case_79: 3085 | //line NONE:1 3086 | ts = p 3087 | 3088 | //line machine.go:3089 3089 | switch data[p] { 3090 | case 34: 3091 | goto tr122 3092 | case 36: 3093 | goto st81 3094 | case 92: 3095 | goto st17 3096 | } 3097 | goto tr23 3098 | tr23: 3099 | //line NONE:1 3100 | te = p+1 3101 | 3102 | //line machine.rl:32 3103 | act = 3; 3104 | goto st80 3105 | st80: 3106 | if p++; p == pe { 3107 | goto _test_eof80 3108 | } 3109 | st_case_80: 3110 | //line machine.go:3111 3111 | switch data[p] { 3112 | case 34: 3113 | goto tr125 3114 | case 36: 3115 | goto st16 3116 | case 92: 3117 | goto st17 3118 | } 3119 | goto tr23 3120 | st16: 3121 | if p++; p == pe { 3122 | goto _test_eof16 3123 | } 3124 | st_case_16: 3125 | switch data[p] { 3126 | case 34: 3127 | goto tr22 3128 | case 123: 3129 | goto tr22 3130 | } 3131 | goto tr23 3132 | st17: 3133 | if p++; p == pe { 3134 | goto _test_eof17 3135 | } 3136 | st_case_17: 3137 | goto tr23 3138 | st81: 3139 | if p++; p == pe { 3140 | goto _test_eof81 3141 | } 3142 | st_case_81: 3143 | switch data[p] { 3144 | case 34: 3145 | goto tr127 3146 | case 123: 3147 | goto tr128 3148 | } 3149 | goto tr23 3150 | tr25: 3151 | //line machine.rl:42 3152 | p = (te) - 1 3153 | { tok(text); addLines() } 3154 | goto st82 3155 | tr29: 3156 | //line NONE:1 3157 | switch act { 3158 | case 5: 3159 | {p = (te) - 1 3160 | if !tokleave(ii) { return }; {top--; cs = stack[top];goto _again } } 3161 | case 7: 3162 | {p = (te) - 1 3163 | tok(text); addLines() } 3164 | } 3165 | 3166 | goto st82 3167 | tr131: 3168 | //line machine.rl:42 3169 | te = p 3170 | p-- 3171 | { tok(text); addLines() } 3172 | goto st82 3173 | tr134: 3174 | //line machine.rl:43 3175 | te = p 3176 | p-- 3177 | { tok(text) } 3178 | goto st82 3179 | tr135: 3180 | //line machine.rl:41 3181 | te = p+1 3182 | { tokenter(interp, '}'); { if nostack() { return }; {stack[top] = 82; top++; goto st22 }} } 3183 | goto st82 3184 | tr137: 3185 | //line machine.rl:40 3186 | te = p 3187 | p-- 3188 | { if !tokleave(ii) { return }; {top--; cs = stack[top];goto _again } } 3189 | goto st82 3190 | st82: 3191 | //line NONE:1 3192 | ts = 0 3193 | 3194 | if p++; p == pe { 3195 | goto _test_eof82 3196 | } 3197 | st_case_82: 3198 | //line NONE:1 3199 | ts = p 3200 | 3201 | //line machine.go:3202 3202 | switch data[p] { 3203 | case 36: 3204 | goto st84 3205 | case 39: 3206 | goto st85 3207 | } 3208 | goto tr26 3209 | tr26: 3210 | //line NONE:1 3211 | te = p+1 3212 | 3213 | //line machine.rl:42 3214 | act = 7; 3215 | goto st83 3216 | st83: 3217 | if p++; p == pe { 3218 | goto _test_eof83 3219 | } 3220 | st_case_83: 3221 | //line machine.go:3222 3222 | switch data[p] { 3223 | case 36: 3224 | goto st18 3225 | case 39: 3226 | goto st19 3227 | } 3228 | goto tr26 3229 | st18: 3230 | if p++; p == pe { 3231 | goto _test_eof18 3232 | } 3233 | st_case_18: 3234 | switch data[p] { 3235 | case 39: 3236 | goto tr25 3237 | case 123: 3238 | goto tr25 3239 | } 3240 | goto tr26 3241 | st19: 3242 | if p++; p == pe { 3243 | goto _test_eof19 3244 | } 3245 | st_case_19: 3246 | switch data[p] { 3247 | case 36: 3248 | goto tr25 3249 | case 39: 3250 | goto st20 3251 | } 3252 | goto tr26 3253 | st20: 3254 | if p++; p == pe { 3255 | goto _test_eof20 3256 | } 3257 | st_case_20: 3258 | switch data[p] { 3259 | case 36: 3260 | goto tr26 3261 | case 39: 3262 | goto tr26 3263 | case 92: 3264 | goto st21 3265 | } 3266 | goto tr25 3267 | st21: 3268 | if p++; p == pe { 3269 | goto _test_eof21 3270 | } 3271 | st_case_21: 3272 | goto tr26 3273 | st84: 3274 | if p++; p == pe { 3275 | goto _test_eof84 3276 | } 3277 | st_case_84: 3278 | switch data[p] { 3279 | case 39: 3280 | goto tr134 3281 | case 123: 3282 | goto tr135 3283 | } 3284 | goto tr26 3285 | st85: 3286 | if p++; p == pe { 3287 | goto _test_eof85 3288 | } 3289 | st_case_85: 3290 | switch data[p] { 3291 | case 36: 3292 | goto tr134 3293 | case 39: 3294 | goto tr136 3295 | } 3296 | goto tr26 3297 | tr136: 3298 | //line NONE:1 3299 | te = p+1 3300 | 3301 | //line machine.rl:40 3302 | act = 5; 3303 | goto st86 3304 | st86: 3305 | if p++; p == pe { 3306 | goto _test_eof86 3307 | } 3308 | st_case_86: 3309 | //line machine.go:3310 3310 | switch data[p] { 3311 | case 36: 3312 | goto tr26 3313 | case 39: 3314 | goto tr26 3315 | case 92: 3316 | goto st21 3317 | } 3318 | goto tr137 3319 | st_case_0: 3320 | st0: 3321 | cs = 0 3322 | goto _out 3323 | st_out: 3324 | _test_eof22: cs = 22; goto _test_eof 3325 | _test_eof23: cs = 23; goto _test_eof 3326 | _test_eof1: cs = 1; goto _test_eof 3327 | _test_eof24: cs = 24; goto _test_eof 3328 | _test_eof2: cs = 2; goto _test_eof 3329 | _test_eof3: cs = 3; goto _test_eof 3330 | _test_eof25: cs = 25; goto _test_eof 3331 | _test_eof26: cs = 26; goto _test_eof 3332 | _test_eof27: cs = 27; goto _test_eof 3333 | _test_eof28: cs = 28; goto _test_eof 3334 | _test_eof29: cs = 29; goto _test_eof 3335 | _test_eof30: cs = 30; goto _test_eof 3336 | _test_eof31: cs = 31; goto _test_eof 3337 | _test_eof32: cs = 32; goto _test_eof 3338 | _test_eof33: cs = 33; goto _test_eof 3339 | _test_eof4: cs = 4; goto _test_eof 3340 | _test_eof5: cs = 5; goto _test_eof 3341 | _test_eof34: cs = 34; goto _test_eof 3342 | _test_eof35: cs = 35; goto _test_eof 3343 | _test_eof36: cs = 36; goto _test_eof 3344 | _test_eof37: cs = 37; goto _test_eof 3345 | _test_eof6: cs = 6; goto _test_eof 3346 | _test_eof38: cs = 38; goto _test_eof 3347 | _test_eof7: cs = 7; goto _test_eof 3348 | _test_eof8: cs = 8; goto _test_eof 3349 | _test_eof39: cs = 39; goto _test_eof 3350 | _test_eof40: cs = 40; goto _test_eof 3351 | _test_eof9: cs = 9; goto _test_eof 3352 | _test_eof10: cs = 10; goto _test_eof 3353 | _test_eof41: cs = 41; goto _test_eof 3354 | _test_eof42: cs = 42; goto _test_eof 3355 | _test_eof43: cs = 43; goto _test_eof 3356 | _test_eof44: cs = 44; goto _test_eof 3357 | _test_eof45: cs = 45; goto _test_eof 3358 | _test_eof11: cs = 11; goto _test_eof 3359 | _test_eof12: cs = 12; goto _test_eof 3360 | _test_eof46: cs = 46; goto _test_eof 3361 | _test_eof47: cs = 47; goto _test_eof 3362 | _test_eof48: cs = 48; goto _test_eof 3363 | _test_eof13: cs = 13; goto _test_eof 3364 | _test_eof14: cs = 14; goto _test_eof 3365 | _test_eof49: cs = 49; goto _test_eof 3366 | _test_eof50: cs = 50; goto _test_eof 3367 | _test_eof51: cs = 51; goto _test_eof 3368 | _test_eof52: cs = 52; goto _test_eof 3369 | _test_eof53: cs = 53; goto _test_eof 3370 | _test_eof54: cs = 54; goto _test_eof 3371 | _test_eof55: cs = 55; goto _test_eof 3372 | _test_eof56: cs = 56; goto _test_eof 3373 | _test_eof57: cs = 57; goto _test_eof 3374 | _test_eof58: cs = 58; goto _test_eof 3375 | _test_eof59: cs = 59; goto _test_eof 3376 | _test_eof60: cs = 60; goto _test_eof 3377 | _test_eof61: cs = 61; goto _test_eof 3378 | _test_eof62: cs = 62; goto _test_eof 3379 | _test_eof63: cs = 63; goto _test_eof 3380 | _test_eof64: cs = 64; goto _test_eof 3381 | _test_eof65: cs = 65; goto _test_eof 3382 | _test_eof66: cs = 66; goto _test_eof 3383 | _test_eof67: cs = 67; goto _test_eof 3384 | _test_eof68: cs = 68; goto _test_eof 3385 | _test_eof69: cs = 69; goto _test_eof 3386 | _test_eof70: cs = 70; goto _test_eof 3387 | _test_eof71: cs = 71; goto _test_eof 3388 | _test_eof72: cs = 72; goto _test_eof 3389 | _test_eof73: cs = 73; goto _test_eof 3390 | _test_eof74: cs = 74; goto _test_eof 3391 | _test_eof75: cs = 75; goto _test_eof 3392 | _test_eof76: cs = 76; goto _test_eof 3393 | _test_eof15: cs = 15; goto _test_eof 3394 | _test_eof77: cs = 77; goto _test_eof 3395 | _test_eof78: cs = 78; goto _test_eof 3396 | _test_eof79: cs = 79; goto _test_eof 3397 | _test_eof80: cs = 80; goto _test_eof 3398 | _test_eof16: cs = 16; goto _test_eof 3399 | _test_eof17: cs = 17; goto _test_eof 3400 | _test_eof81: cs = 81; goto _test_eof 3401 | _test_eof82: cs = 82; goto _test_eof 3402 | _test_eof83: cs = 83; goto _test_eof 3403 | _test_eof18: cs = 18; goto _test_eof 3404 | _test_eof19: cs = 19; goto _test_eof 3405 | _test_eof20: cs = 20; goto _test_eof 3406 | _test_eof21: cs = 21; goto _test_eof 3407 | _test_eof84: cs = 84; goto _test_eof 3408 | _test_eof85: cs = 85; goto _test_eof 3409 | _test_eof86: cs = 86; goto _test_eof 3410 | 3411 | _test_eof: {} 3412 | if p == eof { 3413 | switch cs { 3414 | case 23: 3415 | goto tr66 3416 | case 1: 3417 | goto tr0 3418 | case 24: 3419 | goto tr68 3420 | case 2: 3421 | goto tr2 3422 | case 3: 3423 | goto tr2 3424 | case 25: 3425 | goto tr68 3426 | case 26: 3427 | goto tr70 3428 | case 27: 3429 | goto tr66 3430 | case 28: 3431 | goto tr72 3432 | case 29: 3433 | goto tr66 3434 | case 30: 3435 | goto tr66 3436 | case 31: 3437 | goto tr66 3438 | case 32: 3439 | goto tr66 3440 | case 33: 3441 | goto tr5 3442 | case 4: 3443 | goto tr5 3444 | case 5: 3445 | goto tr5 3446 | case 34: 3447 | goto tr77 3448 | case 35: 3449 | goto tr77 3450 | case 36: 3451 | goto tr66 3452 | case 37: 3453 | goto tr66 3454 | case 6: 3455 | goto tr0 3456 | case 38: 3457 | goto tr68 3458 | case 7: 3459 | goto tr2 3460 | case 8: 3461 | goto tr2 3462 | case 39: 3463 | goto tr68 3464 | case 40: 3465 | goto tr66 3466 | case 9: 3467 | goto tr0 3468 | case 10: 3469 | goto tr0 3470 | case 41: 3471 | goto tr84 3472 | case 42: 3473 | goto tr86 3474 | case 43: 3475 | goto tr86 3476 | case 44: 3477 | goto tr84 3478 | case 45: 3479 | goto tr66 3480 | case 11: 3481 | goto tr0 3482 | case 12: 3483 | goto tr0 3484 | case 46: 3485 | goto tr66 3486 | case 47: 3487 | goto tr66 3488 | case 48: 3489 | goto tr5 3490 | case 13: 3491 | goto tr5 3492 | case 14: 3493 | goto tr5 3494 | case 49: 3495 | goto tr90 3496 | case 50: 3497 | goto tr86 3498 | case 51: 3499 | goto tr86 3500 | case 52: 3501 | goto tr86 3502 | case 53: 3503 | goto tr86 3504 | case 54: 3505 | goto tr86 3506 | case 55: 3507 | goto tr86 3508 | case 56: 3509 | goto tr86 3510 | case 57: 3511 | goto tr86 3512 | case 58: 3513 | goto tr86 3514 | case 59: 3515 | goto tr101 3516 | case 60: 3517 | goto tr86 3518 | case 61: 3519 | goto tr86 3520 | case 62: 3521 | goto tr86 3522 | case 63: 3523 | goto tr86 3524 | case 64: 3525 | goto tr86 3526 | case 65: 3527 | goto tr86 3528 | case 66: 3529 | goto tr86 3530 | case 67: 3531 | goto tr86 3532 | case 68: 3533 | goto tr86 3534 | case 69: 3535 | goto tr86 3536 | case 70: 3537 | goto tr86 3538 | case 71: 3539 | goto tr86 3540 | case 72: 3541 | goto tr86 3542 | case 73: 3543 | goto tr86 3544 | case 74: 3545 | goto tr86 3546 | case 75: 3547 | goto tr66 3548 | case 76: 3549 | goto tr66 3550 | case 15: 3551 | goto tr0 3552 | case 77: 3553 | goto tr120 3554 | case 78: 3555 | goto tr120 3556 | case 80: 3557 | goto tr125 3558 | case 16: 3559 | goto tr22 3560 | case 17: 3561 | goto tr24 3562 | case 81: 3563 | goto tr127 3564 | case 83: 3565 | goto tr131 3566 | case 18: 3567 | goto tr25 3568 | case 19: 3569 | goto tr25 3570 | case 20: 3571 | goto tr25 3572 | case 21: 3573 | goto tr29 3574 | case 84: 3575 | goto tr134 3576 | case 85: 3577 | goto tr134 3578 | case 86: 3579 | goto tr137 3580 | } 3581 | } 3582 | 3583 | _out: {} 3584 | } 3585 | 3586 | //line machine.rl:170 3587 | 3588 | if p != eof { 3589 | err = r.Errorf("precedes the token that failed to lex") 3590 | } else if len(backrefs) != 0 { 3591 | iprev, _ := backrefs.Pop() 3592 | prev := r.tokens[iprev] 3593 | err = fmt.Errorf("%s%s is not terminated", r.At(prev.pos), symString(prev.sym)) 3594 | } 3595 | return 3596 | } 3597 | -------------------------------------------------------------------------------- /nix/parser/machine.rl: -------------------------------------------------------------------------------- 1 | // compile-command: "ragel -Z -G2 machine.rl" 2 | 3 | package parser 4 | 5 | import "fmt" 6 | 7 | const maxstack = 64 8 | 9 | %%{ 10 | 11 | machine expr; 12 | 13 | 14 | prepush { if nostack() { return }; } 15 | 16 | Space = [ \t\r\n]+; 17 | Comment1 = "#" [^\r\n]*; 18 | Comment2 = "/*" any* :>> "*/"; 19 | URI = [a-zA-Z] [a-zA-Z0-9.+\-]* ":" [a-zA-Z0-9%/?:@&=+$,_.!~*'\-]+; 20 | Path = [a-zA-Z0-9._+\-]* ([/] [a-zA-Z0-9._+\-]+)+ [/]?; 21 | HPath = "~" ([/] [a-zA-Z0-9._+\-]+)+ [/]?; 22 | SPath = "<" [a-zA-Z0-9._+\-]+ ([/] [a-zA-Z0-9._+\-]+)* ">"; 23 | ID = [a-zA-Z0-9_] [a-zA-Z0-9_'\-]*; 24 | Float = (([1-9] [0-9]* [.] [0-9]*) | (0? [.] [0-9]+)) ([Ee] [+\-]? [0-9]+)?; 25 | Int = [0-9]+; 26 | 27 | 28 | qstring := |* 29 | 30 | ["] => { if !tokleave('"') { return }; fret; }; 31 | "${" => { tokenter(interp, '}'); fcall expr; }; 32 | ( [^$"\\] | /[$][^{"]/ | /\\./ )+ => { tok(text); addLines() }; 33 | "$" => { tok(text) }; 34 | 35 | *|; 36 | 37 | 38 | istring := |* 39 | 40 | "''" => { if !tokleave(ii) { return }; fret; }; 41 | "${" => { tokenter(interp, '}'); fcall expr; }; 42 | ( [^'$] | "'''" | "''$" | /''\\./ | /'[^'$]/ | /[$][^{']/ )+ => { tok(text); addLines() }; 43 | ['$] => { tok(text) }; 44 | 45 | *|; 46 | 47 | 48 | expr := |* 49 | 50 | "assert" => { tok(assert_) }; 51 | "else" => { tok(else_) }; 52 | "if" => { tok(if_) }; 53 | "in" => { tok(in) }; 54 | "inherit" => { tok(inherit) }; 55 | "let" => { tok(let) }; 56 | "or" => { tok(or_) }; 57 | "rec" => { tok(rec) }; 58 | "then" => { tok(then) }; 59 | "with" => { tok(with) }; 60 | 61 | [ \t\r]+; 62 | "\n" => { r.file.AddLine(ts) }; 63 | Comment1 => { tokcomment(comment) }; 64 | Comment2 => { tokcomment(comment); addLines() }; 65 | URI => { tok(uri) }; 66 | Path => { tok(path) }; 67 | HPath => { tok(path) }; 68 | SPath => { tok(path) }; 69 | Float => { tok(float) }; 70 | Int => { tok(int_) }; 71 | ID => { tok(id) }; 72 | 73 | "..." => { tok(ellipsis) }; 74 | "->" => { tok(impl) }; 75 | "||" => { tok(or) }; 76 | "&&" => { tok(and) }; 77 | "==" => { tok(eq) }; 78 | "!=" => { tok(neq) }; 79 | "<=" => { tok(leq) }; 80 | ">=" => { tok(geq) }; 81 | "//" => { tok(update) }; 82 | "++" => { tok(concat) }; 83 | 84 | ["] => { tokenter('"', '"'); fcall qstring; }; 85 | "''" => { tokenter(ii, ii); fcall istring; }; 86 | 87 | "${" => { tokenter(interp, '}'); fcall expr; }; 88 | "(" => { tokenter('(', ')'); fcall expr; }; 89 | "[" => { tokenter('[', ']'); fcall expr; }; 90 | "{" => { tokenter('{', '}'); fcall expr; }; 91 | [}\])] => { if !tokleave(int(data[ts])) { return }; fret; }; 92 | 93 | [@:] => { if !tokarg() { return }; }; 94 | 95 | any => { tok(int(data[ts])) }; 96 | 97 | *|; 98 | 99 | }%% 100 | 101 | %% write data; 102 | 103 | func lexData(data []byte, r *lexResult) (err error) { 104 | var cs, act, ts, te, top int 105 | var stack [maxstack]int 106 | p, pe := 0, len(data) 107 | eof := pe 108 | %% write init; 109 | _, _, _, _, _ = expr_first_final, expr_error, expr_en_qstring, expr_en_istring, expr_en_expr 110 | if r.file == nil { 111 | r.file = fileset.AddFile("(string)", -1, len(data)) 112 | } 113 | if r.data == nil { 114 | r.data = data 115 | } else { 116 | r.data = append(r.data, data...) 117 | } 118 | nostack := func() bool { 119 | if top != maxstack { 120 | return false 121 | } 122 | err = r.Errorf("exceeds recursion limit") 123 | return true 124 | } 125 | tok := func(sym int) { r.tokens = append(r.tokens, lexerToken{sym: sym, pos: ts, end: te}) } 126 | tokcomment := func(sym int) { r.comments = append(r.comments, lexerToken{sym: sym, pos: ts, end: te}) } 127 | var backrefs Backrefs 128 | tokenter := func(sym, fin int) { backrefs.Push(len(r.tokens), fin); tok(sym); } 129 | tokleave := func(sym int) bool { 130 | tok(sym) 131 | if top == 0 || len(backrefs) == 0 { 132 | err = r.Errorf("does not close anything") 133 | return false 134 | } 135 | iprev, prevsym := backrefs.Pop() 136 | if prevsym != sym { 137 | err = r.Errorf("does not close %v", r.tokens[iprev]) 138 | return false 139 | } 140 | r.tokens[len(r.tokens)-1].prev = iprev 141 | return true 142 | } 143 | tokarg := func() bool { 144 | tok(int(data[ts])) 145 | if len(r.tokens) == 1 { 146 | err = r.Errorf("does not follow anything") 147 | return false 148 | } 149 | prev := &r.tokens[len(r.tokens)-2] 150 | switch prev.sym { 151 | case id: 152 | prev.sym = argID 153 | case '}': 154 | r.tokens[prev.prev].sym = argBracket 155 | default: 156 | err = r.Errorf("does not follow an argument of a function") 157 | return false 158 | } 159 | return true 160 | } 161 | addLines := func() { 162 | for i := ts; i < te; i++ { 163 | if data[i] == '\n' { 164 | r.file.AddLine(i) 165 | } 166 | } 167 | } 168 | 169 | %% write exec; 170 | 171 | if p != eof { 172 | err = r.Errorf("precedes the token that failed to lex") 173 | } else if len(backrefs) != 0 { 174 | iprev, _ := backrefs.Pop() 175 | prev := r.tokens[iprev] 176 | err = fmt.Errorf("%s%s is not terminated", r.At(prev.pos), symString(prev.sym)) 177 | } 178 | return 179 | } 180 | -------------------------------------------------------------------------------- /nix/parser/nix.y: -------------------------------------------------------------------------------- 1 | %{ 2 | package parser 3 | %} 4 | 5 | %union { 6 | token int 7 | node *Node 8 | } 9 | 10 | %type 11 | Expression Interp String ID Atom Select Apply Op InterpID AttrPath List Binds InheritList Function ArgSet Arg 12 | 13 | %token 14 | assert_ if_ then else_ let in with or_ rec inherit ellipsis interp space comment ii 15 | uri path float int_ id text argID argBracket 16 | ':' '@' ',' ';' '"' '.' '(' ')' '[' ']' '{' '}' '=' 17 | 18 | %nonassoc impl 19 | %left or 20 | %left and 21 | %nonassoc eq neq 22 | %left '<' '>' leq geq 23 | %right update 24 | %nonassoc '!' 25 | %left '+' '-' 26 | %left '*' '/' 27 | %right concat 28 | %nonassoc '?' 29 | %nonassoc negate 30 | 31 | /* 32 | p := yylex.(*Parser) 33 | */ 34 | 35 | %% 36 | 37 | Main 38 | : Expression 39 | { p.Result = $1 } 40 | ; 41 | 42 | Expression 43 | : Op 44 | | assert_ Expression ';' Expression 45 | { $$ = p.NewNode(AssertNode, $1, $3).N2($2, $4) } 46 | | if_ Expression then Expression else_ Expression 47 | { $$ = p.NewNode(IfNode, $1, $3, $5).N3($2, $4, $6) } 48 | | let Binds in Expression 49 | { $$ = p.NewNode(LetNode, $1, $3).N2($2, $4) } 50 | | with Expression ';' Expression 51 | { $$ = p.NewNode(WithNode, $1, $3).N2($2, $4) } 52 | | Function 53 | ; 54 | 55 | Interp 56 | : interp Expression '}' 57 | { $$ = p.NewNode(InterpNode, $1, $3).N1($2) } 58 | ; 59 | 60 | String 61 | : 62 | { $$ = p.NewNode(StringNode) } 63 | | String text 64 | { $$ = $1.N1(p.NewNode(TextNode, $2)) } 65 | | String Interp 66 | { $$ = $1.N1($2) } 67 | ; 68 | 69 | ID 70 | : id 71 | { $$ = p.NewNode(IDNode, $1) } 72 | ; 73 | 74 | Atom 75 | : uri 76 | { $$ = p.NewNode(URINode, $1) } 77 | | path 78 | { $$ = p.NewNode(PathNode, $1) } 79 | | float 80 | { $$ = p.NewNode(FloatNode, $1) } 81 | | int_ 82 | { $$ = p.NewNode(IntNode, $1) } 83 | | ID 84 | | '"' String '"' 85 | { $$ = $2.T2($1, $3) } 86 | | ii String ii 87 | { $$ = $2.T2($1, $3).SetType(IStringNode) } 88 | | '(' Expression ')' 89 | { $$ = p.NewNode(ParensNode, $1, $3).N1($2) } 90 | | '[' List ']' 91 | { $$ = $2.T2($1, $3) } 92 | | '{' Binds '}' 93 | { $$ = $2.T2($1, $3).SetType(SetNode) } 94 | | rec '{' Binds '}' 95 | { $$ = $3.T3($1, $2, $4).SetType(RecSetNode) } 96 | ; 97 | 98 | Select 99 | : Atom 100 | | Atom '.' AttrPath 101 | { $$ = p.NewNode(SelectNode, $2).N2($1, $3) } 102 | | Atom '.' AttrPath or_ Select 103 | { $$ = p.NewNode(SelectOrNode, $2, $4).N3($1, $3, $5) } 104 | ; 105 | 106 | Apply 107 | : Select 108 | | Apply Select 109 | { $$ = p.NewNode(ApplyNode).N2($1, $2) } 110 | ; 111 | 112 | Op 113 | : Apply 114 | | '-' Op %prec negate 115 | { $$ = p.Op(negate, $1).N1($2) } 116 | | Op '?' AttrPath 117 | { $$ = p.Op('?', $2).N2($1, $3) } 118 | | Op concat Op 119 | { $$ = p.Op(concat, $2).N2($1, $3) } 120 | | Op '/' Op 121 | { $$ = p.Op('/', $2).N2($1, $3) } 122 | | Op '*' Op 123 | { $$ = p.Op('*', $2).N2($1, $3) } 124 | | Op '-' Op 125 | { $$ = p.Op('-', $2).N2($1, $3) } 126 | | Op '+' Op 127 | { $$ = p.Op('+', $2).N2($1, $3) } 128 | | '!' Op 129 | { $$ = p.Op('!', $1).N1($2) } 130 | | Op update Op 131 | { $$ = p.Op(update, $2).N2($1, $3) } 132 | | Op geq Op 133 | { $$ = p.Op(geq, $2).N2($1, $3) } 134 | | Op leq Op 135 | { $$ = p.Op(leq, $2).N2($1, $3) } 136 | | Op '>' Op 137 | { $$ = p.Op('>', $2).N2($1, $3) } 138 | | Op '<' Op 139 | { $$ = p.Op('<', $2).N2($1, $3) } 140 | | Op neq Op 141 | { $$ = p.Op(neq, $2).N2($1, $3) } 142 | | Op eq Op 143 | { $$ = p.Op(eq, $2).N2($1, $3) } 144 | | Op and Op 145 | { $$ = p.Op(and, $2).N2($1, $3) } 146 | | Op or Op 147 | { $$ = p.Op(or, $2).N2($1, $3) } 148 | | Op impl Op 149 | { $$ = p.Op(impl, $2).N2($1, $3) } 150 | ; 151 | 152 | InterpID 153 | : ID 154 | | or_ 155 | { $$ = p.NewNode(IDNode, $1) } 156 | | Interp 157 | | '"' String '"' 158 | { $$ = $2.T2($1, $3) } 159 | ; 160 | 161 | AttrPath 162 | : InterpID 163 | { $$ = p.NewNode(AttrPathNode).N1($1) } 164 | | AttrPath '.' InterpID 165 | { $$ = $1.T1($2).N1($3) } 166 | ; 167 | 168 | List 169 | : 170 | { $$ = p.NewNode(ListNode) } 171 | | List Select 172 | { $$ = $1.N1($2) } 173 | ; 174 | 175 | Binds 176 | : 177 | { $$ = p.NewNode(BindsNode) } 178 | | Binds AttrPath '=' Expression ';' 179 | { $$ = $1.N1(p.NewNode(BindNode, $3, $5).N2($2, $4)) } 180 | | Binds inherit InheritList ';' 181 | { $$ = $1.N1(p.NewNode(InheritNode, $2, $4).N1($3)) } 182 | | Binds inherit '(' Expression ')' InheritList ';' 183 | { $$ = $1.N1(p.NewNode(InheritFromNode, $2, $3, $5, $7).N2($4, $6)) } 184 | ; 185 | 186 | InheritList 187 | : 188 | { $$ = p.NewNode(InheritListNode) } 189 | | InheritList InterpID 190 | { $$ = $1.N1($2) } 191 | ; 192 | 193 | 194 | Function 195 | : argID ':' Expression 196 | { $$ = p.NewNode(FunctionNode, $2).N2(p.NewNode(IDNode, $1), $3) } 197 | | argBracket ArgSet '}' ':' Expression 198 | { $$ = p.NewNode(FunctionNode, $4).N2($2.T2($1, $3), $5) } 199 | | argID '@' argBracket ArgSet '}' ':' Expression 200 | { $$ = p.NewNode(FunctionNode, $2, $6).N3(p.NewNode(IDNode, $1), $4.T2($3, $5), $7) } 201 | | argBracket ArgSet '}' '@' argID ':' Expression 202 | { $$ = p.NewNode(FunctionNode, $4, $6).N3(p.NewNode(IDNode, $5), $2.T2($1, $3), $7) } 203 | ; 204 | 205 | ArgSet 206 | : 207 | { $$ = p.NewNode(ArgSetNode) } 208 | | Arg 209 | { $$ = p.NewNode(ArgSetNode).N1($1) } 210 | | ellipsis 211 | { $$ = p.NewNode(ArgSetNode).N1(p.NewNode(ArgNode, $1)) } 212 | | Arg ',' ArgSet 213 | { $$ = $3.N1($1.T1($2)) } 214 | ; 215 | 216 | Arg 217 | : ID 218 | { $$ = p.NewNode(ArgNode).N1($1) } 219 | | ID '?' Expression 220 | { $$ = p.NewNode(ArgNode, $2).N2($1, $3) } 221 | ; 222 | -------------------------------------------------------------------------------- /nix/parser/nodetype.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | type NodeType uint16 4 | 5 | const ( 6 | ApplyNode NodeType = iota 7 | ArgNode 8 | ArgSetNode 9 | AssertNode 10 | AttrPathNode 11 | BindNode 12 | BindsNode 13 | FloatNode 14 | FunctionNode 15 | IDNode 16 | IStringNode 17 | IfNode 18 | InheritFromNode 19 | InheritListNode 20 | InheritNode 21 | IntNode 22 | InterpNode 23 | LetNode 24 | ListNode 25 | ParensNode 26 | PathNode 27 | RecSetNode 28 | SelectNode 29 | SelectOrNode 30 | SetNode 31 | StringNode 32 | TextNode 33 | URINode 34 | WithNode 35 | 36 | OpNode 37 | ) 38 | 39 | var nodeName = map[NodeType]string{ 40 | ApplyNode: "apply", 41 | ArgNode: "arg", 42 | ArgSetNode: "argset", 43 | AssertNode: "assert", 44 | AttrPathNode: "attrpath", 45 | BindNode: "bind", 46 | BindsNode: "binds", 47 | FloatNode: "float", 48 | FunctionNode: "function", 49 | IDNode: "id", 50 | IStringNode: "istring", 51 | IfNode: "if", 52 | InheritFromNode: "inheritfrom", 53 | InheritListNode: "inheritlist", 54 | InheritNode: "inherit", 55 | IntNode: "int", 56 | InterpNode: "interp", 57 | LetNode: "let", 58 | ListNode: "list", 59 | ParensNode: "parens", 60 | PathNode: "path", 61 | RecSetNode: "recset", 62 | SelectNode: "select", 63 | SelectOrNode: "selector", 64 | SetNode: "set", 65 | StringNode: "string", 66 | TextNode: "text", 67 | URINode: "uri", 68 | WithNode: "with", 69 | 70 | OpNode + negate: "-", 71 | OpNode + '?': "?", 72 | OpNode + concat: "++", 73 | OpNode + '/': "/", 74 | OpNode + '*': "*", 75 | OpNode + '-': "-", 76 | OpNode + '+': "+", 77 | OpNode + '!': "!", 78 | OpNode + update: "//", 79 | OpNode + geq: ">=", 80 | OpNode + leq: "<=", 81 | OpNode + '>': ">", 82 | OpNode + '<': "<", 83 | OpNode + neq: "!=", 84 | OpNode + eq: "==", 85 | OpNode + and: "&&", 86 | OpNode + or: "||", 87 | OpNode + impl: "->", 88 | } 89 | 90 | func (nt NodeType) String() string { 91 | if s, ok := nodeName[nt]; ok { 92 | return s 93 | } 94 | panic("unknown node type") 95 | } 96 | -------------------------------------------------------------------------------- /nix/parser/parser.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | //go:generate goyacc nix.y 4 | //go:generate sed "/yyS :=/a\\\tp := yylex.(*Parser)" -i y.go 5 | 6 | import ( 7 | "fmt" 8 | "strings" 9 | ) 10 | 11 | type Node struct { 12 | Type NodeType 13 | Tokens []int 14 | Nodes []*Node 15 | 16 | preallocatedNodes [2]*Node 17 | } 18 | 19 | const nodesBlock = 1024 20 | 21 | type Parser struct { 22 | *lexResult 23 | prev int 24 | last int 25 | errors []string 26 | 27 | nodes []Node 28 | nextNode int 29 | 30 | Result *Node 31 | } 32 | 33 | func newParser(lr *lexResult) *Parser { 34 | return &Parser{lexResult: lr, prev: -1, last: len(lr.tokens) - 1} 35 | } 36 | 37 | func (p *Parser) Lex(lval *yySymType) int { 38 | if p.prev == p.last { 39 | return 0 40 | } 41 | p.prev++ 42 | lval.token = p.prev 43 | return p.tokens[p.prev].sym 44 | } 45 | 46 | func (p *Parser) Error(s string) { 47 | s = p.tokens[p.prev].String() + ": " + s 48 | p.errors = append(p.errors, s) 49 | } 50 | 51 | func (p *Parser) NewNode(t NodeType, tokens ...int) *Node { 52 | if p.nextNode == len(p.nodes) { 53 | p.nodes = make([]Node, nodesBlock) 54 | p.nextNode = 0 55 | } 56 | n := &p.nodes[p.nextNode] 57 | p.nextNode++ 58 | n.Type = t 59 | n.Tokens = tokens 60 | n.Nodes = n.preallocatedNodes[:0] 61 | return n 62 | } 63 | 64 | func (p *Parser) Op(t NodeType, tokens ...int) *Node { return p.NewNode(OpNode+t, tokens...) } 65 | 66 | func (n *Node) SetType(t NodeType) *Node { n.Type = t; return n } 67 | 68 | func (n *Node) T(tokens ...int) *Node { n.Tokens = append(n.Tokens, tokens...); return n } 69 | func (n *Node) T1(t0 int) *Node { n.Tokens = append(n.Tokens, t0); return n } 70 | func (n *Node) T2(t0, t1 int) *Node { n.Tokens = append(n.Tokens, t0, t1); return n } 71 | func (n *Node) T3(t0, t1, t2 int) *Node { n.Tokens = append(n.Tokens, t0, t1, t2); return n } 72 | 73 | func (n *Node) N(nodes ...*Node) *Node { n.Nodes = append(n.Nodes, nodes...); return n } 74 | func (n *Node) N1(n0 *Node) *Node { n.Nodes = append(n.Nodes, n0); return n } 75 | func (n *Node) N2(n0, n1 *Node) *Node { n.Nodes = append(n.Nodes, n0, n1); return n } 76 | func (n *Node) N3(n0, n1, n2 *Node) *Node { n.Nodes = append(n.Nodes, n0, n1, n2); return n } 77 | 78 | func (p *Parser) LispResult() string { 79 | return p.Result.lispFormat(p) 80 | } 81 | 82 | func (n *Node) lispFormat(p *Parser) string { 83 | s := n.Type.String() 84 | if s == "" { 85 | panic("unknown node type") 86 | } 87 | for _, child := range n.Nodes { 88 | s += " " + child.lispFormat(p) 89 | } 90 | switch n.Type { 91 | case URINode, PathNode, FloatNode, IntNode: 92 | s += " " + p.TokenString(n.Tokens[0]) 93 | case IDNode: 94 | s += " |" + p.TokenString(n.Tokens[0]) + "|" 95 | case TextNode: 96 | s += ` "` + p.TokenString(n.Tokens[0]) + `"` 97 | } 98 | return "(" + s + ")" 99 | } 100 | 101 | func parse(lr *lexResult) (p *Parser, err error) { 102 | p = newParser(lr) 103 | yyErrorVerbose = true 104 | yyParse(p) 105 | if len(p.errors) == 0 { 106 | return 107 | } 108 | path := p.file.Name() 109 | err = fmt.Errorf("%s: %s", path, strings.Join(p.errors, "; ")) 110 | return 111 | } 112 | 113 | func ParseFile(path string) (p *Parser, err error) { 114 | lr, err := lexFile(path) 115 | if err != nil { 116 | return 117 | } 118 | return parse(lr) 119 | } 120 | 121 | func ParseString(s string) (p *Parser, err error) { 122 | lr, err := lex([]byte(s), "") 123 | if err != nil { 124 | return 125 | } 126 | return parse(lr) 127 | } 128 | -------------------------------------------------------------------------------- /nix/parser/parser_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/alecthomas/assert" 7 | "github.com/orivej/e" 8 | "github.com/orivej/go-nix/nix/util" 9 | ) 10 | 11 | func TestParseOne(t *testing.T) { 12 | p, err := ParseString(oneText) 13 | assert.NoError(t, err) 14 | t.Log(p.LispResult()) 15 | } 16 | 17 | func TestParseAll(t *testing.T) { 18 | if testing.Short() { 19 | t.SkipNow() 20 | } 21 | skipWithoutNixPath(t) 22 | cnt := 0 23 | err := util.WalkNix(nixpkgs, func(path string) error { 24 | _, err := ParseFile(path) 25 | assert.NoError(t, err, path) 26 | cnt++ 27 | return nil 28 | }) 29 | t.Logf("parsed %d files", cnt) 30 | assert.NoError(t, err) 31 | } 32 | 33 | func BenchmarkParse(b *testing.B) { 34 | path := allPackages 35 | lr, err := lexFile(path) 36 | e.Exit(err) 37 | 38 | for i := 0; i < b.N; i++ { 39 | _, err = parse(lr) 40 | assert.NoError(b, err) 41 | } 42 | } 43 | 44 | var oneText = ` 45 | # Function comment. 46 | { lib }: 47 | with lib.trivial; 48 | rec { 49 | inherit lib; 50 | inherit (builtins) head tail; 51 | s.a = "a${"b"}c"; 52 | } 53 | ` 54 | -------------------------------------------------------------------------------- /nix/parser/path.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "os" 5 | gopath "path" 6 | "strings" 7 | ) 8 | 9 | var NixPath = splitNixPath(os.Getenv("NIX_PATH")) 10 | 11 | func ResolvePath(s string) string { 12 | return resolvePath(s, NixPath, fsPathExists) 13 | } 14 | 15 | func splitNixPath(s string) [][2]string { 16 | if s == "" { 17 | return nil 18 | } 19 | parts := strings.Split(s, ":") 20 | entries := make([][2]string, len(parts)) 21 | for i, part := range parts { 22 | entries[i][1] = part 23 | if strings.Contains(part, "=") { 24 | copy(entries[i][:], strings.SplitN(part, "=", 2)) 25 | } 26 | } 27 | return entries 28 | } 29 | 30 | func fsPathExists(s string) bool { 31 | _, err := os.Stat(s) 32 | return err == nil 33 | } 34 | 35 | func resolvePath(s string, nixpath [][2]string, exists func(string) bool) string { 36 | for _, pair := range nixpath { 37 | k, v := pair[0], pair[1] 38 | var r string 39 | switch { 40 | case k == "": 41 | r = gopath.Join(v, s) 42 | case s == k || strings.HasPrefix(s, k+"/"): 43 | r = v + s[len(k):] 44 | default: 45 | continue 46 | } 47 | if exists(r) { 48 | return r 49 | } 50 | } 51 | return "" 52 | } 53 | -------------------------------------------------------------------------------- /nix/parser/path_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/alecthomas/assert" 7 | ) 8 | 9 | var allPackages = ResolvePath("nixpkgs/pkgs/top-level/all-packages.nix") 10 | var nixpkgs = ResolvePath("nixpkgs") 11 | var attrsets = ResolvePath("nixpkgs/lib/attrsets.nix") 12 | 13 | func skipWithoutNixPath(t *testing.T) { 14 | if len(NixPath) == 0 { 15 | t.Skip("NIX_PATH is not set") 16 | } 17 | } 18 | 19 | func TestSplitNixPath(t *testing.T) { 20 | tests := map[string][][2]string{ 21 | "": nil, 22 | "a": {{"", "a"}}, 23 | "a:b:c": {{"", "a"}, {"", "b"}, {"", "c"}}, 24 | "p=b": {{"p", "b"}}, 25 | "a:p=b:c": {{"", "a"}, {"p", "b"}, {"", "c"}}, 26 | "a:p=b:q=c": {{"", "a"}, {"p", "b"}, {"q", "c"}}, 27 | } 28 | for q, a := range tests { 29 | assert.Equal(t, a, splitNixPath(q), q) 30 | } 31 | } 32 | 33 | func TestResolvePath(t *testing.T) { 34 | no := func(string) bool { return false } 35 | yes := func(string) bool { return true } 36 | assert.Equal(t, "", resolvePath("f", [][2]string{{"", "/a"}}, no)) 37 | assert.Equal(t, "/a/f", resolvePath("f", [][2]string{{"", "/a"}}, yes)) 38 | assert.Equal(t, "/b/f", resolvePath("p/f", [][2]string{{"p", "/b"}}, yes)) 39 | assert.Equal(t, "", resolvePath("pa/f", [][2]string{{"p", "/b"}}, yes)) 40 | } 41 | -------------------------------------------------------------------------------- /nix/parser/y.go: -------------------------------------------------------------------------------- 1 | //line nix.y:2 2 | package parser 3 | 4 | import __yyfmt__ "fmt" 5 | 6 | //line nix.y:2 7 | //line nix.y:5 8 | type yySymType struct { 9 | yys int 10 | token int 11 | node *Node 12 | } 13 | 14 | const assert_ = 57346 15 | const if_ = 57347 16 | const then = 57348 17 | const else_ = 57349 18 | const let = 57350 19 | const in = 57351 20 | const with = 57352 21 | const or_ = 57353 22 | const rec = 57354 23 | const inherit = 57355 24 | const ellipsis = 57356 25 | const interp = 57357 26 | const space = 57358 27 | const comment = 57359 28 | const ii = 57360 29 | const uri = 57361 30 | const path = 57362 31 | const float = 57363 32 | const int_ = 57364 33 | const id = 57365 34 | const text = 57366 35 | const argID = 57367 36 | const argBracket = 57368 37 | const impl = 57369 38 | const or = 57370 39 | const and = 57371 40 | const eq = 57372 41 | const neq = 57373 42 | const leq = 57374 43 | const geq = 57375 44 | const update = 57376 45 | const concat = 57377 46 | const negate = 57378 47 | 48 | var yyToknames = [...]string{ 49 | "$end", 50 | "error", 51 | "$unk", 52 | "assert_", 53 | "if_", 54 | "then", 55 | "else_", 56 | "let", 57 | "in", 58 | "with", 59 | "or_", 60 | "rec", 61 | "inherit", 62 | "ellipsis", 63 | "interp", 64 | "space", 65 | "comment", 66 | "ii", 67 | "uri", 68 | "path", 69 | "float", 70 | "int_", 71 | "id", 72 | "text", 73 | "argID", 74 | "argBracket", 75 | "':'", 76 | "'@'", 77 | "','", 78 | "';'", 79 | "'\"'", 80 | "'.'", 81 | "'('", 82 | "')'", 83 | "'['", 84 | "']'", 85 | "'{'", 86 | "'}'", 87 | "'='", 88 | "impl", 89 | "or", 90 | "and", 91 | "eq", 92 | "neq", 93 | "'<'", 94 | "'>'", 95 | "leq", 96 | "geq", 97 | "update", 98 | "'!'", 99 | "'+'", 100 | "'-'", 101 | "'*'", 102 | "'/'", 103 | "concat", 104 | "'?'", 105 | "negate", 106 | } 107 | var yyStatenames = [...]string{} 108 | 109 | const yyEofCode = 1 110 | const yyErrCode = 2 111 | const yyInitialStackSize = 16 112 | 113 | //line yacctab:1 114 | var yyExca = [...]int{ 115 | -1, 1, 116 | 1, -1, 117 | -2, 0, 118 | -1, 81, 119 | 43, 0, 120 | 44, 0, 121 | -2, 43, 122 | -1, 82, 123 | 43, 0, 124 | 44, 0, 125 | -2, 44, 126 | -1, 85, 127 | 40, 0, 128 | -2, 47, 129 | } 130 | 131 | const yyPrivate = 57344 132 | 133 | const yyLast = 370 134 | 135 | var yyAct = [...]int{ 136 | 137 | 2, 14, 20, 65, 114, 44, 45, 53, 47, 29, 138 | 28, 48, 96, 68, 132, 34, 56, 33, 32, 31, 139 | 30, 29, 28, 126, 60, 31, 30, 29, 28, 46, 140 | 58, 66, 43, 42, 41, 40, 39, 38, 37, 36, 141 | 35, 34, 94, 33, 32, 31, 30, 29, 28, 66, 142 | 89, 107, 92, 59, 63, 62, 138, 102, 113, 115, 143 | 66, 137, 107, 104, 57, 66, 91, 86, 95, 122, 144 | 140, 109, 99, 99, 38, 37, 36, 35, 34, 64, 145 | 33, 32, 31, 30, 29, 28, 139, 110, 111, 112, 146 | 107, 93, 116, 106, 134, 67, 56, 121, 56, 70, 147 | 108, 117, 127, 120, 70, 87, 1, 27, 97, 66, 148 | 66, 124, 55, 98, 128, 69, 131, 66, 130, 133, 149 | 125, 27, 99, 54, 135, 8, 70, 61, 136, 33, 150 | 32, 31, 30, 29, 28, 98, 118, 119, 9, 15, 151 | 142, 143, 100, 141, 66, 130, 4, 5, 51, 52, 152 | 6, 0, 7, 0, 26, 0, 0, 0, 0, 0, 153 | 22, 16, 17, 18, 19, 27, 67, 12, 13, 0, 154 | 70, 70, 0, 21, 101, 23, 0, 24, 27, 25, 155 | 98, 0, 0, 0, 0, 144, 69, 0, 0, 0, 156 | 0, 0, 11, 0, 10, 42, 41, 40, 39, 38, 157 | 37, 36, 35, 34, 0, 33, 32, 31, 30, 29, 158 | 28, 41, 40, 39, 38, 37, 36, 35, 34, 0, 159 | 33, 32, 31, 30, 29, 28, 40, 39, 38, 37, 160 | 36, 35, 34, 0, 33, 32, 31, 30, 29, 28, 161 | 26, 0, 0, 0, 0, 0, 22, 16, 17, 18, 162 | 19, 27, 67, 0, 90, 3, 70, 0, 0, 21, 163 | 0, 23, 0, 24, 27, 25, 49, 50, 0, 0, 164 | 0, 0, 69, 0, 0, 0, 0, 0, 11, 123, 165 | 10, 0, 0, 0, 0, 71, 72, 73, 74, 75, 166 | 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 167 | 26, 0, 0, 0, 0, 0, 22, 16, 17, 18, 168 | 19, 27, 0, 0, 0, 0, 0, 0, 0, 21, 169 | 26, 23, 0, 24, 103, 25, 22, 16, 17, 18, 170 | 19, 27, 67, 0, 90, 0, 70, 0, 67, 21, 171 | 0, 23, 70, 24, 27, 25, 0, 88, 0, 67, 172 | 27, 90, 69, 70, 0, 0, 0, 129, 69, 105, 173 | 0, 27, 0, 0, 0, 0, 0, 0, 0, 69, 174 | } 175 | var yyPact = [...]int{ 176 | 177 | 142, -1000, -1000, -8, 142, 142, -1000, 142, -1000, 308, 178 | 228, 228, 121, 98, -1000, 32, -1000, -1000, -1000, -1000, 179 | -1000, -1000, -1000, 142, -1000, -1000, 17, -1000, 84, 228, 180 | 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 181 | 228, 228, 228, 228, 37, 99, 338, 36, -1000, -1000, 182 | 78, 142, 65, 4, 39, -1000, -44, 84, 111, 156, 183 | 23, 288, 321, -1000, 30, -1000, -1000, -1000, -1000, -1000, 184 | 142, -46, -46, -46, -28, -28, -34, -34, -34, -34, 185 | -34, 29, 29, 183, 169, 154, 142, 142, 142, 19, 186 | 26, 142, -1000, 98, 109, 98, 142, 58, -1000, -1000, 187 | -1000, -1000, -1000, -1000, -1000, -1000, 241, 84, 89, -15, 188 | -1000, 95, -1000, 142, 327, 142, -1000, -24, 142, 69, 189 | -1000, -1000, 308, -1000, -1000, -1000, -1000, 142, 31, -1000, 190 | -1000, 22, 59, -1000, 43, -1000, -1000, -1000, -1000, 142, 191 | 142, 155, -1000, -1000, -1000, 192 | } 193 | var yyPgo = [...]int{ 194 | 195 | 0, 0, 13, 30, 2, 139, 1, 138, 255, 3, 196 | 50, 127, 29, 4, 125, 7, 123, 106, 197 | } 198 | var yyR1 = [...]int{ 199 | 200 | 0, 17, 1, 1, 1, 1, 1, 1, 2, 3, 201 | 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 202 | 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 203 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 204 | 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 205 | 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 206 | 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 207 | 16, 16, 208 | } 209 | var yyR2 = [...]int{ 210 | 211 | 0, 1, 1, 4, 6, 4, 4, 1, 3, 0, 212 | 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 213 | 3, 3, 3, 4, 1, 3, 5, 1, 2, 1, 214 | 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 215 | 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 216 | 1, 3, 1, 3, 0, 2, 0, 5, 4, 7, 217 | 0, 2, 3, 5, 7, 7, 0, 1, 1, 3, 218 | 1, 3, 219 | } 220 | var yyChk = [...]int{ 221 | 222 | -1000, -17, -1, -8, 4, 5, 8, 10, -14, -7, 223 | 52, 50, 25, 26, -6, -5, 19, 20, 21, 22, 224 | -4, 31, 18, 33, 35, 37, 12, 23, 56, 55, 225 | 54, 53, 52, 51, 49, 48, 47, 46, 45, 44, 226 | 43, 42, 41, 40, -1, -1, -12, -1, -6, -8, 227 | -8, 27, 28, -15, -16, 14, -4, 32, -3, -3, 228 | -1, -11, -12, 37, -10, -9, -4, 11, -2, 31, 229 | 15, -8, -8, -8, -8, -8, -8, -8, -8, -8, 230 | -8, -8, -8, -8, -8, -8, 30, 6, 9, -10, 231 | 13, 30, -1, 26, 38, 29, 56, -10, 24, -2, 232 | 31, 18, 34, 36, -6, 38, -12, 32, -3, -1, 233 | -1, -1, -1, 39, -13, 33, -1, -15, 27, 28, 234 | -15, -1, 11, 38, -9, 31, 38, 7, -1, 30, 235 | -9, -1, 38, -1, 25, -6, -1, 30, 34, 27, 236 | 27, -13, -1, -1, 30, 237 | } 238 | var yyDef = [...]int{ 239 | 240 | 0, -2, 1, 2, 0, 0, 56, 0, 7, 29, 241 | 0, 0, 0, 66, 27, 24, 13, 14, 15, 16, 242 | 17, 9, 9, 0, 54, 56, 0, 12, 0, 0, 243 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244 | 0, 0, 0, 0, 0, 0, 0, 0, 28, 30, 245 | 37, 0, 0, 0, 67, 68, 70, 0, 0, 0, 246 | 0, 0, 0, 56, 31, 52, 48, 49, 50, 9, 247 | 0, 32, 33, 34, 35, 36, 38, 39, 40, 41, 248 | 42, -2, -2, 45, 46, -2, 0, 0, 0, 0, 249 | 60, 0, 62, 66, 0, 66, 0, 25, 10, 11, 250 | 18, 19, 20, 21, 55, 22, 0, 0, 0, 0, 251 | 3, 0, 5, 0, 0, 0, 6, 0, 0, 0, 252 | 69, 71, 0, 23, 53, 51, 8, 0, 0, 58, 253 | 61, 0, 0, 63, 0, 26, 4, 57, 60, 0, 254 | 0, 0, 64, 65, 59, 255 | } 256 | var yyTok1 = [...]int{ 257 | 258 | 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 259 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 260 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 261 | 3, 3, 3, 50, 31, 3, 3, 3, 3, 3, 262 | 33, 34, 53, 51, 29, 52, 32, 54, 3, 3, 263 | 3, 3, 3, 3, 3, 3, 3, 3, 27, 30, 264 | 45, 39, 46, 56, 28, 3, 3, 3, 3, 3, 265 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 266 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 267 | 3, 35, 3, 36, 3, 3, 3, 3, 3, 3, 268 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 269 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 270 | 3, 3, 3, 37, 3, 38, 271 | } 272 | var yyTok2 = [...]int{ 273 | 274 | 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 275 | 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 276 | 22, 23, 24, 25, 26, 40, 41, 42, 43, 44, 277 | 47, 48, 49, 55, 57, 278 | } 279 | var yyTok3 = [...]int{ 280 | 0, 281 | } 282 | 283 | var yyErrorMessages = [...]struct { 284 | state int 285 | token int 286 | msg string 287 | }{} 288 | 289 | //line yaccpar:1 290 | 291 | /* parser for yacc output */ 292 | 293 | var ( 294 | yyDebug = 0 295 | yyErrorVerbose = false 296 | ) 297 | 298 | type yyLexer interface { 299 | Lex(lval *yySymType) int 300 | Error(s string) 301 | } 302 | 303 | type yyParser interface { 304 | Parse(yyLexer) int 305 | Lookahead() int 306 | } 307 | 308 | type yyParserImpl struct { 309 | lval yySymType 310 | stack [yyInitialStackSize]yySymType 311 | char int 312 | } 313 | 314 | func (p *yyParserImpl) Lookahead() int { 315 | return p.char 316 | } 317 | 318 | func yyNewParser() yyParser { 319 | return &yyParserImpl{} 320 | } 321 | 322 | const yyFlag = -1000 323 | 324 | func yyTokname(c int) string { 325 | if c >= 1 && c-1 < len(yyToknames) { 326 | if yyToknames[c-1] != "" { 327 | return yyToknames[c-1] 328 | } 329 | } 330 | return __yyfmt__.Sprintf("tok-%v", c) 331 | } 332 | 333 | func yyStatname(s int) string { 334 | if s >= 0 && s < len(yyStatenames) { 335 | if yyStatenames[s] != "" { 336 | return yyStatenames[s] 337 | } 338 | } 339 | return __yyfmt__.Sprintf("state-%v", s) 340 | } 341 | 342 | func yyErrorMessage(state, lookAhead int) string { 343 | const TOKSTART = 4 344 | 345 | if !yyErrorVerbose { 346 | return "syntax error" 347 | } 348 | 349 | for _, e := range yyErrorMessages { 350 | if e.state == state && e.token == lookAhead { 351 | return "syntax error: " + e.msg 352 | } 353 | } 354 | 355 | res := "syntax error: unexpected " + yyTokname(lookAhead) 356 | 357 | // To match Bison, suggest at most four expected tokens. 358 | expected := make([]int, 0, 4) 359 | 360 | // Look for shiftable tokens. 361 | base := yyPact[state] 362 | for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { 363 | if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok { 364 | if len(expected) == cap(expected) { 365 | return res 366 | } 367 | expected = append(expected, tok) 368 | } 369 | } 370 | 371 | if yyDef[state] == -2 { 372 | i := 0 373 | for yyExca[i] != -1 || yyExca[i+1] != state { 374 | i += 2 375 | } 376 | 377 | // Look for tokens that we accept or reduce. 378 | for i += 2; yyExca[i] >= 0; i += 2 { 379 | tok := yyExca[i] 380 | if tok < TOKSTART || yyExca[i+1] == 0 { 381 | continue 382 | } 383 | if len(expected) == cap(expected) { 384 | return res 385 | } 386 | expected = append(expected, tok) 387 | } 388 | 389 | // If the default action is to accept or reduce, give up. 390 | if yyExca[i+1] != 0 { 391 | return res 392 | } 393 | } 394 | 395 | for i, tok := range expected { 396 | if i == 0 { 397 | res += ", expecting " 398 | } else { 399 | res += " or " 400 | } 401 | res += yyTokname(tok) 402 | } 403 | return res 404 | } 405 | 406 | func yylex1(lex yyLexer, lval *yySymType) (char, token int) { 407 | token = 0 408 | char = lex.Lex(lval) 409 | if char <= 0 { 410 | token = yyTok1[0] 411 | goto out 412 | } 413 | if char < len(yyTok1) { 414 | token = yyTok1[char] 415 | goto out 416 | } 417 | if char >= yyPrivate { 418 | if char < yyPrivate+len(yyTok2) { 419 | token = yyTok2[char-yyPrivate] 420 | goto out 421 | } 422 | } 423 | for i := 0; i < len(yyTok3); i += 2 { 424 | token = yyTok3[i+0] 425 | if token == char { 426 | token = yyTok3[i+1] 427 | goto out 428 | } 429 | } 430 | 431 | out: 432 | if token == 0 { 433 | token = yyTok2[1] /* unknown char */ 434 | } 435 | if yyDebug >= 3 { 436 | __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) 437 | } 438 | return char, token 439 | } 440 | 441 | func yyParse(yylex yyLexer) int { 442 | return yyNewParser().Parse(yylex) 443 | } 444 | 445 | func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { 446 | var yyn int 447 | var yyVAL yySymType 448 | var yyDollar []yySymType 449 | _ = yyDollar // silence set and not used 450 | yyS := yyrcvr.stack[:] 451 | p := yylex.(*Parser) 452 | 453 | Nerrs := 0 /* number of errors */ 454 | Errflag := 0 /* error recovery flag */ 455 | yystate := 0 456 | yyrcvr.char = -1 457 | yytoken := -1 // yyrcvr.char translated into internal numbering 458 | defer func() { 459 | // Make sure we report no lookahead when not parsing. 460 | yystate = -1 461 | yyrcvr.char = -1 462 | yytoken = -1 463 | }() 464 | yyp := -1 465 | goto yystack 466 | 467 | ret0: 468 | return 0 469 | 470 | ret1: 471 | return 1 472 | 473 | yystack: 474 | /* put a state and value onto the stack */ 475 | if yyDebug >= 4 { 476 | __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) 477 | } 478 | 479 | yyp++ 480 | if yyp >= len(yyS) { 481 | nyys := make([]yySymType, len(yyS)*2) 482 | copy(nyys, yyS) 483 | yyS = nyys 484 | } 485 | yyS[yyp] = yyVAL 486 | yyS[yyp].yys = yystate 487 | 488 | yynewstate: 489 | yyn = yyPact[yystate] 490 | if yyn <= yyFlag { 491 | goto yydefault /* simple state */ 492 | } 493 | if yyrcvr.char < 0 { 494 | yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) 495 | } 496 | yyn += yytoken 497 | if yyn < 0 || yyn >= yyLast { 498 | goto yydefault 499 | } 500 | yyn = yyAct[yyn] 501 | if yyChk[yyn] == yytoken { /* valid shift */ 502 | yyrcvr.char = -1 503 | yytoken = -1 504 | yyVAL = yyrcvr.lval 505 | yystate = yyn 506 | if Errflag > 0 { 507 | Errflag-- 508 | } 509 | goto yystack 510 | } 511 | 512 | yydefault: 513 | /* default state action */ 514 | yyn = yyDef[yystate] 515 | if yyn == -2 { 516 | if yyrcvr.char < 0 { 517 | yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) 518 | } 519 | 520 | /* look through exception table */ 521 | xi := 0 522 | for { 523 | if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { 524 | break 525 | } 526 | xi += 2 527 | } 528 | for xi += 2; ; xi += 2 { 529 | yyn = yyExca[xi+0] 530 | if yyn < 0 || yyn == yytoken { 531 | break 532 | } 533 | } 534 | yyn = yyExca[xi+1] 535 | if yyn < 0 { 536 | goto ret0 537 | } 538 | } 539 | if yyn == 0 { 540 | /* error ... attempt to resume parsing */ 541 | switch Errflag { 542 | case 0: /* brand new error */ 543 | yylex.Error(yyErrorMessage(yystate, yytoken)) 544 | Nerrs++ 545 | if yyDebug >= 1 { 546 | __yyfmt__.Printf("%s", yyStatname(yystate)) 547 | __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) 548 | } 549 | fallthrough 550 | 551 | case 1, 2: /* incompletely recovered error ... try again */ 552 | Errflag = 3 553 | 554 | /* find a state where "error" is a legal shift action */ 555 | for yyp >= 0 { 556 | yyn = yyPact[yyS[yyp].yys] + yyErrCode 557 | if yyn >= 0 && yyn < yyLast { 558 | yystate = yyAct[yyn] /* simulate a shift of "error" */ 559 | if yyChk[yystate] == yyErrCode { 560 | goto yystack 561 | } 562 | } 563 | 564 | /* the current p has no shift on "error", pop stack */ 565 | if yyDebug >= 2 { 566 | __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) 567 | } 568 | yyp-- 569 | } 570 | /* there is no state on the stack with an error shift ... abort */ 571 | goto ret1 572 | 573 | case 3: /* no shift yet; clobber input char */ 574 | if yyDebug >= 2 { 575 | __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) 576 | } 577 | if yytoken == yyEofCode { 578 | goto ret1 579 | } 580 | yyrcvr.char = -1 581 | yytoken = -1 582 | goto yynewstate /* try again in the same state */ 583 | } 584 | } 585 | 586 | /* reduction by production yyn */ 587 | if yyDebug >= 2 { 588 | __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) 589 | } 590 | 591 | yynt := yyn 592 | yypt := yyp 593 | _ = yypt // guard against "declared and not used" 594 | 595 | yyp -= yyR2[yyn] 596 | // yyp is now the index of $0. Perform the default action. Iff the 597 | // reduced production is ε, $1 is possibly out of range. 598 | if yyp+1 >= len(yyS) { 599 | nyys := make([]yySymType, len(yyS)*2) 600 | copy(nyys, yyS) 601 | yyS = nyys 602 | } 603 | yyVAL = yyS[yyp+1] 604 | 605 | /* consult goto table to find next state */ 606 | yyn = yyR1[yyn] 607 | yyg := yyPgo[yyn] 608 | yyj := yyg + yyS[yyp].yys + 1 609 | 610 | if yyj >= yyLast { 611 | yystate = yyAct[yyg] 612 | } else { 613 | yystate = yyAct[yyj] 614 | if yyChk[yystate] != -yyn { 615 | yystate = yyAct[yyg] 616 | } 617 | } 618 | // dummy call; replaced with literal code 619 | switch yynt { 620 | 621 | case 1: 622 | yyDollar = yyS[yypt-1 : yypt+1] 623 | //line nix.y:39 624 | { 625 | p.Result = yyDollar[1].node 626 | } 627 | case 3: 628 | yyDollar = yyS[yypt-4 : yypt+1] 629 | //line nix.y:45 630 | { 631 | yyVAL.node = p.NewNode(AssertNode, yyDollar[1].token, yyDollar[3].token).N2(yyDollar[2].node, yyDollar[4].node) 632 | } 633 | case 4: 634 | yyDollar = yyS[yypt-6 : yypt+1] 635 | //line nix.y:47 636 | { 637 | yyVAL.node = p.NewNode(IfNode, yyDollar[1].token, yyDollar[3].token, yyDollar[5].token).N3(yyDollar[2].node, yyDollar[4].node, yyDollar[6].node) 638 | } 639 | case 5: 640 | yyDollar = yyS[yypt-4 : yypt+1] 641 | //line nix.y:49 642 | { 643 | yyVAL.node = p.NewNode(LetNode, yyDollar[1].token, yyDollar[3].token).N2(yyDollar[2].node, yyDollar[4].node) 644 | } 645 | case 6: 646 | yyDollar = yyS[yypt-4 : yypt+1] 647 | //line nix.y:51 648 | { 649 | yyVAL.node = p.NewNode(WithNode, yyDollar[1].token, yyDollar[3].token).N2(yyDollar[2].node, yyDollar[4].node) 650 | } 651 | case 8: 652 | yyDollar = yyS[yypt-3 : yypt+1] 653 | //line nix.y:57 654 | { 655 | yyVAL.node = p.NewNode(InterpNode, yyDollar[1].token, yyDollar[3].token).N1(yyDollar[2].node) 656 | } 657 | case 9: 658 | yyDollar = yyS[yypt-0 : yypt+1] 659 | //line nix.y:62 660 | { 661 | yyVAL.node = p.NewNode(StringNode) 662 | } 663 | case 10: 664 | yyDollar = yyS[yypt-2 : yypt+1] 665 | //line nix.y:64 666 | { 667 | yyVAL.node = yyDollar[1].node.N1(p.NewNode(TextNode, yyDollar[2].token)) 668 | } 669 | case 11: 670 | yyDollar = yyS[yypt-2 : yypt+1] 671 | //line nix.y:66 672 | { 673 | yyVAL.node = yyDollar[1].node.N1(yyDollar[2].node) 674 | } 675 | case 12: 676 | yyDollar = yyS[yypt-1 : yypt+1] 677 | //line nix.y:71 678 | { 679 | yyVAL.node = p.NewNode(IDNode, yyDollar[1].token) 680 | } 681 | case 13: 682 | yyDollar = yyS[yypt-1 : yypt+1] 683 | //line nix.y:76 684 | { 685 | yyVAL.node = p.NewNode(URINode, yyDollar[1].token) 686 | } 687 | case 14: 688 | yyDollar = yyS[yypt-1 : yypt+1] 689 | //line nix.y:78 690 | { 691 | yyVAL.node = p.NewNode(PathNode, yyDollar[1].token) 692 | } 693 | case 15: 694 | yyDollar = yyS[yypt-1 : yypt+1] 695 | //line nix.y:80 696 | { 697 | yyVAL.node = p.NewNode(FloatNode, yyDollar[1].token) 698 | } 699 | case 16: 700 | yyDollar = yyS[yypt-1 : yypt+1] 701 | //line nix.y:82 702 | { 703 | yyVAL.node = p.NewNode(IntNode, yyDollar[1].token) 704 | } 705 | case 18: 706 | yyDollar = yyS[yypt-3 : yypt+1] 707 | //line nix.y:85 708 | { 709 | yyVAL.node = yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token) 710 | } 711 | case 19: 712 | yyDollar = yyS[yypt-3 : yypt+1] 713 | //line nix.y:87 714 | { 715 | yyVAL.node = yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token).SetType(IStringNode) 716 | } 717 | case 20: 718 | yyDollar = yyS[yypt-3 : yypt+1] 719 | //line nix.y:89 720 | { 721 | yyVAL.node = p.NewNode(ParensNode, yyDollar[1].token, yyDollar[3].token).N1(yyDollar[2].node) 722 | } 723 | case 21: 724 | yyDollar = yyS[yypt-3 : yypt+1] 725 | //line nix.y:91 726 | { 727 | yyVAL.node = yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token) 728 | } 729 | case 22: 730 | yyDollar = yyS[yypt-3 : yypt+1] 731 | //line nix.y:93 732 | { 733 | yyVAL.node = yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token).SetType(SetNode) 734 | } 735 | case 23: 736 | yyDollar = yyS[yypt-4 : yypt+1] 737 | //line nix.y:95 738 | { 739 | yyVAL.node = yyDollar[3].node.T3(yyDollar[1].token, yyDollar[2].token, yyDollar[4].token).SetType(RecSetNode) 740 | } 741 | case 25: 742 | yyDollar = yyS[yypt-3 : yypt+1] 743 | //line nix.y:101 744 | { 745 | yyVAL.node = p.NewNode(SelectNode, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 746 | } 747 | case 26: 748 | yyDollar = yyS[yypt-5 : yypt+1] 749 | //line nix.y:103 750 | { 751 | yyVAL.node = p.NewNode(SelectOrNode, yyDollar[2].token, yyDollar[4].token).N3(yyDollar[1].node, yyDollar[3].node, yyDollar[5].node) 752 | } 753 | case 28: 754 | yyDollar = yyS[yypt-2 : yypt+1] 755 | //line nix.y:109 756 | { 757 | yyVAL.node = p.NewNode(ApplyNode).N2(yyDollar[1].node, yyDollar[2].node) 758 | } 759 | case 30: 760 | yyDollar = yyS[yypt-2 : yypt+1] 761 | //line nix.y:115 762 | { 763 | yyVAL.node = p.Op(negate, yyDollar[1].token).N1(yyDollar[2].node) 764 | } 765 | case 31: 766 | yyDollar = yyS[yypt-3 : yypt+1] 767 | //line nix.y:117 768 | { 769 | yyVAL.node = p.Op('?', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 770 | } 771 | case 32: 772 | yyDollar = yyS[yypt-3 : yypt+1] 773 | //line nix.y:119 774 | { 775 | yyVAL.node = p.Op(concat, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 776 | } 777 | case 33: 778 | yyDollar = yyS[yypt-3 : yypt+1] 779 | //line nix.y:121 780 | { 781 | yyVAL.node = p.Op('/', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 782 | } 783 | case 34: 784 | yyDollar = yyS[yypt-3 : yypt+1] 785 | //line nix.y:123 786 | { 787 | yyVAL.node = p.Op('*', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 788 | } 789 | case 35: 790 | yyDollar = yyS[yypt-3 : yypt+1] 791 | //line nix.y:125 792 | { 793 | yyVAL.node = p.Op('-', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 794 | } 795 | case 36: 796 | yyDollar = yyS[yypt-3 : yypt+1] 797 | //line nix.y:127 798 | { 799 | yyVAL.node = p.Op('+', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 800 | } 801 | case 37: 802 | yyDollar = yyS[yypt-2 : yypt+1] 803 | //line nix.y:129 804 | { 805 | yyVAL.node = p.Op('!', yyDollar[1].token).N1(yyDollar[2].node) 806 | } 807 | case 38: 808 | yyDollar = yyS[yypt-3 : yypt+1] 809 | //line nix.y:131 810 | { 811 | yyVAL.node = p.Op(update, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 812 | } 813 | case 39: 814 | yyDollar = yyS[yypt-3 : yypt+1] 815 | //line nix.y:133 816 | { 817 | yyVAL.node = p.Op(geq, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 818 | } 819 | case 40: 820 | yyDollar = yyS[yypt-3 : yypt+1] 821 | //line nix.y:135 822 | { 823 | yyVAL.node = p.Op(leq, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 824 | } 825 | case 41: 826 | yyDollar = yyS[yypt-3 : yypt+1] 827 | //line nix.y:137 828 | { 829 | yyVAL.node = p.Op('>', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 830 | } 831 | case 42: 832 | yyDollar = yyS[yypt-3 : yypt+1] 833 | //line nix.y:139 834 | { 835 | yyVAL.node = p.Op('<', yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 836 | } 837 | case 43: 838 | yyDollar = yyS[yypt-3 : yypt+1] 839 | //line nix.y:141 840 | { 841 | yyVAL.node = p.Op(neq, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 842 | } 843 | case 44: 844 | yyDollar = yyS[yypt-3 : yypt+1] 845 | //line nix.y:143 846 | { 847 | yyVAL.node = p.Op(eq, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 848 | } 849 | case 45: 850 | yyDollar = yyS[yypt-3 : yypt+1] 851 | //line nix.y:145 852 | { 853 | yyVAL.node = p.Op(and, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 854 | } 855 | case 46: 856 | yyDollar = yyS[yypt-3 : yypt+1] 857 | //line nix.y:147 858 | { 859 | yyVAL.node = p.Op(or, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 860 | } 861 | case 47: 862 | yyDollar = yyS[yypt-3 : yypt+1] 863 | //line nix.y:149 864 | { 865 | yyVAL.node = p.Op(impl, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 866 | } 867 | case 49: 868 | yyDollar = yyS[yypt-1 : yypt+1] 869 | //line nix.y:155 870 | { 871 | yyVAL.node = p.NewNode(IDNode, yyDollar[1].token) 872 | } 873 | case 51: 874 | yyDollar = yyS[yypt-3 : yypt+1] 875 | //line nix.y:158 876 | { 877 | yyVAL.node = yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token) 878 | } 879 | case 52: 880 | yyDollar = yyS[yypt-1 : yypt+1] 881 | //line nix.y:163 882 | { 883 | yyVAL.node = p.NewNode(AttrPathNode).N1(yyDollar[1].node) 884 | } 885 | case 53: 886 | yyDollar = yyS[yypt-3 : yypt+1] 887 | //line nix.y:165 888 | { 889 | yyVAL.node = yyDollar[1].node.T1(yyDollar[2].token).N1(yyDollar[3].node) 890 | } 891 | case 54: 892 | yyDollar = yyS[yypt-0 : yypt+1] 893 | //line nix.y:170 894 | { 895 | yyVAL.node = p.NewNode(ListNode) 896 | } 897 | case 55: 898 | yyDollar = yyS[yypt-2 : yypt+1] 899 | //line nix.y:172 900 | { 901 | yyVAL.node = yyDollar[1].node.N1(yyDollar[2].node) 902 | } 903 | case 56: 904 | yyDollar = yyS[yypt-0 : yypt+1] 905 | //line nix.y:177 906 | { 907 | yyVAL.node = p.NewNode(BindsNode) 908 | } 909 | case 57: 910 | yyDollar = yyS[yypt-5 : yypt+1] 911 | //line nix.y:179 912 | { 913 | yyVAL.node = yyDollar[1].node.N1(p.NewNode(BindNode, yyDollar[3].token, yyDollar[5].token).N2(yyDollar[2].node, yyDollar[4].node)) 914 | } 915 | case 58: 916 | yyDollar = yyS[yypt-4 : yypt+1] 917 | //line nix.y:181 918 | { 919 | yyVAL.node = yyDollar[1].node.N1(p.NewNode(InheritNode, yyDollar[2].token, yyDollar[4].token).N1(yyDollar[3].node)) 920 | } 921 | case 59: 922 | yyDollar = yyS[yypt-7 : yypt+1] 923 | //line nix.y:183 924 | { 925 | yyVAL.node = yyDollar[1].node.N1(p.NewNode(InheritFromNode, yyDollar[2].token, yyDollar[3].token, yyDollar[5].token, yyDollar[7].token).N2(yyDollar[4].node, yyDollar[6].node)) 926 | } 927 | case 60: 928 | yyDollar = yyS[yypt-0 : yypt+1] 929 | //line nix.y:188 930 | { 931 | yyVAL.node = p.NewNode(InheritListNode) 932 | } 933 | case 61: 934 | yyDollar = yyS[yypt-2 : yypt+1] 935 | //line nix.y:190 936 | { 937 | yyVAL.node = yyDollar[1].node.N1(yyDollar[2].node) 938 | } 939 | case 62: 940 | yyDollar = yyS[yypt-3 : yypt+1] 941 | //line nix.y:196 942 | { 943 | yyVAL.node = p.NewNode(FunctionNode, yyDollar[2].token).N2(p.NewNode(IDNode, yyDollar[1].token), yyDollar[3].node) 944 | } 945 | case 63: 946 | yyDollar = yyS[yypt-5 : yypt+1] 947 | //line nix.y:198 948 | { 949 | yyVAL.node = p.NewNode(FunctionNode, yyDollar[4].token).N2(yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token), yyDollar[5].node) 950 | } 951 | case 64: 952 | yyDollar = yyS[yypt-7 : yypt+1] 953 | //line nix.y:200 954 | { 955 | yyVAL.node = p.NewNode(FunctionNode, yyDollar[2].token, yyDollar[6].token).N3(p.NewNode(IDNode, yyDollar[1].token), yyDollar[4].node.T2(yyDollar[3].token, yyDollar[5].token), yyDollar[7].node) 956 | } 957 | case 65: 958 | yyDollar = yyS[yypt-7 : yypt+1] 959 | //line nix.y:202 960 | { 961 | yyVAL.node = p.NewNode(FunctionNode, yyDollar[4].token, yyDollar[6].token).N3(p.NewNode(IDNode, yyDollar[5].token), yyDollar[2].node.T2(yyDollar[1].token, yyDollar[3].token), yyDollar[7].node) 962 | } 963 | case 66: 964 | yyDollar = yyS[yypt-0 : yypt+1] 965 | //line nix.y:207 966 | { 967 | yyVAL.node = p.NewNode(ArgSetNode) 968 | } 969 | case 67: 970 | yyDollar = yyS[yypt-1 : yypt+1] 971 | //line nix.y:209 972 | { 973 | yyVAL.node = p.NewNode(ArgSetNode).N1(yyDollar[1].node) 974 | } 975 | case 68: 976 | yyDollar = yyS[yypt-1 : yypt+1] 977 | //line nix.y:211 978 | { 979 | yyVAL.node = p.NewNode(ArgSetNode).N1(p.NewNode(ArgNode, yyDollar[1].token)) 980 | } 981 | case 69: 982 | yyDollar = yyS[yypt-3 : yypt+1] 983 | //line nix.y:213 984 | { 985 | yyVAL.node = yyDollar[3].node.N1(yyDollar[1].node.T1(yyDollar[2].token)) 986 | } 987 | case 70: 988 | yyDollar = yyS[yypt-1 : yypt+1] 989 | //line nix.y:218 990 | { 991 | yyVAL.node = p.NewNode(ArgNode).N1(yyDollar[1].node) 992 | } 993 | case 71: 994 | yyDollar = yyS[yypt-3 : yypt+1] 995 | //line nix.y:220 996 | { 997 | yyVAL.node = p.NewNode(ArgNode, yyDollar[2].token).N2(yyDollar[1].node, yyDollar[3].node) 998 | } 999 | } 1000 | goto yystack /* stack new state and value */ 1001 | } 1002 | -------------------------------------------------------------------------------- /nix/util/walk.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | func WalkNix(dir string, f func(string) error) error { 9 | return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 10 | if err != nil { 11 | return err 12 | } 13 | if info.IsDir() || filepath.Ext(info.Name()) != ".nix" { 14 | return nil 15 | } 16 | return f(path) 17 | }) 18 | } 19 | --------------------------------------------------------------------------------