aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/urubu/cmd/ucdgen/main.go98
-rw-r--r--src/urubu/cmd/vartan-go/generate.go98
-rw-r--r--src/urubu/cmd/vartan-go/main.go14
-rw-r--r--src/urubu/cmd/vartan/compile.go190
-rw-r--r--src/urubu/cmd/vartan/main.go14
-rw-r--r--src/urubu/cmd/vartan/parse.go110
-rw-r--r--src/urubu/cmd/vartan/root.go22
-rw-r--r--src/urubu/cmd/vartan/show.go295
-rw-r--r--src/urubu/cmd/vartan/test.go50
-rw-r--r--src/urubu/compressor/compressor.go214
-rw-r--r--src/urubu/driver/lexer/lexer.go335
-rw-r--r--src/urubu/driver/lexer/spec.go71
-rw-r--r--src/urubu/driver/lexer/template.go760
-rw-r--r--src/urubu/driver/parser/parser.go416
-rw-r--r--src/urubu/driver/parser/semantic_action.go371
-rw-r--r--src/urubu/driver/parser/spec.go73
-rw-r--r--src/urubu/driver/parser/template.go535
-rw-r--r--src/urubu/driver/parser/token_stream.go65
-rw-r--r--src/urubu/error/error.go86
-rw-r--r--src/urubu/grammar/first.go148
-rw-r--r--src/urubu/grammar/grammar.go1390
-rw-r--r--src/urubu/grammar/item.go206
-rw-r--r--src/urubu/grammar/lalr1.go318
-rw-r--r--src/urubu/grammar/lexical/compiler.go413
-rw-r--r--src/urubu/grammar/lexical/dfa/dfa.go173
-rw-r--r--src/urubu/grammar/lexical/dfa/symbol_position.go182
-rw-r--r--src/urubu/grammar/lexical/dfa/tree.go567
-rw-r--r--src/urubu/grammar/lexical/entry.go171
-rw-r--r--src/urubu/grammar/lexical/parser/error.go36
-rw-r--r--src/urubu/grammar/lexical/parser/fragment.go72
-rw-r--r--src/urubu/grammar/lexical/parser/lexer.go594
-rw-r--r--src/urubu/grammar/lexical/parser/parser.go531
-rw-r--r--src/urubu/grammar/lexical/parser/tree.go459
-rw-r--r--src/urubu/grammar/lr0.go197
-rw-r--r--src/urubu/grammar/parsing_table.go553
-rw-r--r--src/urubu/grammar/production.go117
-rw-r--r--src/urubu/grammar/semantic_error.go30
-rw-r--r--src/urubu/grammar/symbol/symbol.go295
-rw-r--r--src/urubu/spec/grammar/description.go71
-rw-r--r--src/urubu/spec/grammar/grammar.go160
-rw-r--r--src/urubu/spec/grammar/parser/clexspec.json1
-rw-r--r--src/urubu/spec/grammar/parser/lexer.go297
-rw-r--r--src/urubu/spec/grammar/parser/lexspec.json123
-rw-r--r--src/urubu/spec/grammar/parser/parser.go582
-rw-r--r--src/urubu/spec/grammar/parser/syntax_error.go45
-rw-r--r--src/urubu/spec/grammar/parser/vartan_lexer.go1339
-rw-r--r--src/urubu/spec/grammar/util.go21
-rw-r--r--src/urubu/spec/test/parser.go336
-rw-r--r--src/urubu/spec/test/tree-report.json1
-rw-r--r--src/urubu/spec/test/tree.json1
-rw-r--r--src/urubu/spec/test/tree.vartan87
-rw-r--r--src/urubu/spec/test/tree_lexer.go1024
-rw-r--r--src/urubu/spec/test/tree_parser.go716
-rw-r--r--src/urubu/spec/test/tree_semantic_action.go367
-rw-r--r--src/urubu/tester/tester.go181
-rw-r--r--src/urubu/ucd/api.go180
-rw-r--r--src/urubu/ucd/codepoint.go6552
-rw-r--r--src/urubu/ucd/codepoint.go.tmpl65
-rw-r--r--src/urubu/ucd/parser.go155
-rw-r--r--src/urubu/ucd/prop_list.go50
-rw-r--r--src/urubu/ucd/property.go95
-rw-r--r--src/urubu/ucd/property_value_aliases.go82
-rw-r--r--src/urubu/ucd/scripts.go52
-rw-r--r--src/urubu/ucd/unicode_data.go56
-rw-r--r--src/urubu/utf8/utf8.go112
65 files changed, 23020 insertions, 0 deletions
diff --git a/src/urubu/cmd/ucdgen/main.go b/src/urubu/cmd/ucdgen/main.go
new file mode 100644
index 0000000..d5599a6
--- /dev/null
+++ b/src/urubu/cmd/ucdgen/main.go
@@ -0,0 +1,98 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+ "os"
+ "strings"
+ "text/template"
+
+ "urubu/ucd"
+)
+
+func main() {
+ err := gen()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ os.Exit(1)
+ }
+}
+
+func gen() error {
+ var propValAliases *ucd.PropertyValueAliases
+ {
+ resp, err := http.Get("https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt")
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ propValAliases, err = ucd.ParsePropertyValueAliases(resp.Body)
+ if err != nil {
+ return err
+ }
+ }
+ var unicodeData *ucd.UnicodeData
+ {
+ resp, err := http.Get("https://www.unicode.org/Public/13.0.0/ucd/UnicodeData.txt")
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ unicodeData, err = ucd.ParseUnicodeData(resp.Body, propValAliases)
+ if err != nil {
+ return err
+ }
+ }
+ var scripts *ucd.Scripts
+ {
+ resp, err := http.Get("https://www.unicode.org/Public/13.0.0/ucd/Scripts.txt")
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ scripts, err = ucd.ParseScripts(resp.Body, propValAliases)
+ if err != nil {
+ return err
+ }
+ }
+ var propList *ucd.PropList
+ {
+ resp, err := http.Get("https://www.unicode.org/Public/13.0.0/ucd/PropList.txt")
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ propList, err = ucd.ParsePropList(resp.Body)
+ if err != nil {
+ return err
+ }
+ }
+ tmpl, err := template.ParseFiles("../ucd/codepoint.go.tmpl")
+ if err != nil {
+ return err
+ }
+ var b strings.Builder
+ err = tmpl.Execute(&b, struct {
+ GeneratorName string
+ UnicodeData *ucd.UnicodeData
+ Scripts *ucd.Scripts
+ PropList *ucd.PropList
+ PropertyValueAliases *ucd.PropertyValueAliases
+ }{
+ GeneratorName: "generator/main.go",
+ UnicodeData: unicodeData,
+ Scripts: scripts,
+ PropList: propList,
+ PropertyValueAliases: propValAliases,
+ })
+ if err != nil {
+ return err
+ }
+ f, err := os.OpenFile("../ucd/codepoint.go", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ fmt.Fprint(f, b.String())
+ return nil
+}
diff --git a/src/urubu/cmd/vartan-go/generate.go b/src/urubu/cmd/vartan-go/generate.go
new file mode 100644
index 0000000..8f2da84
--- /dev/null
+++ b/src/urubu/cmd/vartan-go/generate.go
@@ -0,0 +1,98 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+
+ "urubu/driver/lexer"
+ "urubu/driver/parser"
+ spec "urubu/spec/grammar"
+)
+
+func runGenerate(args []string) error {
+ cgram, err := readCompiledGrammar(args[0])
+ if err != nil {
+ return fmt.Errorf("Cannot read a compiled grammar: %w", err)
+ }
+
+ {
+ b, err := lexer.GenLexer(cgram.Lexical, "main")
+ if err != nil {
+ return fmt.Errorf("Failed to generate a lexer: %w", err)
+ }
+
+ filePath := fmt.Sprintf("%v_lexer.go", cgram.Name)
+
+ f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return fmt.Errorf("Failed to create an output file: %v", err)
+ }
+ defer f.Close()
+
+ _, err = f.Write(b)
+ if err != nil {
+ return fmt.Errorf("Failed to write lexer source code: %v", err)
+ }
+ }
+
+ {
+ b, err := parser.GenParser(cgram, "main")
+ if err != nil {
+ return fmt.Errorf("Failed to generate a parser: %w", err)
+ }
+
+ filePath := fmt.Sprintf("%v_parser.go", cgram.Name)
+
+ f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return fmt.Errorf("Failed to create an output file: %v", err)
+ }
+ defer f.Close()
+
+ _, err = f.Write(b)
+ if err != nil {
+ return fmt.Errorf("Failed to write parser source code: %v", err)
+ }
+ }
+
+ {
+ b, err := parser.GenSemanticAction("main")
+ if err != nil {
+ return fmt.Errorf("Failed to generate a semantic action set: %w", err)
+ }
+
+ filePath := fmt.Sprintf("%v_semantic_action.go", cgram.Name)
+
+ f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return fmt.Errorf("Failed to create an output file: %v", err)
+ }
+ defer f.Close()
+
+ _, err = f.Write(b)
+ if err != nil {
+ return fmt.Errorf("Failed to write semantic action source code: %v", err)
+ }
+ }
+
+ return nil
+}
+
+func readCompiledGrammar(path string) (*spec.CompiledGrammar, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ data, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ cgram := &spec.CompiledGrammar{}
+ err = json.Unmarshal(data, cgram)
+ if err != nil {
+ return nil, err
+ }
+ return cgram, nil
+}
diff --git a/src/urubu/cmd/vartan-go/main.go b/src/urubu/cmd/vartan-go/main.go
new file mode 100644
index 0000000..315e7b3
--- /dev/null
+++ b/src/urubu/cmd/vartan-go/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ err := runGenerate(os.Args[1:])
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
diff --git a/src/urubu/cmd/vartan/compile.go b/src/urubu/cmd/vartan/compile.go
new file mode 100644
index 0000000..79fa9ef
--- /dev/null
+++ b/src/urubu/cmd/vartan/compile.go
@@ -0,0 +1,190 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+
+ verr "urubu/error"
+ "urubu/grammar"
+ spec "urubu/spec/grammar"
+ "urubu/spec/grammar/parser"
+)
+
+
+
+func runCompile(args []string) (retErr error) {
+ var tmpDirPath string
+ defer func() {
+ if tmpDirPath == "" {
+ return
+ }
+ os.RemoveAll(tmpDirPath)
+ }()
+
+ var grmPath string
+ if len(args) > 0 {
+ grmPath = args[0]
+ }
+ defer func() {
+ if retErr != nil {
+ specErrs, ok := retErr.(verr.SpecErrors)
+ if ok {
+ for _, err := range specErrs {
+ if len(args) > 0 {
+ err.FilePath = grmPath
+ err.SourceName = grmPath
+ } else {
+ err.FilePath = grmPath
+ err.SourceName = "stdin"
+ }
+ }
+ }
+ }
+ }()
+
+ if grmPath == "" {
+ var err error
+ tmpDirPath, err = os.MkdirTemp("", "vartan-compile-*")
+ if err != nil {
+ return err
+ }
+
+ src, err := io.ReadAll(os.Stdin)
+ if err != nil {
+ return err
+ }
+
+ grmPath = filepath.Join(tmpDirPath, "stdin.vartan")
+ err = os.WriteFile(grmPath, src, 0600)
+ if err != nil {
+ return err
+ }
+ }
+
+ gram, report, err := readGrammar(grmPath)
+ if err != nil {
+ return err
+ }
+
+ err = writeCompiledGrammarAndReport(gram, report, "")
+ if err != nil {
+ return fmt.Errorf("Cannot write an output files: %w", err)
+ }
+
+ var implicitlyResolvedCount int
+ for _, s := range report.States {
+ for _, c := range s.SRConflict {
+ if c.ResolvedBy == grammar.ResolvedByShift.Int() {
+ implicitlyResolvedCount++
+ }
+ }
+ for _, c := range s.RRConflict {
+ if c.ResolvedBy == grammar.ResolvedByProdOrder.Int() {
+ implicitlyResolvedCount++
+ }
+ }
+ }
+ if implicitlyResolvedCount > 0 {
+ fmt.Fprintf(os.Stdout, "%v conflicts\n", implicitlyResolvedCount)
+ }
+
+ return nil
+}
+
+func readGrammar(path string) (*spec.CompiledGrammar, *spec.Report, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, nil, fmt.Errorf("Cannot open the grammar file %s: %w", path, err)
+ }
+ defer f.Close()
+
+ ast, err := parser.Parse(f)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ b := grammar.GrammarBuilder{
+ AST: ast,
+ }
+ return b.Build(grammar.EnableReporting())
+}
+
+// writeCompiledGrammarAndReport writes a compiled grammar and a report to a files located at a specified path.
+// This function selects one of the following output methods depending on how the path is specified.
+//
+// 1. When the path is a directory path, this function writes the compiled grammar and the report to
+// <path>/<grammar-name>.json and <path>/<grammar-name>-report.json files, respectively.
+// <grammar-name>-report.json as the output files.
+// 2. When the path is a file path or a non-exitent path, this function asumes that the path represents a file
+// path for the compiled grammar. Then it also writes the report in the same directory as the compiled grammar.
+// The report file is named <grammar-name>.json.
+// 3. When the path is an empty string, this function writes the compiled grammar to the stdout and writes
+// the report to a file named <current-directory>/<grammar-name>-report.json.
+func writeCompiledGrammarAndReport(cgram *spec.CompiledGrammar, report *spec.Report, path string) error {
+ cgramPath, reportPath, err := makeOutputFilePaths(cgram.Name, path)
+ if err != nil {
+ return err
+ }
+
+ {
+ var cgramW io.Writer
+ if cgramPath != "" {
+ cgramFile, err := os.OpenFile(cgramPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return err
+ }
+ defer cgramFile.Close()
+ cgramW = cgramFile
+ } else {
+ cgramW = os.Stdout
+ }
+
+ b, err := json.Marshal(cgram)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(cgramW, "%v\n", string(b))
+ }
+
+ {
+ reportFile, err := os.OpenFile(reportPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return err
+ }
+ defer reportFile.Close()
+
+ b, err := json.Marshal(report)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(reportFile, "%v\n", string(b))
+ }
+
+ return nil
+}
+
+func makeOutputFilePaths(gramName string, path string) (string, string, error) {
+ reportFileName := gramName + "-report.json"
+
+ if path == "" {
+ wd, err := os.Getwd()
+ if err != nil {
+ return "", "", err
+ }
+ return "", filepath.Join(wd, reportFileName), nil
+ }
+
+ fi, err := os.Stat(path)
+ if err != nil && !os.IsNotExist(err) {
+ return "", "", err
+ }
+ if os.IsNotExist(err) || !fi.IsDir() {
+ dir, _ := filepath.Split(path)
+ return path, filepath.Join(dir, reportFileName), nil
+ }
+
+ return filepath.Join(path, gramName+".json"), filepath.Join(path, reportFileName), nil
+}
diff --git a/src/urubu/cmd/vartan/main.go b/src/urubu/cmd/vartan/main.go
new file mode 100644
index 0000000..98f98e1
--- /dev/null
+++ b/src/urubu/cmd/vartan/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ err := Execute()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
diff --git a/src/urubu/cmd/vartan/parse.go b/src/urubu/cmd/vartan/parse.go
new file mode 100644
index 0000000..9c5fd9c
--- /dev/null
+++ b/src/urubu/cmd/vartan/parse.go
@@ -0,0 +1,110 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ driver "urubu/driver/parser"
+ spec "urubu/spec/grammar"
+)
+
+
+
+func runParse(args []string) error {
+ cg, err := readCompiledGrammar(args[0])
+ if err != nil {
+ return fmt.Errorf("Cannot read a compiled grammar: %w", err)
+ }
+
+ src := os.Stdin
+ gram := driver.NewGrammar(cg)
+
+ tb := driver.NewDefaultSyntaxTreeBuilder()
+ treeAct := driver.NewCSTActionSet(gram, tb)
+
+ opts := []driver.ParserOption{}
+ opts = append(opts, driver.SemanticAction(treeAct))
+
+ toks, err := driver.NewTokenStream(cg, src)
+ if err != nil {
+ return err
+ }
+
+ p, err := driver.NewParser(toks, gram, opts...)
+ if err != nil {
+ return err
+ }
+
+ err = p.Parse()
+ if err != nil {
+ return err
+ }
+
+ // A parser can construct a parse tree even if syntax errors occur.
+ // When therer is a parse tree, print it.
+ if tree := tb.Tree(); tree != nil {
+ b, err := json.Marshal(tree)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintln(os.Stdout, string(b))
+ }
+
+ if len(p.SyntaxErrors()) > 0 {
+ var b strings.Builder
+ synErrs := p.SyntaxErrors()
+ writeSyntaxErrorMessage(&b, cg, synErrs[0])
+ for _, synErr := range synErrs[1:] {
+ fmt.Fprintf(&b, "\n")
+ writeSyntaxErrorMessage(&b, cg, synErr)
+ }
+ if b.Len() > 0 {
+ return fmt.Errorf(b.String())
+ }
+ }
+
+ return nil
+}
+
+func readCompiledGrammar(path string) (*spec.CompiledGrammar, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ data, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ cg := &spec.CompiledGrammar{}
+ err = json.Unmarshal(data, cg)
+ if err != nil {
+ return nil, err
+ }
+ return cg, nil
+}
+
+func writeSyntaxErrorMessage(b *strings.Builder, cgram *spec.CompiledGrammar, synErr *driver.SyntaxError) {
+ fmt.Fprintf(b, "%v:%v: %v: ", synErr.Row+1, synErr.Col+1, synErr.Message)
+
+ tok := synErr.Token
+ switch {
+ case tok.EOF():
+ fmt.Fprintf(b, "<eof>")
+ case tok.Invalid():
+ fmt.Fprintf(b, "'%v' (<invalid>)", string(tok.Lexeme()))
+ default:
+ if kind := cgram.Syntactic.Terminals[tok.TerminalID()]; kind != "" {
+ fmt.Fprintf(b, "'%v' (%v)", string(tok.Lexeme()), kind)
+ } else {
+ fmt.Fprintf(b, "'%v'", string(tok.Lexeme()))
+ }
+ }
+
+ fmt.Fprintf(b, ": expected: %v", synErr.ExpectedTerminals[0])
+ for _, t := range synErr.ExpectedTerminals[1:] {
+ fmt.Fprintf(b, ", %v", t)
+ }
+}
diff --git a/src/urubu/cmd/vartan/root.go b/src/urubu/cmd/vartan/root.go
new file mode 100644
index 0000000..3dda70c
--- /dev/null
+++ b/src/urubu/cmd/vartan/root.go
@@ -0,0 +1,22 @@
+package main
+
+import (
+ "os"
+)
+
+func Execute() error {
+ cmd := os.Args[1]
+ args := os.Args[2:]
+
+ if cmd == "compile" {
+ return runCompile(args)
+ } else if cmd == "parse" {
+ return runParse(args)
+ } else if cmd == "show" {
+ return runShow(args)
+ } else if cmd == "test" {
+ return runTest(args)
+ }
+
+ return nil // FIXME
+}
diff --git a/src/urubu/cmd/vartan/show.go b/src/urubu/cmd/vartan/show.go
new file mode 100644
index 0000000..cab63a0
--- /dev/null
+++ b/src/urubu/cmd/vartan/show.go
@@ -0,0 +1,295 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+ "text/template"
+
+ "urubu/grammar"
+ spec "urubu/spec/grammar"
+)
+
+
+
+func runShow(args []string) error {
+ report, err := readReport(args[0])
+ if err != nil {
+ return err
+ }
+
+ err = writeReport(os.Stdout, report)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func readReport(path string) (*spec.Report, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, fmt.Errorf("Cannot open the report %s: %w", path, err)
+ }
+ defer f.Close()
+
+ d, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+
+ report := &spec.Report{}
+ err = json.Unmarshal(d, report)
+ if err != nil {
+ return nil, err
+ }
+
+ return report, nil
+}
+
+const reportTemplate = `# Conflicts
+
+{{ printConflictSummary . }}
+
+# Terminals
+
+{{ range slice .Terminals 1 -}}
+{{ printTerminal . }}
+{{ end }}
+# Productions
+
+{{ range slice .Productions 1 -}}
+{{ printProduction . }}
+{{ end }}
+# States
+{{ range .States }}
+## State {{ .Number }}
+
+{{ range .Kernel -}}
+{{ printItem . }}
+{{ end }}
+{{ range .Shift -}}
+{{ printShift . }}
+{{ end -}}
+{{ range .Reduce -}}
+{{ printReduce . }}
+{{ end -}}
+{{ range .GoTo -}}
+{{ printGoTo . }}
+{{ end }}
+{{ range .SRConflict -}}
+{{ printSRConflict . }}
+{{ end -}}
+{{ range .RRConflict -}}
+{{ printRRConflict . }}
+{{ end -}}
+{{ end }}`
+
+func writeReport(w io.Writer, report *spec.Report) error {
+ termName := func(sym int) string {
+ return report.Terminals[sym].Name
+ }
+
+ nonTermName := func(sym int) string {
+ return report.NonTerminals[sym].Name
+ }
+
+ termAssoc := func(sym int) string {
+ switch report.Terminals[sym].Associativity {
+ case "l":
+ return "left"
+ case "r":
+ return "right"
+ default:
+ return "no"
+ }
+ }
+
+ prodAssoc := func(prod int) string {
+ switch report.Productions[prod].Associativity {
+ case "l":
+ return "left"
+ case "r":
+ return "right"
+ default:
+ return "no"
+ }
+ }
+
+ fns := template.FuncMap{
+ "printConflictSummary": func(report *spec.Report) string {
+ var implicitlyResolvedCount int
+ var explicitlyResolvedCount int
+ for _, s := range report.States {
+ for _, c := range s.SRConflict {
+ if c.ResolvedBy == grammar.ResolvedByShift.Int() {
+ implicitlyResolvedCount++
+ } else {
+ explicitlyResolvedCount++
+ }
+ }
+ for _, c := range s.RRConflict {
+ if c.ResolvedBy == grammar.ResolvedByProdOrder.Int() {
+ implicitlyResolvedCount++
+ } else {
+ explicitlyResolvedCount++
+ }
+ }
+ }
+
+ var b strings.Builder
+ if implicitlyResolvedCount == 1 {
+ fmt.Fprintf(&b, "%v conflict occurred and resolved implicitly.\n", implicitlyResolvedCount)
+ } else if implicitlyResolvedCount > 1 {
+ fmt.Fprintf(&b, "%v conflicts occurred and resolved implicitly.\n", implicitlyResolvedCount)
+ }
+ if explicitlyResolvedCount == 1 {
+ fmt.Fprintf(&b, "%v conflict occurred and resolved explicitly.\n", explicitlyResolvedCount)
+ } else if explicitlyResolvedCount > 1 {
+ fmt.Fprintf(&b, "%v conflicts occurred and resolved explicitly.\n", explicitlyResolvedCount)
+ }
+ if implicitlyResolvedCount == 0 && explicitlyResolvedCount == 0 {
+ fmt.Fprintf(&b, "No conflict")
+ }
+ return b.String()
+ },
+ "printTerminal": func(term spec.Terminal) string {
+ var prec string
+ if term.Precedence != 0 {
+ prec = fmt.Sprintf("%2v", term.Precedence)
+ } else {
+ prec = " -"
+ }
+
+ var assoc string
+ if term.Associativity != "" {
+ assoc = term.Associativity
+ } else {
+ assoc = "-"
+ }
+
+ return fmt.Sprintf("%4v %v %v %v", term.Number, prec, assoc, term.Name)
+ },
+ "printProduction": func(prod spec.Production) string {
+ var prec string
+ if prod.Precedence != 0 {
+ prec = fmt.Sprintf("%2v", prod.Precedence)
+ } else {
+ prec = " -"
+ }
+
+ var assoc string
+ if prod.Associativity != "" {
+ assoc = prod.Associativity
+ } else {
+ assoc = "-"
+ }
+
+ var b strings.Builder
+ fmt.Fprintf(&b, "%v →", nonTermName(prod.LHS))
+ if len(prod.RHS) > 0 {
+ for _, e := range prod.RHS {
+ if e > 0 {
+ fmt.Fprintf(&b, " %v", termName(e))
+ } else {
+ fmt.Fprintf(&b, " %v", nonTermName(e*-1))
+ }
+ }
+ } else {
+ fmt.Fprintf(&b, " ε")
+ }
+
+ return fmt.Sprintf("%4v %v %v %v", prod.Number, prec, assoc, b.String())
+ },
+ "printItem": func(item spec.Item) string {
+ prod := report.Productions[item.Production]
+
+ var b strings.Builder
+ fmt.Fprintf(&b, "%v →", nonTermName(prod.LHS))
+ for i, e := range prod.RHS {
+ if i == item.Dot {
+ fmt.Fprintf(&b, " ・")
+ }
+ if e > 0 {
+ fmt.Fprintf(&b, " %v", termName(e))
+ } else {
+ fmt.Fprintf(&b, " %v", nonTermName(e*-1))
+ }
+ }
+ if item.Dot >= len(prod.RHS) {
+ fmt.Fprintf(&b, " ・")
+ }
+
+ return fmt.Sprintf("%4v %v", prod.Number, b.String())
+ },
+ "printShift": func(tran spec.Transition) string {
+ return fmt.Sprintf("shift %4v on %v", tran.State, termName(tran.Symbol))
+ },
+ "printReduce": func(reduce spec.Reduce) string {
+ var b strings.Builder
+ {
+ fmt.Fprintf(&b, "%v", termName(reduce.LookAhead[0]))
+ for _, a := range reduce.LookAhead[1:] {
+ fmt.Fprintf(&b, ", %v", termName(a))
+ }
+ }
+ return fmt.Sprintf("reduce %4v on %v", reduce.Production, b.String())
+ },
+ "printGoTo": func(tran spec.Transition) string {
+ return fmt.Sprintf("goto %4v on %v", tran.State, nonTermName(tran.Symbol))
+ },
+ "printSRConflict": func(sr spec.SRConflict) string {
+ var adopted string
+ switch {
+ case sr.AdoptedState != nil:
+ adopted = fmt.Sprintf("shift %v", *sr.AdoptedState)
+ case sr.AdoptedProduction != nil:
+ adopted = fmt.Sprintf("reduce %v", *sr.AdoptedProduction)
+ }
+ var resolvedBy string
+ switch sr.ResolvedBy {
+ case grammar.ResolvedByPrec.Int():
+ if sr.AdoptedState != nil {
+ resolvedBy = fmt.Sprintf("symbol %v has higher precedence than production %v", termName(sr.Symbol), sr.Production)
+ } else {
+ resolvedBy = fmt.Sprintf("production %v has higher precedence than symbol %v", sr.Production, termName(sr.Symbol))
+ }
+ case grammar.ResolvedByAssoc.Int():
+ if sr.AdoptedState != nil {
+ resolvedBy = fmt.Sprintf("symbol %v and production %v has the same precedence, and symbol %v has %v associativity", termName(sr.Symbol), sr.Production, termName(sr.Symbol), termAssoc(sr.Symbol))
+ } else {
+ resolvedBy = fmt.Sprintf("production %v and symbol %v has the same precedence, and production %v has %v associativity", sr.Production, termName(sr.Symbol), sr.Production, prodAssoc(sr.Production))
+ }
+ case grammar.ResolvedByShift.Int():
+ resolvedBy = fmt.Sprintf("symbol %v and production %v don't define a precedence comparison (default rule)", sr.Symbol, sr.Production)
+ default:
+ resolvedBy = "?" // This is a bug.
+ }
+ return fmt.Sprintf("shift/reduce conflict (shift %v, reduce %v) on %v: %v adopted because %v", sr.State, sr.Production, termName(sr.Symbol), adopted, resolvedBy)
+ },
+ "printRRConflict": func(rr spec.RRConflict) string {
+ var resolvedBy string
+ switch rr.ResolvedBy {
+ case grammar.ResolvedByProdOrder.Int():
+ resolvedBy = fmt.Sprintf("production %v and %v don't define a precedence comparison (default rule)", rr.Production1, rr.Production2)
+ default:
+ resolvedBy = "?" // This is a bug.
+ }
+ return fmt.Sprintf("reduce/reduce conflict (%v, %v) on %v: reduce %v adopted because %v", rr.Production1, rr.Production2, termName(rr.Symbol), rr.AdoptedProduction, resolvedBy)
+ },
+ }
+
+ tmpl, err := template.New("").Funcs(fns).Parse(reportTemplate)
+ if err != nil {
+ return err
+ }
+
+ err = tmpl.Execute(w, report)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/src/urubu/cmd/vartan/test.go b/src/urubu/cmd/vartan/test.go
new file mode 100644
index 0000000..eb24c0c
--- /dev/null
+++ b/src/urubu/cmd/vartan/test.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "os"
+
+ "urubu/tester"
+)
+
+
+
+func runTest(args []string) error {
+ gram, _, err := readGrammar(args[0])
+ if err != nil {
+ return fmt.Errorf("Cannot read a grammar: %w", err)
+ }
+
+ var cs []*tester.TestCaseWithMetadata
+ {
+ cs = tester.ListTestCases(args[1])
+ errOccurred := false
+ for _, c := range cs {
+ if c.Error != nil {
+ fmt.Fprintf(os.Stderr, "Failed to read a test case or a directory: %v\n%v\n", c.FilePath, c.Error)
+ errOccurred = true
+ }
+ }
+ if errOccurred {
+ return errors.New("Cannot run test")
+ }
+ }
+
+ t := &tester.Tester{
+ Grammar: gram,
+ Cases: cs,
+ }
+ rs := t.Run()
+ testFailed := false
+ for _, r := range rs {
+ fmt.Fprintln(os.Stdout, r)
+ if r.Error != nil {
+ testFailed = true
+ }
+ }
+ if testFailed {
+ return errors.New("Test failed")
+ }
+ return nil
+}
diff --git a/src/urubu/compressor/compressor.go b/src/urubu/compressor/compressor.go
new file mode 100644
index 0000000..cdfeacb
--- /dev/null
+++ b/src/urubu/compressor/compressor.go
@@ -0,0 +1,214 @@
+package compressor
+
+import (
+ "encoding/binary"
+ "fmt"
+ "sort"
+)
+
+type OriginalTable struct {
+ entries []int
+ rowCount int
+ colCount int
+}
+
+func NewOriginalTable(entries []int, colCount int) (*OriginalTable, error) {
+ if len(entries) == 0 {
+ return nil, fmt.Errorf("enries is empty")
+ }
+ if colCount <= 0 {
+ return nil, fmt.Errorf("colCount must be >=1")
+ }
+ if len(entries)%colCount != 0 {
+ return nil, fmt.Errorf("entries length or column count are incorrect; entries length: %v, column count: %v", len(entries), colCount)
+ }
+
+ return &OriginalTable{
+ entries: entries,
+ rowCount: len(entries) / colCount,
+ colCount: colCount,
+ }, nil
+}
+
+type Compressor interface {
+ Compress(orig *OriginalTable) error
+ Lookup(row, col int) (int, error)
+ OriginalTableSize() (int, int)
+}
+
+var (
+ _ Compressor = &UniqueEntriesTable{}
+ _ Compressor = &RowDisplacementTable{}
+)
+
+type UniqueEntriesTable struct {
+ UniqueEntries []int
+ RowNums []int
+ OriginalRowCount int
+ OriginalColCount int
+}
+
+func NewUniqueEntriesTable() *UniqueEntriesTable {
+ return &UniqueEntriesTable{}
+}
+
+func (tab *UniqueEntriesTable) Lookup(row, col int) (int, error) {
+ if row < 0 || row >= tab.OriginalRowCount || col < 0 || col >= tab.OriginalColCount {
+ return 0, fmt.Errorf("indexes are out of range: [%v, %v]", row, col)
+ }
+ return tab.UniqueEntries[tab.RowNums[row]*tab.OriginalColCount+col], nil
+}
+
+func (tab *UniqueEntriesTable) OriginalTableSize() (int, int) {
+ return tab.OriginalRowCount, tab.OriginalColCount
+}
+
+func (tab *UniqueEntriesTable) Compress(orig *OriginalTable) error {
+ var uniqueEntries []int
+ rowNums := make([]int, orig.rowCount)
+ hash2RowNum := map[string]int{}
+ nextRowNum := 0
+ for row := 0; row < orig.rowCount; row++ {
+ var rowHash string
+ {
+ buf := make([]byte, 0, orig.colCount*8)
+ for col := 0; col < orig.colCount; col++ {
+ b := make([]byte, 8)
+ binary.PutUvarint(b, uint64(orig.entries[row*orig.colCount+col]))
+ buf = append(buf, b...)
+ }
+ rowHash = string(buf)
+ }
+ rowNum, ok := hash2RowNum[rowHash]
+ if !ok {
+ rowNum = nextRowNum
+ nextRowNum++
+ hash2RowNum[rowHash] = rowNum
+ start := row * orig.colCount
+ entry := append([]int{}, orig.entries[start:start+orig.colCount]...)
+ uniqueEntries = append(uniqueEntries, entry...)
+ }
+ rowNums[row] = rowNum
+ }
+
+ tab.UniqueEntries = uniqueEntries
+ tab.RowNums = rowNums
+ tab.OriginalRowCount = orig.rowCount
+ tab.OriginalColCount = orig.colCount
+
+ return nil
+}
+
+const ForbiddenValue = -1
+
+type RowDisplacementTable struct {
+ OriginalRowCount int
+ OriginalColCount int
+ EmptyValue int
+ Entries []int
+ Bounds []int
+ RowDisplacement []int
+}
+
+func NewRowDisplacementTable(emptyValue int) *RowDisplacementTable {
+ return &RowDisplacementTable{
+ EmptyValue: emptyValue,
+ }
+}
+
+func (tab *RowDisplacementTable) Lookup(row int, col int) (int, error) {
+ if row < 0 || row >= tab.OriginalRowCount || col < 0 || col >= tab.OriginalColCount {
+ return tab.EmptyValue, fmt.Errorf("indexes are out of range: [%v, %v]", row, col)
+ }
+ d := tab.RowDisplacement[row]
+ if tab.Bounds[d+col] != row {
+ return tab.EmptyValue, nil
+ }
+ return tab.Entries[d+col], nil
+}
+
+func (tab *RowDisplacementTable) OriginalTableSize() (int, int) {
+ return tab.OriginalRowCount, tab.OriginalColCount
+}
+
+type rowInfo struct {
+ rowNum int
+ nonEmptyCount int
+ nonEmptyCol []int
+}
+
+func (tab *RowDisplacementTable) Compress(orig *OriginalTable) error {
+ rowInfo := make([]rowInfo, orig.rowCount)
+ {
+ row := 0
+ col := 0
+ rowInfo[0].rowNum = 0
+ for _, v := range orig.entries {
+ if col == orig.colCount {
+ row++
+ col = 0
+ rowInfo[row].rowNum = row
+ }
+ if v != tab.EmptyValue {
+ rowInfo[row].nonEmptyCount++
+ rowInfo[row].nonEmptyCol = append(rowInfo[row].nonEmptyCol, col)
+ }
+ col++
+ }
+
+ sort.SliceStable(rowInfo, func(i int, j int) bool {
+ return rowInfo[i].nonEmptyCount > rowInfo[j].nonEmptyCount
+ })
+ }
+
+ origEntriesLen := len(orig.entries)
+ entries := make([]int, origEntriesLen)
+ bounds := make([]int, origEntriesLen)
+ resultBottom := orig.colCount
+ rowDisplacement := make([]int, orig.rowCount)
+ {
+ for i := 0; i < origEntriesLen; i++ {
+ entries[i] = tab.EmptyValue
+ bounds[i] = ForbiddenValue
+ }
+
+ nextRowDisplacement := 0
+ for _, rInfo := range rowInfo {
+ if rInfo.nonEmptyCount <= 0 {
+ continue
+ }
+
+ for {
+ isOverlapped := false
+ for _, col := range rInfo.nonEmptyCol {
+ if entries[nextRowDisplacement+col] == tab.EmptyValue {
+ continue
+ }
+ nextRowDisplacement++
+ isOverlapped = true
+ break
+ }
+ if isOverlapped {
+ continue
+ }
+
+ rowDisplacement[rInfo.rowNum] = nextRowDisplacement
+ for _, col := range rInfo.nonEmptyCol {
+ entries[nextRowDisplacement+col] = orig.entries[(rInfo.rowNum*orig.colCount)+col]
+ bounds[nextRowDisplacement+col] = rInfo.rowNum
+ }
+ resultBottom = nextRowDisplacement + orig.colCount
+ nextRowDisplacement++
+ break
+ }
+ }
+ }
+
+ tab.OriginalRowCount = orig.rowCount
+ tab.OriginalColCount = orig.colCount
+ tab.Entries = entries[:resultBottom]
+ tab.Bounds = bounds[:resultBottom]
+ tab.RowDisplacement = rowDisplacement
+
+ return nil
+}
diff --git a/src/urubu/driver/lexer/lexer.go b/src/urubu/driver/lexer/lexer.go
new file mode 100644
index 0000000..3f9712e
--- /dev/null
+++ b/src/urubu/driver/lexer/lexer.go
@@ -0,0 +1,335 @@
+package lexer
+
+import (
+ "fmt"
+ "io"
+)
+
+type ModeID int
+
+func (id ModeID) Int() int {
+ return int(id)
+}
+
+type StateID int
+
+func (id StateID) Int() int {
+ return int(id)
+}
+
+type KindID int
+
+func (id KindID) Int() int {
+ return int(id)
+}
+
+type ModeKindID int
+
+func (id ModeKindID) Int() int {
+ return int(id)
+}
+
+type LexSpec interface {
+ InitialMode() ModeID
+ Pop(mode ModeID, modeKind ModeKindID) bool
+ Push(mode ModeID, modeKind ModeKindID) (ModeID, bool)
+ ModeName(mode ModeID) string
+ InitialState(mode ModeID) StateID
+ NextState(mode ModeID, state StateID, v int) (StateID, bool)
+ Accept(mode ModeID, state StateID) (ModeKindID, bool)
+ KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string)
+}
+
+// Token representes a token.
+type Token struct {
+ // ModeID is an ID of a lex mode.
+ ModeID ModeID
+
+ // KindID is an ID of a kind. This is unique among all modes.
+ KindID KindID
+
+ // ModeKindID is an ID of a lexical kind. This is unique only within a mode.
+ // Note that you need to use KindID field if you want to identify a kind across all modes.
+ ModeKindID ModeKindID
+
+ // BytePos is a byte position where a token appears.
+ BytePos int
+
+ // ByteLen is a length of a token.
+ ByteLen int
+
+ // Row is a row number where a token appears.
+ Row int
+
+ // Col is a column number where a token appears.
+ // Note that Col is counted in code points, not bytes.
+ Col int
+
+ // Lexeme is a byte sequence matched a pattern of a lexical specification.
+ Lexeme []byte
+
+ // When this field is true, it means the token is the EOF token.
+ EOF bool
+
+ // When this field is true, it means the token is an error token.
+ Invalid bool
+}
+
+type LexerOption func(l *Lexer) error
+
+// DisableModeTransition disables the active mode transition. Thus, even if the lexical specification has the push and pop
+// operations, the lexer doesn't perform these operations. When the lexical specification has multiple modes, and this option is
+// enabled, you need to call the Lexer.Push and Lexer.Pop methods to perform the mode transition. You can use the Lexer.Mode method
+// to know the current lex mode.
+func DisableModeTransition() LexerOption {
+ return func(l *Lexer) error {
+ l.passiveModeTran = true
+ return nil
+ }
+}
+
+type lexerState struct {
+ srcPtr int
+ row int
+ col int
+}
+
+type Lexer struct {
+ spec LexSpec
+ src []byte
+ state lexerState
+ lastAcceptedState lexerState
+ tokBuf []*Token
+ modeStack []ModeID
+ passiveModeTran bool
+}
+
+// NewLexer returns a new lexer.
+func NewLexer(spec LexSpec, src io.Reader, opts ...LexerOption) (*Lexer, error) {
+ b, err := io.ReadAll(src)
+ if err != nil {
+ return nil, err
+ }
+ l := &Lexer{
+ spec: spec,
+ src: b,
+ state: lexerState{
+ srcPtr: 0,
+ row: 0,
+ col: 0,
+ },
+ lastAcceptedState: lexerState{
+ srcPtr: 0,
+ row: 0,
+ col: 0,
+ },
+ modeStack: []ModeID{
+ spec.InitialMode(),
+ },
+ passiveModeTran: false,
+ }
+ for _, opt := range opts {
+ err := opt(l)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return l, nil
+}
+
+// Next returns a next token.
+func (l *Lexer) Next() (*Token, error) {
+ if len(l.tokBuf) > 0 {
+ tok := l.tokBuf[0]
+ l.tokBuf = l.tokBuf[1:]
+ return tok, nil
+ }
+
+ tok, err := l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ return tok, nil
+ }
+ errTok := tok
+ for {
+ tok, err = l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ break
+ }
+ errTok.ByteLen += tok.ByteLen
+ errTok.Lexeme = append(errTok.Lexeme, tok.Lexeme...)
+ }
+ l.tokBuf = append(l.tokBuf, tok)
+
+ return errTok, nil
+}
+
+func (l *Lexer) nextAndTransition() (*Token, error) {
+ tok, err := l.next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.EOF || tok.Invalid {
+ return tok, nil
+ }
+ if l.passiveModeTran {
+ return tok, nil
+ }
+ mode := l.Mode()
+ if l.spec.Pop(mode, tok.ModeKindID) {
+ err := l.PopMode()
+ if err != nil {
+ return nil, err
+ }
+ }
+ if mode, ok := l.spec.Push(mode, tok.ModeKindID); ok {
+ l.PushMode(mode)
+ }
+ // The checking length of the mode stack must be at after pop and push operations because those operations can be performed
+ // at the same time. When the mode stack has just one element and popped it, the mode stack will be temporarily emptied.
+ // However, since a push operation may be performed immediately after it, the lexer allows the stack to be temporarily empty.
+ if len(l.modeStack) == 0 {
+ return nil, fmt.Errorf("a mode stack must have at least one element")
+ }
+ return tok, nil
+}
+
+func (l *Lexer) next() (*Token, error) {
+ mode := l.Mode()
+ state := l.spec.InitialState(mode)
+ buf := []byte{}
+ startPos := l.state.srcPtr
+ row := l.state.row
+ col := l.state.col
+ var tok *Token
+ for {
+ v, eof := l.read()
+ if eof {
+ if tok != nil {
+ l.revert()
+ return tok, nil
+ }
+ // When `buf` has unaccepted data and reads the EOF, the lexer treats the buffered data as an invalid token.
+ if len(buf) > 0 {
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ BytePos: startPos,
+ ByteLen: l.state.srcPtr - startPos,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ BytePos: startPos,
+ Row: row,
+ Col: col,
+ EOF: true,
+ }, nil
+ }
+ buf = append(buf, v)
+ nextState, ok := l.spec.NextState(mode, state, int(v))
+ if !ok {
+ if tok != nil {
+ l.revert()
+ return tok, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ BytePos: startPos,
+ ByteLen: l.state.srcPtr - startPos,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ state = nextState
+ if modeKindID, ok := l.spec.Accept(mode, state); ok {
+ kindID, _ := l.spec.KindIDAndName(mode, modeKindID)
+ tok = &Token{
+ ModeID: mode,
+ KindID: kindID,
+ ModeKindID: modeKindID,
+ BytePos: startPos,
+ ByteLen: l.state.srcPtr - startPos,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ }
+ l.accept()
+ }
+ }
+}
+
+// Mode returns the current lex mode.
+func (l *Lexer) Mode() ModeID {
+ return l.modeStack[len(l.modeStack)-1]
+}
+
+// PushMode adds a lex mode onto the mode stack.
+func (l *Lexer) PushMode(mode ModeID) {
+ l.modeStack = append(l.modeStack, mode)
+}
+
+// PopMode removes a lex mode from the top of the mode stack.
+func (l *Lexer) PopMode() error {
+ sLen := len(l.modeStack)
+ if sLen == 0 {
+ return fmt.Errorf("cannot pop a lex mode from a lex mode stack any more")
+ }
+ l.modeStack = l.modeStack[:sLen-1]
+ return nil
+}
+
+func (l *Lexer) read() (byte, bool) {
+ if l.state.srcPtr >= len(l.src) {
+ return 0, true
+ }
+
+ b := l.src[l.state.srcPtr]
+ l.state.srcPtr++
+
+ // Count the token positions.
+ // The driver treats LF as the end of lines and counts columns in code points, not bytes.
+ // To count in code points, we refer to the First Byte column in the Table 3-6.
+ //
+ // Reference:
+ // - [Table 3-6] https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf > Table 3-6. UTF-8 Bit Distribution
+ if b < 128 {
+ // 0x0A is LF.
+ if b == 0x0A {
+ l.state.row++
+ l.state.col = 0
+ } else {
+ l.state.col++
+ }
+ } else if b>>5 == 6 || b>>4 == 14 || b>>3 == 30 {
+ l.state.col++
+ }
+
+ return b, false
+}
+
+// accept saves the current state.
+func (l *Lexer) accept() {
+ l.lastAcceptedState = l.state
+}
+
+// revert reverts the lexer state to the last accepted state.
+//
+// We must not call this function consecutively.
+func (l *Lexer) revert() {
+ l.state = l.lastAcceptedState
+}
diff --git a/src/urubu/driver/lexer/spec.go b/src/urubu/driver/lexer/spec.go
new file mode 100644
index 0000000..75c74af
--- /dev/null
+++ b/src/urubu/driver/lexer/spec.go
@@ -0,0 +1,71 @@
+package lexer
+
+import spec "urubu/spec/grammar"
+
+type lexSpec struct {
+ spec *spec.LexicalSpec
+}
+
+func NewLexSpec(spec *spec.LexicalSpec) *lexSpec {
+ return &lexSpec{
+ spec: spec,
+ }
+}
+
+func (s *lexSpec) InitialMode() ModeID {
+ return ModeID(s.spec.InitialModeID.Int())
+}
+
+func (s *lexSpec) Pop(mode ModeID, modeKind ModeKindID) bool {
+ return s.spec.Specs[mode].Pop[modeKind] == 1
+}
+
+func (s *lexSpec) Push(mode ModeID, modeKind ModeKindID) (ModeID, bool) {
+ modeID := s.spec.Specs[mode].Push[modeKind]
+ return ModeID(modeID.Int()), !modeID.IsNil()
+}
+
+func (s *lexSpec) ModeName(mode ModeID) string {
+ return s.spec.ModeNames[mode].String()
+}
+
+func (s *lexSpec) InitialState(mode ModeID) StateID {
+ return StateID(s.spec.Specs[mode].DFA.InitialStateID.Int())
+}
+
+func (s *lexSpec) NextState(mode ModeID, state StateID, v int) (StateID, bool) {
+ switch s.spec.CompressionLevel {
+ case 2:
+ tran := s.spec.Specs[mode].DFA.Transition
+ rowNum := tran.RowNums[state]
+ d := tran.UniqueEntries.RowDisplacement[rowNum]
+ if tran.UniqueEntries.Bounds[d+v] != rowNum {
+ return StateID(tran.UniqueEntries.EmptyValue.Int()), false
+ }
+ return StateID(tran.UniqueEntries.Entries[d+v].Int()), true
+ case 1:
+ tran := s.spec.Specs[mode].DFA.Transition
+ next := tran.UncompressedUniqueEntries[tran.RowNums[state]*tran.OriginalColCount+v]
+ if next == spec.StateIDNil {
+ return StateID(spec.StateIDNil.Int()), false
+ }
+ return StateID(next.Int()), true
+ }
+
+ modeSpec := s.spec.Specs[mode]
+ next := modeSpec.DFA.UncompressedTransition[state.Int()*modeSpec.DFA.ColCount+v]
+ if next == spec.StateIDNil {
+ return StateID(spec.StateIDNil), false
+ }
+ return StateID(next.Int()), true
+}
+
+func (s *lexSpec) Accept(mode ModeID, state StateID) (ModeKindID, bool) {
+ modeKindID := s.spec.Specs[mode].DFA.AcceptingStates[state]
+ return ModeKindID(modeKindID.Int()), modeKindID != spec.LexModeKindIDNil
+}
+
+func (s *lexSpec) KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string) {
+ kindID := s.spec.KindIDs[mode][modeKind]
+ return KindID(kindID.Int()), s.spec.KindNames[kindID].String()
+}
diff --git a/src/urubu/driver/lexer/template.go b/src/urubu/driver/lexer/template.go
new file mode 100644
index 0000000..35dfd93
--- /dev/null
+++ b/src/urubu/driver/lexer/template.go
@@ -0,0 +1,760 @@
+package lexer
+
+import (
+ "bytes"
+ _ "embed"
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "strings"
+ "text/template"
+
+ "urubu/grammar/lexical"
+ spec "urubu/spec/grammar"
+)
+
+// go:embed lexer.go
+var lexerCoreSrc string
+
+func GenLexer(lexSpec *spec.LexicalSpec, pkgName string) ([]byte, error) {
+ var lexerSrc string
+ {
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "lexer.go", lexerCoreSrc, parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = format.Node(&b, fset, f)
+ if err != nil {
+ return nil, err
+ }
+
+ lexerSrc = b.String()
+ }
+
+ var modeIDsSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "const (\n")
+ for i, k := range lexSpec.ModeNames {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, " ModeIDNil ModeID = %v\n", i)
+ continue
+ }
+ fmt.Fprintf(&b, " ModeID%v ModeID = %v\n", lexical.SnakeCaseToUpperCamelCase(k.String()), i)
+ }
+ fmt.Fprintf(&b, ")")
+
+ modeIDsSrc = b.String()
+ }
+
+ var modeNamesSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "const (\n")
+ for i, k := range lexSpec.ModeNames {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, " ModeNameNil = %#v\n", "")
+ continue
+ }
+ fmt.Fprintf(&b, " ModeName%v = %#v\n", lexical.SnakeCaseToUpperCamelCase(k.String()), k)
+ }
+ fmt.Fprintf(&b, ")")
+
+ modeNamesSrc = b.String()
+ }
+
+ var modeIDToNameSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, `
+// ModeIDToName converts a mode ID to a name.
+func ModeIDToName(id ModeID) string {
+ switch id {`)
+ for i, k := range lexSpec.ModeNames {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, `
+ case ModeIDNil:
+ return ModeNameNil`)
+ continue
+ }
+ name := lexical.SnakeCaseToUpperCamelCase(k.String())
+ fmt.Fprintf(&b, `
+ case ModeID%v:
+ return ModeName%v`, name, name)
+ }
+ fmt.Fprintf(&b, `
+ }
+ return ""
+}
+`)
+
+ modeIDToNameSrc = b.String()
+ }
+
+ var kindIDsSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "const (\n")
+ for i, k := range lexSpec.KindNames {
+ if i == spec.LexKindIDNil.Int() {
+ fmt.Fprintf(&b, " KindIDNil KindID = %v\n", i)
+ continue
+ }
+ fmt.Fprintf(&b, " KindID%v KindID = %v\n", lexical.SnakeCaseToUpperCamelCase(k.String()), i)
+ }
+ fmt.Fprintf(&b, ")")
+
+ kindIDsSrc = b.String()
+ }
+
+ var kindNamesSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "const (\n")
+ fmt.Fprintf(&b, " KindNameNil = %#v\n", "")
+ for _, k := range lexSpec.KindNames[1:] {
+ fmt.Fprintf(&b, " KindName%v = %#v\n", lexical.SnakeCaseToUpperCamelCase(k.String()), k)
+ }
+ fmt.Fprintf(&b, ")")
+
+ kindNamesSrc = b.String()
+ }
+
+ var kindIDToNameSrc string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, `
+// KindIDToName converts a kind ID to a name.
+func KindIDToName(id KindID) string {
+ switch id {`)
+ for i, k := range lexSpec.KindNames {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, `
+ case KindIDNil:
+ return KindNameNil`)
+ continue
+ }
+ name := lexical.SnakeCaseToUpperCamelCase(k.String())
+ fmt.Fprintf(&b, `
+ case KindID%v:
+ return KindName%v`, name, name)
+ }
+ fmt.Fprintf(&b, `
+ }
+ return ""
+}
+`)
+
+ kindIDToNameSrc = b.String()
+ }
+
+ var specSrc string
+ {
+ t, err := template.New("").Funcs(genTemplateFuncs(lexSpec)).Parse(lexSpecTemplate)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, map[string]interface{}{
+ "initialModeID": "ModeID" + lexical.SnakeCaseToUpperCamelCase(lexSpec.ModeNames[lexSpec.InitialModeID].String()),
+ "modeIDNil": "ModeIDNil",
+ "modeKindIDNil": spec.LexModeKindIDNil,
+ "stateIDNil": spec.StateIDNil,
+ "compressionLevel": lexSpec.CompressionLevel,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ specSrc = b.String()
+ }
+
+ var src string
+ {
+ tmpl := `// Code generated by vartan-go. DO NOT EDIT.
+{{ .lexerSrc }}
+
+{{ .modeIDsSrc }}
+
+{{ .modeNamesSrc }}
+
+{{ .modeIDToNameSrc }}
+
+{{ .kindIDsSrc }}
+
+{{ .kindNamesSrc }}
+
+{{ .kindIDToNameSrc }}
+
+{{ .specSrc }}
+`
+
+ t, err := template.New("").Parse(tmpl)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, map[string]string{
+ "lexerSrc": lexerSrc,
+ "modeIDsSrc": modeIDsSrc,
+ "modeNamesSrc": modeNamesSrc,
+ "modeIDToNameSrc": modeIDToNameSrc,
+ "kindIDsSrc": kindIDsSrc,
+ "kindNamesSrc": kindNamesSrc,
+ "kindIDToNameSrc": kindIDToNameSrc,
+ "specSrc": specSrc,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ src = b.String()
+ }
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+
+ f.Name = ast.NewIdent(pkgName)
+
+ var b bytes.Buffer
+ err = format.Node(&b, fset, f)
+ if err != nil {
+ return nil, err
+ }
+
+ return b.Bytes(), nil
+}
+
+const lexSpecTemplate = `
+type lexSpec struct {
+ pop [][]bool
+ push [][]ModeID
+ modeNames []string
+ initialStates []StateID
+ acceptances [][]ModeKindID
+ kindIDs [][]KindID
+ kindNames []string
+ initialModeID ModeID
+ modeIDNil ModeID
+ modeKindIDNil ModeKindID
+ stateIDNil StateID
+
+ rowNums [][]int
+ rowDisplacements [][]int
+ bounds [][]int
+ entries [][]StateID
+ originalColCounts []int
+}
+
+func NewLexSpec() *lexSpec {
+ return &lexSpec{
+ pop: {{ genPopTable }},
+ push: {{ genPushTable }},
+ modeNames: {{ genModeNameTable }},
+ initialStates: {{ genInitialStateTable }},
+ acceptances: {{ genAcceptTable }},
+ kindIDs: {{ genKindIDTable }},
+ kindNames: {{ genKindNameTable }},
+ initialModeID: {{ .initialModeID }},
+ modeIDNil: {{ .modeIDNil }},
+ modeKindIDNil: {{ .modeKindIDNil }},
+ stateIDNil: {{ .stateIDNil }},
+
+ rowNums: {{ genRowNums }},
+ rowDisplacements: {{ genRowDisplacements }},
+ bounds: {{ genBounds }},
+ entries: {{ genEntries }},
+ originalColCounts: {{ genOriginalColCounts }},
+ }
+}
+
+func (s *lexSpec) InitialMode() ModeID {
+ return s.initialModeID
+}
+
+func (s *lexSpec) Pop(mode ModeID, modeKind ModeKindID) bool {
+ return s.pop[mode][modeKind]
+}
+
+func (s *lexSpec) Push(mode ModeID, modeKind ModeKindID) (ModeID, bool) {
+ id := s.push[mode][modeKind]
+ return id, id != s.modeIDNil
+}
+
+func (s *lexSpec) ModeName(mode ModeID) string {
+ return s.modeNames[mode]
+}
+
+func (s *lexSpec) InitialState(mode ModeID) StateID {
+ return s.initialStates[mode]
+}
+
+func (s *lexSpec) NextState(mode ModeID, state StateID, v int) (StateID, bool) {
+{{ if eq .compressionLevel 2 -}}
+ rowNum := s.rowNums[mode][state]
+ d := s.rowDisplacements[mode][rowNum]
+ if s.bounds[mode][d+v] != rowNum {
+ return s.stateIDNil, false
+ }
+ return s.entries[mode][d+v], true
+{{ else if eq .compressionLevel 1 -}}
+ rowNum := s.rowNums[mode][state]
+ colCount := s.originalColCounts[mode]
+ next := s.entries[mode][rowNum*colCount+v]
+ if next == s.stateIDNil {
+ return s.stateIDNil, false
+ }
+ return next, true
+{{ else -}}
+ colCount := s.originalColCounts[mode]
+ next := s.entries[mode][int(state)*colCount+v]
+ if next == s.stateIDNil {
+ return s.stateIDNil, false
+ }
+ return next, true
+{{ end -}}
+}
+
+func (s *lexSpec) Accept(mode ModeID, state StateID) (ModeKindID, bool) {
+ id := s.acceptances[mode][state]
+ return id, id != s.modeKindIDNil
+}
+
+func (s *lexSpec) KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string) {
+ id := s.kindIDs[mode][modeKind]
+ return id, s.kindNames[id]
+}
+`
+
+func genTemplateFuncs(lexSpec *spec.LexicalSpec) template.FuncMap {
+ fns := template.FuncMap{
+ "genPopTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]bool{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.Pop {
+ fmt.Fprintf(&b, "%v, ", v != 0)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genPushTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]ModeID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.Push {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genModeNameTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]string{\n")
+ for i, name := range lexSpec.ModeNames {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "ModeNameNil,\n")
+ continue
+ }
+ fmt.Fprintf(&b, "ModeName%v,\n", lexical.SnakeCaseToUpperCamelCase(name.String()))
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genInitialStateTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]StateID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "%v,\n", spec.StateIDNil)
+ continue
+ }
+
+ fmt.Fprintf(&b, "%v,\n", s.DFA.InitialStateID)
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genAcceptTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]ModeKindID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.AcceptingStates {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genKindIDTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]KindID{\n")
+ for i, ids := range lexSpec.KindIDs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ fmt.Fprintf(&b, "{\n")
+ for j, id := range ids {
+ if j == spec.LexModeKindIDNil.Int() {
+ fmt.Fprintf(&b, "KindIDNil,\n")
+ continue
+ }
+ fmt.Fprintf(&b, "KindID%v,\n", lexical.SnakeCaseToUpperCamelCase(string(lexSpec.KindNames[id].String())))
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genKindNameTable": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]string{\n")
+ for i, name := range lexSpec.KindNames {
+ if i == spec.LexKindIDNil.Int() {
+ fmt.Fprintf(&b, "KindNameNil,\n")
+ continue
+ }
+ fmt.Fprintf(&b, "KindName%v,\n", lexical.SnakeCaseToUpperCamelCase(name.String()))
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ }
+
+ switch lexSpec.CompressionLevel {
+ case 2:
+ fns["genRowNums"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.Transition.RowNums {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genRowDisplacements"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, d := range s.DFA.Transition.UniqueEntries.RowDisplacement {
+ fmt.Fprintf(&b, "%v,", d)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genBounds"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.Transition.UniqueEntries.Bounds {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genEntries"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]StateID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.Transition.UniqueEntries.Entries {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genOriginalColCounts"] = func() string {
+ return "nil"
+ }
+ case 1:
+ fns["genRowNums"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.Transition.RowNums {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genRowDisplacements"] = func() string {
+ return "nil"
+ }
+
+ fns["genBounds"] = func() string {
+ return "nil"
+ }
+
+ fns["genEntries"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]StateID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.Transition.UncompressedUniqueEntries {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genOriginalColCounts"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "0,\n")
+ continue
+ }
+
+ fmt.Fprintf(&b, "%v,\n", s.DFA.Transition.OriginalColCount)
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+ default:
+ fns["genRowNums"] = func() string {
+ return "nil"
+ }
+
+ fns["genRowDisplacements"] = func() string {
+ return "nil"
+ }
+
+ fns["genBounds"] = func() string {
+ return "nil"
+ }
+
+ fns["genEntries"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]StateID{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ c := 1
+ fmt.Fprintf(&b, "{\n")
+ for _, v := range s.DFA.UncompressedTransition {
+ fmt.Fprintf(&b, "%v,", v)
+
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+
+ fns["genOriginalColCounts"] = func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ for i, s := range lexSpec.Specs {
+ if i == spec.LexModeIDNil.Int() {
+ fmt.Fprintf(&b, "0,\n")
+ continue
+ }
+
+ fmt.Fprintf(&b, "%v,\n", s.DFA.ColCount)
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ }
+ }
+
+ return fns
+}
diff --git a/src/urubu/driver/parser/parser.go b/src/urubu/driver/parser/parser.go
new file mode 100644
index 0000000..2eaa678
--- /dev/null
+++ b/src/urubu/driver/parser/parser.go
@@ -0,0 +1,416 @@
+package parser
+
+import (
+ "fmt"
+)
+
+type Grammar interface {
+ // InitialState returns the initial state of a parser.
+ InitialState() int
+
+ // StartProduction returns the start production of grammar.
+ StartProduction() int
+
+ // Action returns an ACTION entry corresponding to a (state, terminal symbol) pair.
+ Action(state int, terminal int) int
+
+ // GoTo returns a GOTO entry corresponding to a (state, non-terminal symbol) pair.
+ GoTo(state int, lhs int) int
+
+ // ErrorTrapperState returns true when a state can shift the error symbol.
+ ErrorTrapperState(state int) bool
+
+ // LHS returns a LHS symbol of a production.
+ LHS(prod int) int
+
+ // AlternativeSymbolCount returns a symbol count of p production.
+ AlternativeSymbolCount(prod int) int
+
+ // RecoverProduction returns true when a production has the recover directive.
+ RecoverProduction(prod int) bool
+
+ // NonTerminal retuns a string representaion of a non-terminal symbol.
+ NonTerminal(nonTerminal int) string
+
+ // TerminalCount returns a terminal symbol count of grammar.
+ TerminalCount() int
+
+ // SkipTerminal returns true when a terminal symbol must be skipped on syntax analysis.
+ SkipTerminal(terminal int) bool
+
+ // EOF returns the EOF symbol.
+ EOF() int
+
+ // Error returns the error symbol.
+ Error() int
+
+ // Terminal retuns a string representaion of a terminal symbol.
+ Terminal(terminal int) string
+
+ // ASTAction returns an AST action entries.
+ ASTAction(prod int) []int
+}
+
+type VToken interface {
+ // TerminalID returns a terminal ID.
+ TerminalID() int
+
+ // Lexeme returns a lexeme.
+ Lexeme() []byte
+
+ // EOF returns true when a token represents EOF.
+ EOF() bool
+
+ // Invalid returns true when a token is invalid.
+ Invalid() bool
+
+ // BytePosition returns (position, length) pair.
+ // `position` is a byte position where a token appears and `length` is a length in bytes.
+ BytePosition() (int, int)
+
+ // Position returns (row, column) pair.
+ Position() (int, int)
+}
+
+type TokenStream interface {
+ Next() (VToken, error)
+}
+
+type SyntaxError struct {
+ Row int
+ Col int
+ Message string
+ Token VToken
+ ExpectedTerminals []string
+}
+
+type ParserOption func(p *Parser) error
+
+// DisableLAC disables LAC (lookahead correction). LAC is enabled by default.
+func DisableLAC() ParserOption {
+ return func(p *Parser) error {
+ p.disableLAC = true
+ return nil
+ }
+}
+
+func SemanticAction(semAct SemanticActionSet) ParserOption {
+ return func(p *Parser) error {
+ p.semAct = semAct
+ return nil
+ }
+}
+
+type Parser struct {
+ toks TokenStream
+ gram Grammar
+ stateStack *stateStack
+ semAct SemanticActionSet
+ disableLAC bool
+ onError bool
+ shiftCount int
+ synErrs []*SyntaxError
+}
+
+func NewParser(toks TokenStream, gram Grammar, opts ...ParserOption) (*Parser, error) {
+ p := &Parser{
+ toks: toks,
+ gram: gram,
+ stateStack: &stateStack{},
+ }
+
+ for _, opt := range opts {
+ err := opt(p)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return p, nil
+}
+
+func (p *Parser) Parse() error {
+ p.stateStack.push(p.gram.InitialState())
+ tok, err := p.nextToken()
+ if err != nil {
+ return err
+ }
+
+ACTION_LOOP:
+ for {
+ act := p.lookupAction(tok)
+
+ switch {
+ case act < 0: // Shift
+ nextState := act * -1
+
+ recovered := false
+ if p.onError {
+ p.shiftCount++
+
+ // When the parser performs shift three times, the parser recovers from the error state.
+ if p.shiftCount >= 3 {
+ p.onError = false
+ p.shiftCount = 0
+ recovered = true
+ }
+ }
+
+ p.shift(nextState)
+
+ if p.semAct != nil {
+ p.semAct.Shift(tok, recovered)
+ }
+
+ tok, err = p.nextToken()
+ if err != nil {
+ return err
+ }
+ case act > 0: // Reduce
+ prodNum := act
+
+ recovered := false
+ if p.onError && p.gram.RecoverProduction(prodNum) {
+ p.onError = false
+ p.shiftCount = 0
+ recovered = true
+ }
+
+ accepted := p.reduce(prodNum)
+ if accepted {
+ if p.semAct != nil {
+ p.semAct.Accept()
+ }
+
+ return nil
+ }
+
+ if p.semAct != nil {
+ p.semAct.Reduce(prodNum, recovered)
+ }
+ default: // Error
+ if p.onError {
+ tok, err = p.nextToken()
+ if err != nil {
+ return err
+ }
+ if tok.EOF() {
+ if p.semAct != nil {
+ p.semAct.MissError(tok)
+ }
+
+ return nil
+ }
+
+ continue ACTION_LOOP
+ }
+
+ row, col := tok.Position()
+ p.synErrs = append(p.synErrs, &SyntaxError{
+ Row: row,
+ Col: col,
+ Message: "unexpected token",
+ Token: tok,
+ ExpectedTerminals: p.searchLookahead(p.stateStack.top()),
+ })
+
+ count, ok := p.trapError()
+ if !ok {
+ if p.semAct != nil {
+ p.semAct.MissError(tok)
+ }
+
+ return nil
+ }
+
+ p.onError = true
+ p.shiftCount = 0
+
+ act, err := p.lookupActionOnError()
+ if err != nil {
+ return err
+ }
+
+ p.shift(act * -1)
+
+ if p.semAct != nil {
+ p.semAct.TrapAndShiftError(tok, count)
+ }
+ }
+ }
+}
+
+// validateLookahead validates whether `term` is a valid lookahead in the current context. When `term` is valid,
+// this method returns `true`.
+func (p *Parser) validateLookahead(term int) bool {
+ p.stateStack.enableExploratoryMode()
+ defer p.stateStack.disableExploratoryMode()
+
+ for {
+ act := p.gram.Action(p.stateStack.topExploratorily(), term)
+
+ switch {
+ case act < 0: // Shift
+ return true
+ case act > 0: // Reduce
+ prodNum := act
+
+ lhs := p.gram.LHS(prodNum)
+ if lhs == p.gram.LHS(p.gram.StartProduction()) {
+ return true
+ }
+ n := p.gram.AlternativeSymbolCount(prodNum)
+ p.stateStack.popExploratorily(n)
+ state := p.gram.GoTo(p.stateStack.topExploratorily(), lhs)
+ p.stateStack.pushExploratorily(state)
+ default: // Error
+ return false
+ }
+ }
+}
+
+func (p *Parser) nextToken() (VToken, error) {
+ for {
+ // We don't have to check whether the token is invalid because the kind ID of the invalid token is 0,
+ // and the parsing table doesn't have an entry corresponding to the kind ID 0. Thus we can detect
+ // a syntax error because the parser cannot find an entry corresponding to the invalid token.
+ tok, err := p.toks.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.gram.SkipTerminal(tok.TerminalID()) {
+ continue
+ }
+
+ return tok, nil
+ }
+}
+
+func (p *Parser) tokenToTerminal(tok VToken) int {
+ if tok.EOF() {
+ return p.gram.EOF()
+ }
+
+ return tok.TerminalID()
+}
+
+func (p *Parser) lookupAction(tok VToken) int {
+ if !p.disableLAC {
+ term := p.tokenToTerminal(tok)
+ if !p.validateLookahead(term) {
+ return 0
+ }
+ }
+
+ return p.gram.Action(p.stateStack.top(), p.tokenToTerminal(tok))
+}
+
+func (p *Parser) lookupActionOnError() (int, error) {
+ act := p.gram.Action(p.stateStack.top(), p.gram.Error())
+ if act >= 0 {
+ return 0, fmt.Errorf("an entry must be a shift action by the error symbol; entry: %v, state: %v, symbol: %v", act, p.stateStack.top(), p.gram.Terminal(p.gram.Error()))
+ }
+
+ return act, nil
+}
+
+func (p *Parser) shift(nextState int) {
+ p.stateStack.push(nextState)
+}
+
+func (p *Parser) reduce(prodNum int) bool {
+ lhs := p.gram.LHS(prodNum)
+ if lhs == p.gram.LHS(p.gram.StartProduction()) {
+ return true
+ }
+ n := p.gram.AlternativeSymbolCount(prodNum)
+ p.stateStack.pop(n)
+ nextState := p.gram.GoTo(p.stateStack.top(), lhs)
+ p.stateStack.push(nextState)
+ return false
+}
+
+func (p *Parser) trapError() (int, bool) {
+ count := 0
+ for {
+ if p.gram.ErrorTrapperState(p.stateStack.top()) {
+ return count, true
+ }
+
+ if p.stateStack.top() != p.gram.InitialState() {
+ p.stateStack.pop(1)
+ count++
+ } else {
+ return 0, false
+ }
+ }
+}
+
+func (p *Parser) SyntaxErrors() []*SyntaxError {
+ return p.synErrs
+}
+
+func (p *Parser) searchLookahead(state int) []string {
+ kinds := []string{}
+ termCount := p.gram.TerminalCount()
+ for term := 0; term < termCount; term++ {
+ if p.disableLAC {
+ if p.gram.Action(p.stateStack.top(), term) == 0 {
+ continue
+ }
+ } else {
+ if !p.validateLookahead(term) {
+ continue
+ }
+ }
+
+ // We don't add the error symbol to the look-ahead symbols because users cannot input the error symbol
+ // intentionally.
+ if term == p.gram.Error() {
+ continue
+ }
+
+ kinds = append(kinds, p.gram.Terminal(term))
+ }
+
+ return kinds
+}
+
+type stateStack struct {
+ items []int
+ itemsExp []int
+}
+
+func (s *stateStack) enableExploratoryMode() {
+ s.itemsExp = make([]int, len(s.items))
+ copy(s.itemsExp, s.items)
+}
+
+func (s *stateStack) disableExploratoryMode() {
+ s.itemsExp = nil
+}
+
+func (s *stateStack) top() int {
+ return s.items[len(s.items)-1]
+}
+
+func (s *stateStack) topExploratorily() int {
+ return s.itemsExp[len(s.itemsExp)-1]
+}
+
+func (s *stateStack) push(state int) {
+ s.items = append(s.items, state)
+}
+
+func (s *stateStack) pushExploratorily(state int) {
+ s.itemsExp = append(s.itemsExp, state)
+}
+
+func (s *stateStack) pop(n int) {
+ s.items = s.items[:len(s.items)-n]
+}
+
+func (s *stateStack) popExploratorily(n int) {
+ s.itemsExp = s.itemsExp[:len(s.itemsExp)-n]
+}
diff --git a/src/urubu/driver/parser/semantic_action.go b/src/urubu/driver/parser/semantic_action.go
new file mode 100644
index 0000000..6bb78cf
--- /dev/null
+++ b/src/urubu/driver/parser/semantic_action.go
@@ -0,0 +1,371 @@
+package parser
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+// SemanticActionSet is a set of semantic actions a parser calls.
+type SemanticActionSet interface {
+ // Shift runs when the parser shifts a symbol onto a state stack. `tok` is a token corresponding to the symbol.
+ // When the parser recovered from an error state by shifting the token, `recovered` is true.
+ Shift(tok VToken, recovered bool)
+
+ // Reduce runs when the parser reduces an RHS of a production to its LHS. `prodNum` is a number of the production.
+ // When the parser recovered from an error state by reducing the production, `recovered` is true.
+ Reduce(prodNum int, recovered bool)
+
+ // Accept runs when the parser accepts an input.
+ Accept()
+
+ // TrapAndShiftError runs when the parser traps a syntax error and shifts a error symbol onto the state stack.
+ // `cause` is a token that caused a syntax error. `popped` is the number of frames that the parser discards
+ // from the state stack.
+ // Unlike `Shift` function, this function doesn't take a token to be shifted as an argument because a token
+ // corresponding to the error symbol doesn't exist.
+ TrapAndShiftError(cause VToken, popped int)
+
+ // MissError runs when the parser fails to trap a syntax error. `cause` is a token that caused a syntax error.
+ MissError(cause VToken)
+}
+
+var _ SemanticActionSet = &SyntaxTreeActionSet{}
+
+// SyntaxTreeNode is a node of a syntax tree. A node type used in SyntaxTreeActionSet must implement SyntaxTreeNode interface.
+type SyntaxTreeNode interface {
+ // ChildCount returns a child count of a node. A parser calls this method to know the child count to be expanded by an `#ast`
+ // directive with `...` operator.
+ ChildCount() int
+
+ // ExpandChildren returns children of a node. A parser calls this method to fetch the children to be expanded by an `#ast`
+ // directive with `...` operator.
+ ExpandChildren() []SyntaxTreeNode
+}
+
+var _ SyntaxTreeNode = &Node{}
+
+// SyntaxTreeBuilder allows you to construct a syntax tree containing arbitrary user-defined node types.
+// The parser uses SyntaxTreeBuilder interface as a part of semantic actions via SyntaxTreeActionSet interface.
+type SyntaxTreeBuilder interface {
+ Shift(kindName string, tok VToken) SyntaxTreeNode
+ ShiftError(kindName string) SyntaxTreeNode
+ Reduce(kindName string, children []SyntaxTreeNode) SyntaxTreeNode
+ Accept(f SyntaxTreeNode)
+}
+
+var _ SyntaxTreeBuilder = &DefaultSyntaxTreeBuilder{}
+
+// DefaultSyntaxTreeBuilder is a implementation of SyntaxTreeBuilder.
+type DefaultSyntaxTreeBuilder struct {
+ tree *Node
+}
+
+// NewDefaultSyntaxTreeBuilder returns a new DefaultSyntaxTreeBuilder.
+func NewDefaultSyntaxTreeBuilder() *DefaultSyntaxTreeBuilder {
+ return &DefaultSyntaxTreeBuilder{}
+}
+
+// Shift is a implementation of SyntaxTreeBuilder.Shift.
+func (b *DefaultSyntaxTreeBuilder) Shift(kindName string, tok VToken) SyntaxTreeNode {
+ bytePos, byteLen := tok.BytePosition()
+ row, col := tok.Position()
+ return &Node{
+ Type: NodeTypeTerminal,
+ KindName: kindName,
+ Text: string(tok.Lexeme()),
+ BytePos: bytePos,
+ ByteLen: byteLen,
+ Row: row,
+ Col: col,
+ }
+}
+
+// ShiftError is a implementation of SyntaxTreeBuilder.ShiftError.
+func (b *DefaultSyntaxTreeBuilder) ShiftError(kindName string) SyntaxTreeNode {
+ return &Node{
+ Type: NodeTypeError,
+ KindName: kindName,
+ }
+}
+
+// Reduce is a implementation of SyntaxTreeBuilder.Reduce.
+func (b *DefaultSyntaxTreeBuilder) Reduce(kindName string, children []SyntaxTreeNode) SyntaxTreeNode {
+ cNodes := make([]*Node, len(children))
+ for i, c := range children {
+ cNodes[i] = c.(*Node)
+ }
+ return &Node{
+ Type: NodeTypeNonTerminal,
+ KindName: kindName,
+ Children: cNodes,
+ }
+}
+
+// Accept is a implementation of SyntaxTreeBuilder.Accept.
+func (b *DefaultSyntaxTreeBuilder) Accept(f SyntaxTreeNode) {
+ b.tree = f.(*Node)
+}
+
+// Tree returns a syntax tree when the parser has accepted an input. If a syntax error occurs, the return value is nil.
+func (b *DefaultSyntaxTreeBuilder) Tree() *Node {
+ return b.tree
+}
+
+// SyntaxTreeActionSet is a implementation of SemanticActionSet interface and constructs a syntax tree.
+type SyntaxTreeActionSet struct {
+ gram Grammar
+ builder SyntaxTreeBuilder
+ semStack *semanticStack
+ disableASTAction bool
+}
+
+// NewASTActionSet returns a new SyntaxTreeActionSet that constructs an AST (Abstract Syntax Tree).
+// When grammar `gram` contains `#ast` directives, the new SyntaxTreeActionSet this function returns interprets them.
+func NewASTActionSet(gram Grammar, builder SyntaxTreeBuilder) *SyntaxTreeActionSet {
+ return &SyntaxTreeActionSet{
+ gram: gram,
+ builder: builder,
+ semStack: newSemanticStack(),
+ }
+}
+
+// NewCSTTActionSet returns a new SyntaxTreeActionSet that constructs a CST (Concrete Syntax Tree).
+// Even if grammar `gram` contains `#ast` directives, the new SyntaxTreeActionSet this function returns ignores them.
+func NewCSTActionSet(gram Grammar, builder SyntaxTreeBuilder) *SyntaxTreeActionSet {
+ return &SyntaxTreeActionSet{
+ gram: gram,
+ builder: builder,
+ semStack: newSemanticStack(),
+ disableASTAction: true,
+ }
+}
+
+// Shift is a implementation of SemanticActionSet.Shift method.
+func (a *SyntaxTreeActionSet) Shift(tok VToken, recovered bool) {
+ term := a.tokenToTerminal(tok)
+ a.semStack.push(a.builder.Shift(a.gram.Terminal(term), tok))
+}
+
+// Reduce is a implementation of SemanticActionSet.Reduce method.
+func (a *SyntaxTreeActionSet) Reduce(prodNum int, recovered bool) {
+ lhs := a.gram.LHS(prodNum)
+
+ // When an alternative is empty, `n` will be 0, and `handle` will be empty slice.
+ n := a.gram.AlternativeSymbolCount(prodNum)
+ handle := a.semStack.pop(n)
+
+ var astAct []int
+ if !a.disableASTAction {
+ astAct = a.gram.ASTAction(prodNum)
+ }
+ var children []SyntaxTreeNode
+ if astAct != nil {
+ // Count the number of children in advance to avoid frequent growth in a slice for children.
+ {
+ l := 0
+ for _, e := range astAct {
+ if e > 0 {
+ l++
+ } else {
+ offset := e*-1 - 1
+ l += handle[offset].ChildCount()
+ }
+ }
+
+ children = make([]SyntaxTreeNode, l)
+ }
+
+ p := 0
+ for _, e := range astAct {
+ if e > 0 {
+ offset := e - 1
+ children[p] = handle[offset]
+ p++
+ } else {
+ offset := e*-1 - 1
+ for _, c := range handle[offset].ExpandChildren() {
+ children[p] = c
+ p++
+ }
+ }
+ }
+ } else {
+ // If an alternative has no AST action, a driver generates
+ // a node with the same structure as a CST.
+ children = handle
+ }
+
+ a.semStack.push(a.builder.Reduce(a.gram.NonTerminal(lhs), children))
+}
+
+// Accept is a implementation of SemanticActionSet.Accept method.
+func (a *SyntaxTreeActionSet) Accept() {
+ top := a.semStack.pop(1)
+ a.builder.Accept(top[0])
+}
+
+// TrapAndShiftError is a implementation of SemanticActionSet.TrapAndShiftError method.
+func (a *SyntaxTreeActionSet) TrapAndShiftError(cause VToken, popped int) {
+ a.semStack.pop(popped)
+ a.semStack.push(a.builder.ShiftError(a.gram.Terminal(a.gram.Error())))
+}
+
+// MissError is a implementation of SemanticActionSet.MissError method.
+func (a *SyntaxTreeActionSet) MissError(cause VToken) {
+}
+
+func (a *SyntaxTreeActionSet) tokenToTerminal(tok VToken) int {
+ if tok.EOF() {
+ return a.gram.EOF()
+ }
+
+ return tok.TerminalID()
+}
+
+type semanticStack struct {
+ frames []SyntaxTreeNode
+}
+
+func newSemanticStack() *semanticStack {
+ return &semanticStack{
+ frames: make([]SyntaxTreeNode, 0, 100),
+ }
+}
+
+func (s *semanticStack) push(f SyntaxTreeNode) {
+ s.frames = append(s.frames, f)
+}
+
+func (s *semanticStack) pop(n int) []SyntaxTreeNode {
+ fs := s.frames[len(s.frames)-n:]
+ s.frames = s.frames[:len(s.frames)-n]
+
+ return fs
+}
+
+type NodeType int
+
+const (
+ NodeTypeError = 0
+ NodeTypeTerminal = 1
+ NodeTypeNonTerminal = 2
+)
+
+// Node is a implementation of SyntaxTreeNode interface.
+type Node struct {
+ Type NodeType
+ KindName string
+ Text string
+ BytePos int
+ ByteLen int
+ Row int
+ Col int
+ Children []*Node
+}
+
+func (n *Node) MarshalJSON() ([]byte, error) {
+ switch n.Type {
+ case NodeTypeError:
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ })
+ case NodeTypeTerminal:
+ if n.KindName == "" {
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ Text string `json:"text"`
+ Row int `json:"row"`
+ Col int `json:"col"`
+ }{
+ Type: n.Type,
+ Text: n.Text,
+ Row: n.Row,
+ Col: n.Col,
+ })
+ }
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ Text string `json:"text"`
+ Row int `json:"row"`
+ Col int `json:"col"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ Text: n.Text,
+ Row: n.Row,
+ Col: n.Col,
+ })
+ case NodeTypeNonTerminal:
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ Children []*Node `json:"children"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ Children: n.Children,
+ })
+ default:
+ return nil, fmt.Errorf("invalid node type: %v", n.Type)
+ }
+}
+
+// ChildCount is a implementation of SyntaxTreeNode.ChildCount.
+func (n *Node) ChildCount() int {
+ return len(n.Children)
+}
+
+// ExpandChildren is a implementation of SyntaxTreeNode.ExpandChildren.
+func (n *Node) ExpandChildren() []SyntaxTreeNode {
+ fs := make([]SyntaxTreeNode, len(n.Children))
+ for i, n := range n.Children {
+ fs[i] = n
+ }
+ return fs
+}
+
+// PrintTree prints a syntax tree whose root is `node`.
+func PrintTree(w io.Writer, node *Node) {
+ printTree(w, node, "", "")
+}
+
+func printTree(w io.Writer, node *Node, ruledLine string, childRuledLinePrefix string) {
+ if node == nil {
+ return
+ }
+
+ switch node.Type {
+ case NodeTypeError:
+ fmt.Fprintf(w, "%v%v\n", ruledLine, node.KindName)
+ case NodeTypeTerminal:
+ fmt.Fprintf(w, "%v%v %v\n", ruledLine, node.KindName, strconv.Quote(node.Text))
+ case NodeTypeNonTerminal:
+ fmt.Fprintf(w, "%v%v\n", ruledLine, node.KindName)
+
+ num := len(node.Children)
+ for i, child := range node.Children {
+ var line string
+ if num > 1 && i < num-1 {
+ line = "├─ "
+ } else {
+ line = "└─ "
+ }
+
+ var prefix string
+ if i >= num-1 {
+ prefix = " "
+ } else {
+ prefix = "│ "
+ }
+
+ printTree(w, child, childRuledLinePrefix+line, childRuledLinePrefix+prefix)
+ }
+ }
+}
diff --git a/src/urubu/driver/parser/spec.go b/src/urubu/driver/parser/spec.go
new file mode 100644
index 0000000..6dc7c3f
--- /dev/null
+++ b/src/urubu/driver/parser/spec.go
@@ -0,0 +1,73 @@
+package parser
+
+import spec "urubu/spec/grammar"
+
+type grammarImpl struct {
+ g *spec.CompiledGrammar
+}
+
+func NewGrammar(g *spec.CompiledGrammar) *grammarImpl {
+ return &grammarImpl{
+ g: g,
+ }
+}
+
+func (g *grammarImpl) InitialState() int {
+ return g.g.Syntactic.InitialState
+}
+
+func (g *grammarImpl) StartProduction() int {
+ return g.g.Syntactic.StartProduction
+}
+
+func (g *grammarImpl) RecoverProduction(prod int) bool {
+ return g.g.Syntactic.RecoverProductions[prod] != 0
+}
+
+func (g *grammarImpl) Action(state int, terminal int) int {
+ return g.g.Syntactic.Action[state*g.g.Syntactic.TerminalCount+terminal]
+}
+
+func (g *grammarImpl) GoTo(state int, lhs int) int {
+ return g.g.Syntactic.GoTo[state*g.g.Syntactic.NonTerminalCount+lhs]
+}
+
+func (g *grammarImpl) AlternativeSymbolCount(prod int) int {
+ return g.g.Syntactic.AlternativeSymbolCounts[prod]
+}
+
+func (g *grammarImpl) TerminalCount() int {
+ return g.g.Syntactic.TerminalCount
+}
+
+func (g *grammarImpl) SkipTerminal(terminal int) bool {
+ return g.g.Syntactic.TerminalSkip[terminal] == 1
+}
+
+func (g *grammarImpl) ErrorTrapperState(state int) bool {
+ return g.g.Syntactic.ErrorTrapperStates[state] != 0
+}
+
+func (g *grammarImpl) NonTerminal(nonTerminal int) string {
+ return g.g.Syntactic.NonTerminals[nonTerminal]
+}
+
+func (g *grammarImpl) LHS(prod int) int {
+ return g.g.Syntactic.LHSSymbols[prod]
+}
+
+func (g *grammarImpl) EOF() int {
+ return g.g.Syntactic.EOFSymbol
+}
+
+func (g *grammarImpl) Error() int {
+ return g.g.Syntactic.ErrorSymbol
+}
+
+func (g *grammarImpl) Terminal(terminal int) string {
+ return g.g.Syntactic.Terminals[terminal]
+}
+
+func (g *grammarImpl) ASTAction(prod int) []int {
+ return g.g.ASTAction.Entries[prod]
+}
diff --git a/src/urubu/driver/parser/template.go b/src/urubu/driver/parser/template.go
new file mode 100644
index 0000000..33d097c
--- /dev/null
+++ b/src/urubu/driver/parser/template.go
@@ -0,0 +1,535 @@
+package parser
+
+import (
+ "bytes"
+ _ "embed"
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/token"
+ goToken "go/token"
+ "strconv"
+ "strings"
+ "text/template"
+
+ spec "urubu/spec/grammar"
+)
+
+// go:embed parser.go
+var parserCoreSrc string
+
+// go:embed semantic_action.go
+var semActSrc string
+
+func GenParser(cgram *spec.CompiledGrammar, pkgName string) ([]byte, error) {
+ var parserSrc string
+ {
+ fset := goToken.NewFileSet()
+ f, err := parser.ParseFile(fset, "parser.go", parserCoreSrc, parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = format.Node(&b, fset, f)
+ if err != nil {
+ return nil, err
+ }
+
+ parserSrc = b.String()
+ }
+
+ var grammarSrc string
+ {
+ t, err := template.New("").Funcs(genGrammarTemplateFuncs(cgram)).Parse(grammarSrcTmplate)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, map[string]interface{}{
+ "initialState": cgram.Syntactic.InitialState,
+ "startProduction": cgram.Syntactic.StartProduction,
+ "terminalCount": cgram.Syntactic.TerminalCount,
+ "nonTerminalCount": cgram.Syntactic.NonTerminalCount,
+ "eofSymbol": cgram.Syntactic.EOFSymbol,
+ "errorSymbol": cgram.Syntactic.ErrorSymbol,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ grammarSrc = b.String()
+ }
+
+ var lexerSrc string
+ {
+ t, err := template.New("").Funcs(genLexerTemplateFuncs(cgram)).Parse(lexerSrcTmplate)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ lexerSrc = b.String()
+ }
+
+ var src string
+ {
+ tmpl := `// Code generated by vartan-go. DO NOT EDIT.
+{{ .parserSrc }}
+
+{{ .grammarSrc }}
+
+{{ .lexerSrc }}
+`
+ t, err := template.New("").Parse(tmpl)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, map[string]string{
+ "parserSrc": parserSrc,
+ "grammarSrc": grammarSrc,
+ "lexerSrc": lexerSrc,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ src = b.String()
+ }
+
+ fset := goToken.NewFileSet()
+ f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+
+ f.Name = ast.NewIdent(pkgName)
+
+ // Complete an import statement.
+ for _, d := range f.Decls {
+ gd, ok := d.(*ast.GenDecl)
+ if !ok || gd.Tok != token.IMPORT {
+ continue
+ }
+ gd.Specs = append(gd.Specs, &ast.ImportSpec{
+ Path: &ast.BasicLit{
+ Value: `"io"`,
+ },
+ })
+ break
+ }
+
+ var b bytes.Buffer
+ err = format.Node(&b, fset, f)
+ if err != nil {
+ return nil, err
+ }
+
+ return b.Bytes(), nil
+}
+
+const grammarSrcTmplate = `
+type grammarImpl struct {
+ recoverProductions []int
+ action []int
+ goTo []int
+ alternativeSymbolCounts []int
+ errorTrapperStates []int
+ nonTerminals []string
+ lhsSymbols []int
+ terminals []string
+ terminalSkip []int
+ astActions [][]int
+}
+
+func NewGrammar() *grammarImpl {
+ return &grammarImpl{
+ recoverProductions: {{ genRecoverProductions }},
+ action: {{ genAction }},
+ goTo: {{ genGoTo }},
+ alternativeSymbolCounts: {{ genAlternativeSymbolCounts }},
+ errorTrapperStates: {{ genErrorTrapperStates }},
+ nonTerminals: {{ genNonTerminals }},
+ lhsSymbols: {{ genLHSSymbols }},
+ terminals: {{ genTerminals }},
+ terminalSkip: {{ genTerminalSkip }},
+ astActions: {{ genASTActions }},
+ }
+}
+
+func (g *grammarImpl) InitialState() int {
+ return {{ .initialState }}
+}
+
+func (g *grammarImpl) StartProduction() int {
+ return {{ .startProduction }}
+}
+
+func (g *grammarImpl) RecoverProduction(prod int) bool {
+ return g.recoverProductions[prod] != 0
+}
+
+func (g *grammarImpl) Action(state int, terminal int) int {
+ return g.action[state*{{ .terminalCount }}+terminal]
+}
+
+func (g *grammarImpl) GoTo(state int, lhs int) int {
+ return g.goTo[state*{{ .nonTerminalCount }}+lhs]
+}
+
+func (g *grammarImpl) AlternativeSymbolCount(prod int) int {
+ return g.alternativeSymbolCounts[prod]
+}
+
+func (g *grammarImpl) TerminalCount() int {
+ return {{ .terminalCount }}
+}
+
+func (g *grammarImpl) SkipTerminal(terminal int) bool {
+ return g.terminalSkip[terminal] == 1
+}
+
+func (g *grammarImpl) ErrorTrapperState(state int) bool {
+ return g.errorTrapperStates[state] != 0
+}
+
+func (g *grammarImpl) NonTerminal(nonTerminal int) string {
+ return g.nonTerminals[nonTerminal]
+}
+
+func (g *grammarImpl) LHS(prod int) int {
+ return g.lhsSymbols[prod]
+}
+
+func (g *grammarImpl) EOF() int {
+ return {{ .eofSymbol }}
+}
+
+func (g *grammarImpl) Error() int {
+ return {{ .errorSymbol }}
+}
+
+func (g *grammarImpl) Terminal(terminal int) string {
+ return g.terminals[terminal]
+}
+
+func (g *grammarImpl) ASTAction(prod int) []int {
+ return g.astActions[prod]
+}
+`
+
+func genGrammarTemplateFuncs(cgram *spec.CompiledGrammar) template.FuncMap {
+ return template.FuncMap{
+ "genRecoverProductions": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.RecoverProductions {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genAction": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.Action {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genGoTo": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.GoTo {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genAlternativeSymbolCounts": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.AlternativeSymbolCounts {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genErrorTrapperStates": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.ErrorTrapperStates {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genNonTerminals": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]string{\n")
+ for _, v := range cgram.Syntactic.NonTerminals {
+ fmt.Fprintf(&b, "%v,\n", strconv.Quote(v))
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genLHSSymbols": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.LHSSymbols {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genTerminals": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]string{\n")
+ for _, v := range cgram.Syntactic.Terminals {
+ fmt.Fprintf(&b, "%v,\n", strconv.Quote(v))
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genTerminalSkip": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.TerminalSkip {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ "genASTActions": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[][]int{\n")
+ for _, entries := range cgram.ASTAction.Entries {
+ if len(entries) == 0 {
+ fmt.Fprintf(&b, "nil,\n")
+ continue
+ }
+
+ fmt.Fprintf(&b, "{\n")
+ c := 1
+ for _, v := range entries {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "},\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ }
+}
+
+const lexerSrcTmplate = `
+type vToken struct {
+ terminalID int
+ tok *Token
+}
+
+func (t *vToken) TerminalID() int {
+ return t.terminalID
+}
+
+func (t *vToken) Lexeme() []byte {
+ return t.tok.Lexeme
+}
+
+func (t *vToken) EOF() bool {
+ return t.tok.EOF
+}
+
+func (t *vToken) Invalid() bool {
+ return t.tok.Invalid
+}
+
+func (t *vToken) BytePosition() (int, int) {
+ return t.tok.BytePos, t.tok.ByteLen
+}
+
+func (t *vToken) Position() (int, int) {
+ return t.tok.Row, t.tok.Col
+}
+
+var kindToTerminal = {{ genKindToTerminal }}
+
+type tokenStream struct {
+ lex *Lexer
+ kindToTerminal []int
+}
+
+func NewTokenStream(src io.Reader) (*tokenStream, error) {
+ lex, err := NewLexer(NewLexSpec(), src)
+ if err != nil {
+ return nil, err
+ }
+
+ return &tokenStream{
+ lex: lex,
+ }, nil
+}
+
+func (t *tokenStream) Next() (VToken, error) {
+ tok, err := t.lex.Next()
+ if err != nil {
+ return nil, err
+ }
+ return &vToken{
+ terminalID: kindToTerminal[tok.KindID],
+ tok: tok,
+ }, nil
+}
+`
+
+func genLexerTemplateFuncs(cgram *spec.CompiledGrammar) template.FuncMap {
+ return template.FuncMap{
+ "genKindToTerminal": func() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "[]int{\n")
+ c := 1
+ for _, v := range cgram.Syntactic.KindToTerminal {
+ fmt.Fprintf(&b, "%v, ", v)
+ if c == 20 {
+ fmt.Fprintf(&b, "\n")
+ c = 1
+ } else {
+ c++
+ }
+ }
+ if c > 1 {
+ fmt.Fprintf(&b, "\n")
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+ },
+ }
+}
+
+func GenSemanticAction(pkgName string) ([]byte, error) {
+ var src string
+ {
+ tmpl := `// Code generated by vartan-go. DO NOT EDIT.
+{{ .semActSrc }}
+`
+ t, err := template.New("").Parse(tmpl)
+ if err != nil {
+ return nil, err
+ }
+
+ var b strings.Builder
+ err = t.Execute(&b, map[string]string{
+ "semActSrc": semActSrc,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ src = b.String()
+ }
+
+ fset := goToken.NewFileSet()
+ f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+ if err != nil {
+ return nil, err
+ }
+
+ f.Name = ast.NewIdent(pkgName)
+
+ var b bytes.Buffer
+ err = format.Node(&b, fset, f)
+ if err != nil {
+ return nil, err
+ }
+
+ return b.Bytes(), nil
+}
diff --git a/src/urubu/driver/parser/token_stream.go b/src/urubu/driver/parser/token_stream.go
new file mode 100644
index 0000000..788e521
--- /dev/null
+++ b/src/urubu/driver/parser/token_stream.go
@@ -0,0 +1,65 @@
+package parser
+
+import (
+ "io"
+
+ "urubu/driver/lexer"
+ spec "urubu/spec/grammar"
+)
+
+type vToken struct {
+ terminalID int
+ tok *lexer.Token
+}
+
+func (t *vToken) TerminalID() int {
+ return t.terminalID
+}
+
+func (t *vToken) Lexeme() []byte {
+ return t.tok.Lexeme
+}
+
+func (t *vToken) EOF() bool {
+ return t.tok.EOF
+}
+
+func (t *vToken) Invalid() bool {
+ return t.tok.Invalid
+}
+
+func (t *vToken) BytePosition() (int, int) {
+ return t.tok.BytePos, t.tok.ByteLen
+}
+
+func (t *vToken) Position() (int, int) {
+ return t.tok.Row, t.tok.Col
+}
+
+type tokenStream struct {
+ lex *lexer.Lexer
+ kindToTerminal []int
+}
+
+func NewTokenStream(g *spec.CompiledGrammar, src io.Reader) (TokenStream, error) {
+ lex, err := lexer.NewLexer(lexer.NewLexSpec(g.Lexical), src)
+ if err != nil {
+ return nil, err
+ }
+
+ return &tokenStream{
+ lex: lex,
+ kindToTerminal: g.Syntactic.KindToTerminal,
+ }, nil
+}
+
+func (l *tokenStream) Next() (VToken, error) {
+ tok, err := l.lex.Next()
+ if err != nil {
+ return nil, err
+ }
+ return &vToken{
+ terminalID: l.kindToTerminal[tok.KindID],
+ tok: tok,
+ }, nil
+}
diff --git a/src/urubu/error/error.go b/src/urubu/error/error.go
new file mode 100644
index 0000000..0e5d3af
--- /dev/null
+++ b/src/urubu/error/error.go
@@ -0,0 +1,86 @@
+package error
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "sort"
+ "strings"
+)
+
+type SpecErrors []*SpecError
+
+func (e SpecErrors) Error() string {
+ if len(e) == 0 {
+ return ""
+ }
+
+ sorted := make([]*SpecError, len(e))
+ copy(sorted, e)
+ sort.SliceStable(sorted, func(i, j int) bool {
+ return sorted[i].Row < sorted[j].Row
+ })
+ sort.SliceStable(sorted, func(i, j int) bool {
+ return sorted[i].FilePath < sorted[j].FilePath
+ })
+
+ var b strings.Builder
+ fmt.Fprintf(&b, "%v", sorted[0])
+ for _, err := range sorted[1:] {
+ fmt.Fprintf(&b, "\n%v", err)
+ }
+
+ return b.String()
+}
+
+type SpecError struct {
+ Cause error
+ Detail string
+ FilePath string
+ SourceName string
+ Row int
+ Col int
+}
+
+func (e *SpecError) Error() string {
+ var b strings.Builder
+ if e.SourceName != "" {
+ fmt.Fprintf(&b, "%v: ", e.SourceName)
+ }
+ if e.Row != 0 && e.Col != 0 {
+ fmt.Fprintf(&b, "%v:%v: ", e.Row, e.Col)
+ }
+ fmt.Fprintf(&b, "error: %v", e.Cause)
+ if e.Detail != "" {
+ fmt.Fprintf(&b, ": %v", e.Detail)
+ }
+
+ line := readLine(e.FilePath, e.Row)
+ if line != "" {
+ fmt.Fprintf(&b, "\n %v", line)
+ }
+
+ return b.String()
+}
+
+func readLine(filePath string, row int) string {
+ if filePath == "" || row <= 0 {
+ return ""
+ }
+
+ f, err := os.Open(filePath)
+ if err != nil {
+ return ""
+ }
+
+ i := 1
+ s := bufio.NewScanner(f)
+ for s.Scan() {
+ if i == row {
+ return s.Text()
+ }
+ i++
+ }
+
+ return ""
+}
diff --git a/src/urubu/grammar/first.go b/src/urubu/grammar/first.go
new file mode 100644
index 0000000..6443bcf
--- /dev/null
+++ b/src/urubu/grammar/first.go
@@ -0,0 +1,148 @@
+package grammar
+
+import (
+ "fmt"
+
+ "urubu/grammar/symbol"
+)
+
+type firstEntry struct {
+ symbols map[symbol.Symbol]struct{}
+ empty bool
+}
+
+func newFirstEntry() *firstEntry {
+ return &firstEntry{
+ symbols: map[symbol.Symbol]struct{}{},
+ empty: false,
+ }
+}
+
+func (e *firstEntry) add(sym symbol.Symbol) bool {
+ if _, ok := e.symbols[sym]; ok {
+ return false
+ }
+ e.symbols[sym] = struct{}{}
+ return true
+}
+
+func (e *firstEntry) addEmpty() bool {
+ if !e.empty {
+ e.empty = true
+ return true
+ }
+ return false
+}
+
+func (e *firstEntry) mergeExceptEmpty(target *firstEntry) bool {
+ if target == nil {
+ return false
+ }
+ changed := false
+ for sym := range target.symbols {
+ added := e.add(sym)
+ if added {
+ changed = true
+ }
+ }
+ return changed
+}
+
+type firstSet struct {
+ set map[symbol.Symbol]*firstEntry
+}
+
+func newFirstSet(prods *productionSet) *firstSet {
+ fst := &firstSet{
+ set: map[symbol.Symbol]*firstEntry{},
+ }
+ for _, prod := range prods.getAllProductions() {
+ if _, ok := fst.set[prod.lhs]; ok {
+ continue
+ }
+ fst.set[prod.lhs] = newFirstEntry()
+ }
+
+ return fst
+}
+
+func (fst *firstSet) find(prod *production, head int) (*firstEntry, error) {
+ entry := newFirstEntry()
+ if prod.rhsLen <= head {
+ entry.addEmpty()
+ return entry, nil
+ }
+ for _, sym := range prod.rhs[head:] {
+ if sym.IsTerminal() {
+ entry.add(sym)
+ return entry, nil
+ }
+
+ e := fst.findBySymbol(sym)
+ if e == nil {
+ return nil, fmt.Errorf("an entry of FIRST was not found; symbol: %s", sym)
+ }
+ for s := range e.symbols {
+ entry.add(s)
+ }
+ if !e.empty {
+ return entry, nil
+ }
+ }
+ entry.addEmpty()
+ return entry, nil
+}
+
+func (fst *firstSet) findBySymbol(sym symbol.Symbol) *firstEntry {
+ return fst.set[sym]
+}
+
+type firstComContext struct {
+ first *firstSet
+}
+
+func newFirstComContext(prods *productionSet) *firstComContext {
+ return &firstComContext{
+ first: newFirstSet(prods),
+ }
+}
+
+func genFirstSet(prods *productionSet) (*firstSet, error) {
+ cc := newFirstComContext(prods)
+ for {
+ more := false
+ for _, prod := range prods.getAllProductions() {
+ e := cc.first.findBySymbol(prod.lhs)
+ changed, err := genProdFirstEntry(cc, e, prod)
+ if err != nil {
+ return nil, err
+ }
+ if changed {
+ more = true
+ }
+ }
+ if !more {
+ break
+ }
+ }
+ return cc.first, nil
+}
+
+func genProdFirstEntry(cc *firstComContext, acc *firstEntry, prod *production) (bool, error) {
+ if prod.isEmpty() {
+ return acc.addEmpty(), nil
+ }
+
+ for _, sym := range prod.rhs {
+ if sym.IsTerminal() {
+ return acc.add(sym), nil
+ }
+
+ e := cc.first.findBySymbol(sym)
+ changed := acc.mergeExceptEmpty(e)
+ if !e.empty {
+ return changed, nil
+ }
+ }
+ return acc.addEmpty(), nil
+}
diff --git a/src/urubu/grammar/grammar.go b/src/urubu/grammar/grammar.go
new file mode 100644
index 0000000..bfa53c6
--- /dev/null
+++ b/src/urubu/grammar/grammar.go
@@ -0,0 +1,1390 @@
+package grammar
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ verr "urubu/error"
+ "urubu/grammar/lexical"
+ "urubu/grammar/symbol"
+ spec "urubu/spec/grammar"
+ "urubu/spec/grammar/parser"
+)
+
+type astActionEntry struct {
+ position int
+ expansion bool
+}
+
+type assocType string
+
+const (
+ assocTypeNil = assocType("")
+ assocTypeLeft = assocType("left")
+ assocTypeRight = assocType("right")
+)
+
+const (
+ precNil = 0
+ precMin = 1
+)
+
+// precAndAssoc represents precedence and associativities of terminal symbols and productions.
+// We use the priority of the production to resolve shift/reduce conflicts.
+type precAndAssoc struct {
+ // termPrec and termAssoc represent the precedence of the terminal symbols.
+ termPrec map[symbol.SymbolNum]int
+ termAssoc map[symbol.SymbolNum]assocType
+
+ // prodPrec and prodAssoc represent the precedence and the associativities of the production.
+ // These values are inherited from the right-most terminal symbols in the RHS of the productions.
+ prodPrec map[productionNum]int
+ prodAssoc map[productionNum]assocType
+}
+
+func (pa *precAndAssoc) terminalPrecedence(sym symbol.SymbolNum) int {
+ prec, ok := pa.termPrec[sym]
+ if !ok {
+ return precNil
+ }
+
+ return prec
+}
+
+func (pa *precAndAssoc) terminalAssociativity(sym symbol.SymbolNum) assocType {
+ assoc, ok := pa.termAssoc[sym]
+ if !ok {
+ return assocTypeNil
+ }
+
+ return assoc
+}
+
+func (pa *precAndAssoc) productionPredence(prod productionNum) int {
+ prec, ok := pa.prodPrec[prod]
+ if !ok {
+ return precNil
+ }
+
+ return prec
+}
+
+func (pa *precAndAssoc) productionAssociativity(prod productionNum) assocType {
+ assoc, ok := pa.prodAssoc[prod]
+ if !ok {
+ return assocTypeNil
+ }
+
+ return assoc
+}
+
+const reservedSymbolNameError = "error"
+
+type Grammar struct {
+ name string
+ lexSpec *lexical.LexSpec
+ skipSymbols []symbol.Symbol
+ productionSet *productionSet
+ augmentedStartSymbol symbol.Symbol
+ errorSymbol symbol.Symbol
+ symbolTable *symbol.SymbolTableReader
+ astActions map[productionID][]*astActionEntry
+ precAndAssoc *precAndAssoc
+
+ // recoverProductions is a set of productions having the recover directive.
+ recoverProductions map[productionID]struct{}
+}
+
+type buildConfig struct {
+ isReportingEnabled bool
+}
+
+type BuildOption func(config *buildConfig)
+
+func EnableReporting() BuildOption {
+ return func(config *buildConfig) {
+ config.isReportingEnabled = true
+ }
+}
+
+type GrammarBuilder struct {
+ AST *parser.RootNode
+
+ errs verr.SpecErrors
+}
+
+func (b *GrammarBuilder) Build(opts ...BuildOption) (*spec.CompiledGrammar, *spec.Report, error) {
+ gram, err := b.build()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return compile(gram, opts...)
+}
+
+func (b *GrammarBuilder) build() (*Grammar, error) {
+ var specName string
+ {
+ errOccurred := false
+ for _, dir := range b.AST.Directives {
+ if dir.Name != "name" {
+ continue
+ }
+
+ if len(dir.Parameters) != 1 || dir.Parameters[0].ID == "" {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'name' takes just one ID parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+
+ errOccurred = true
+ break
+ }
+
+ specName = dir.Parameters[0].ID
+ break
+ }
+
+ if specName == "" && !errOccurred {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrNoGrammarName,
+ })
+ }
+ }
+
+ b.checkSpellingInconsistenciesOfUserDefinedIDs(b.AST)
+ if len(b.errs) > 0 {
+ return nil, b.errs
+ }
+
+ symTab, ss, err := b.genSymbolTable(b.AST)
+ if err != nil {
+ return nil, err
+ }
+
+ lexSpec, skip, err := b.genLexSpecAndSkipSymbols(symTab.Reader(), b.AST)
+ if err != nil {
+ return nil, err
+ }
+
+ prodsAndActs, err := b.genProductionsAndActions(b.AST, symTab.Reader(), ss.errSym, ss.augStartSym, ss.startSym)
+ if err != nil {
+ return nil, err
+ }
+ if prodsAndActs == nil && len(b.errs) > 0 {
+ return nil, b.errs
+ }
+
+ pa, err := b.genPrecAndAssoc(symTab.Reader(), ss.errSym, prodsAndActs)
+ if err != nil {
+ return nil, err
+ }
+ if pa == nil && len(b.errs) > 0 {
+ return nil, b.errs
+ }
+
+ syms := findUsedAndUnusedSymbols(b.AST)
+ if syms == nil && len(b.errs) > 0 {
+ return nil, b.errs
+ }
+
+ // When a terminal symbol that cannot be reached from the start symbol has the skip directive,
+ // the compiler treats its terminal as a used symbol, not unused.
+ {
+ r := symTab.Reader()
+ for _, sym := range skip {
+ s, _ := r.ToText(sym)
+ if _, ok := syms.unusedTerminals[s]; !ok {
+ prod := syms.usedTerminals[s]
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrTermCannotBeSkipped,
+ Detail: s,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ continue
+ }
+
+ delete(syms.unusedTerminals, s)
+ }
+ }
+
+ for sym, prod := range syms.unusedProductions {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrUnusedProduction,
+ Detail: sym,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ }
+
+ for sym, prod := range syms.unusedTerminals {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrUnusedTerminal,
+ Detail: sym,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ }
+
+ if len(b.errs) > 0 {
+ return nil, b.errs
+ }
+
+ return &Grammar{
+ name: specName,
+ lexSpec: lexSpec,
+ skipSymbols: skip,
+ productionSet: prodsAndActs.prods,
+ augmentedStartSymbol: prodsAndActs.augStartSym,
+ errorSymbol: ss.errSym,
+ symbolTable: symTab.Reader(),
+ astActions: prodsAndActs.astActs,
+ recoverProductions: prodsAndActs.recoverProds,
+ precAndAssoc: pa,
+ }, nil
+}
+
+type usedAndUnusedSymbols struct {
+ unusedProductions map[string]*parser.ProductionNode
+ unusedTerminals map[string]*parser.ProductionNode
+ usedTerminals map[string]*parser.ProductionNode
+}
+
+func findUsedAndUnusedSymbols(root *parser.RootNode) *usedAndUnusedSymbols {
+ prods := map[string]*parser.ProductionNode{}
+ lexProds := map[string]*parser.ProductionNode{}
+ mark := map[string]bool{}
+ {
+ for _, p := range root.Productions {
+ prods[p.LHS] = p
+ mark[p.LHS] = false
+ for _, alt := range p.RHS {
+ for _, e := range alt.Elements {
+ if e.ID == "" {
+ continue
+ }
+ mark[e.ID] = false
+ }
+ }
+ }
+
+ for _, p := range root.LexProductions {
+ lexProds[p.LHS] = p
+ mark[p.LHS] = false
+ }
+
+ start := root.Productions[0]
+ mark[start.LHS] = true
+ markUsedSymbols(mark, map[string]bool{}, prods, start)
+
+ // We don't have to check the error symbol because the error symbol doesn't have a production.
+ delete(mark, reservedSymbolNameError)
+ }
+
+ usedTerms := make(map[string]*parser.ProductionNode, len(lexProds))
+ unusedProds := map[string]*parser.ProductionNode{}
+ unusedTerms := map[string]*parser.ProductionNode{}
+ for sym, used := range mark {
+ if p, ok := prods[sym]; ok {
+ if used {
+ continue
+ }
+ unusedProds[sym] = p
+ continue
+ }
+ if p, ok := lexProds[sym]; ok {
+ if used {
+ usedTerms[sym] = p
+ } else {
+ unusedTerms[sym] = p
+ }
+ continue
+ }
+
+ // May be reached here when a fragment name appears on the right-hand side of a production rule. However, an error
+ // to the effect that a production rule cannot contain a fragment will be detected in a subsequent process. So we can
+ // ignore it here.
+ }
+
+ return &usedAndUnusedSymbols{
+ usedTerminals: usedTerms,
+ unusedProductions: unusedProds,
+ unusedTerminals: unusedTerms,
+ }
+}
+
+func markUsedSymbols(mark map[string]bool, marked map[string]bool, prods map[string]*parser.ProductionNode, prod *parser.ProductionNode) {
+ if marked[prod.LHS] {
+ return
+ }
+
+ for _, alt := range prod.RHS {
+ for _, e := range alt.Elements {
+ if e.ID == "" {
+ continue
+ }
+
+ mark[e.ID] = true
+
+ p, ok := prods[e.ID]
+ if !ok {
+ continue
+ }
+
+ // Remove a production to avoid inifinite recursion.
+ marked[prod.LHS] = true
+
+ markUsedSymbols(mark, marked, prods, p)
+ }
+ }
+}
+
+func (b *GrammarBuilder) checkSpellingInconsistenciesOfUserDefinedIDs(root *parser.RootNode) {
+ var ids []string
+ {
+ for _, prod := range root.Productions {
+ ids = append(ids, prod.LHS)
+ for _, alt := range prod.RHS {
+ for _, elem := range alt.Elements {
+ if elem.Label != nil {
+ ids = append(ids, elem.Label.Name)
+ }
+ }
+ }
+ }
+ for _, prod := range root.LexProductions {
+ ids = append(ids, prod.LHS)
+ }
+ for _, dir := range root.Directives {
+ dirIDs := collectUserDefinedIDsFromDirective(dir)
+ if len(dirIDs) > 0 {
+ ids = append(ids, dirIDs...)
+ }
+ }
+ }
+
+ duplicated := lexical.FindSpellingInconsistencies(ids)
+ if len(duplicated) == 0 {
+ return
+ }
+
+ for _, dup := range duplicated {
+ var s string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "%+v", dup[0])
+ for _, id := range dup[1:] {
+ fmt.Fprintf(&b, ", %+v", id)
+ }
+ s = b.String()
+ }
+
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrSpellingInconsistency,
+ Detail: s,
+ })
+ }
+}
+
+func collectUserDefinedIDsFromDirective(dir *parser.DirectiveNode) []string {
+ var ids []string
+ for _, param := range dir.Parameters {
+ if param.Group != nil {
+ for _, d := range param.Group {
+ dIDs := collectUserDefinedIDsFromDirective(d)
+ if len(dIDs) > 0 {
+ ids = append(ids, dIDs...)
+ }
+ }
+ }
+ if param.OrderedSymbol != "" {
+ ids = append(ids, param.OrderedSymbol)
+ }
+ }
+ return ids
+}
+
+type symbols struct {
+ errSym symbol.Symbol
+ augStartSym symbol.Symbol
+ startSym symbol.Symbol
+}
+
+func (b *GrammarBuilder) genSymbolTable(root *parser.RootNode) (*symbol.SymbolTable, *symbols, error) {
+ symTab := symbol.NewSymbolTable()
+ w := symTab.Writer()
+ r := symTab.Reader()
+
+ // We need to register the reserved symbol before registering others.
+ var errSym symbol.Symbol
+ {
+ sym, err := w.RegisterTerminalSymbol(reservedSymbolNameError)
+ if err != nil {
+ return nil, nil, err
+ }
+ errSym = sym
+ }
+
+ for _, prod := range root.LexProductions {
+ if sym, exist := r.ToSymbol(prod.LHS); exist {
+ if sym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrErrSymIsReserved,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ } else {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateTerminal,
+ Detail: prod.LHS,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ }
+
+ continue
+ }
+
+ _, err := w.RegisterTerminalSymbol(prod.LHS)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+
+ startProd := root.Productions[0]
+ augStartText := fmt.Sprintf("%s'", startProd.LHS)
+ var err error
+ augStartSym, err := w.RegisterStartSymbol(augStartText)
+ if err != nil {
+ return nil, nil, err
+ }
+ if augStartSym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrErrSymIsReserved,
+ Row: startProd.Pos.Row,
+ Col: startProd.Pos.Col,
+ })
+ }
+
+ startSym, err := w.RegisterNonTerminalSymbol(startProd.LHS)
+ if err != nil {
+ return nil, nil, err
+ }
+ if startSym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrErrSymIsReserved,
+ Row: startProd.Pos.Row,
+ Col: startProd.Pos.Col,
+ })
+ }
+
+ for _, prod := range root.Productions {
+ sym, err := w.RegisterNonTerminalSymbol(prod.LHS)
+ if err != nil {
+ return nil, nil, err
+ }
+ if sym.IsTerminal() {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateName,
+ Detail: prod.LHS,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ }
+ if sym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrErrSymIsReserved,
+ Row: prod.Pos.Row,
+ Col: prod.Pos.Col,
+ })
+ }
+ }
+
+ return symTab, &symbols{
+ errSym: errSym,
+ augStartSym: augStartSym,
+ startSym: startSym,
+ }, nil
+}
+
+func (b *GrammarBuilder) genLexSpecAndSkipSymbols(symTab *symbol.SymbolTableReader, root *parser.RootNode) (*lexical.LexSpec, []symbol.Symbol, error) {
+ entries := []*lexical.LexEntry{}
+ skipSyms := []symbol.Symbol{}
+ for _, prod := range root.LexProductions {
+ entry, skip, specErr, err := genLexEntry(prod)
+ if err != nil {
+ return nil, nil, err
+ }
+ if specErr != nil {
+ b.errs = append(b.errs, specErr)
+ continue
+ }
+ if skip {
+ sym, _ := symTab.ToSymbol(prod.LHS)
+ skipSyms = append(skipSyms, sym)
+ }
+ entries = append(entries, entry)
+ }
+
+ checkedFragments := map[string]struct{}{}
+ for _, fragment := range root.Fragments {
+ if _, exist := checkedFragments[fragment.LHS]; exist {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateFragment,
+ Detail: fragment.LHS,
+ Row: fragment.Pos.Row,
+ Col: fragment.Pos.Col,
+ })
+ continue
+ }
+ checkedFragments[fragment.LHS] = struct{}{}
+
+ entries = append(entries, &lexical.LexEntry{
+ Fragment: true,
+ Kind: spec.LexKindName(fragment.LHS),
+ Pattern: fragment.RHS,
+ })
+ }
+
+ return &lexical.LexSpec{
+ Entries: entries,
+ }, skipSyms, nil
+}
+
+func genLexEntry(prod *parser.ProductionNode) (*lexical.LexEntry, bool, *verr.SpecError, error) {
+ alt := prod.RHS[0]
+ elem := alt.Elements[0]
+
+ var pattern string
+ if elem.Literally {
+ pattern = spec.EscapePattern(elem.Pattern)
+ } else {
+ pattern = elem.Pattern
+ }
+
+ var modes []spec.LexModeName
+ var skip bool
+ var push spec.LexModeName
+ var pop bool
+ dirConsumed := map[string]struct{}{}
+ for _, dir := range prod.Directives {
+ if _, consumed := dirConsumed[dir.Name]; consumed {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDuplicateDir,
+ Detail: dir.Name,
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ dirConsumed[dir.Name] = struct{}{}
+
+ switch dir.Name {
+ case "mode":
+ if len(dir.Parameters) == 0 {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'mode' directive needs an ID parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ for _, param := range dir.Parameters {
+ if param.ID == "" {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'mode' directive needs an ID parameter",
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ }, nil
+ }
+ modes = append(modes, spec.LexModeName(param.ID))
+ }
+ case "skip":
+ if len(dir.Parameters) > 0 {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'skip' directive needs no parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ skip = true
+ case "push":
+ if len(dir.Parameters) != 1 || dir.Parameters[0].ID == "" {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'push' directive needs an ID parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ push = spec.LexModeName(dir.Parameters[0].ID)
+ case "pop":
+ if len(dir.Parameters) > 0 {
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'pop' directive needs no parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ pop = true
+ default:
+ return nil, false, &verr.SpecError{
+ Cause: semErrDirInvalidName,
+ Detail: dir.Name,
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ }, nil
+ }
+ }
+
+ if len(alt.Directives) > 0 {
+ return nil, false, &verr.SpecError{
+ Cause: semErrInvalidAltDir,
+ Detail: "a lexical production cannot have alternative directives",
+ Row: alt.Directives[0].Pos.Row,
+ Col: alt.Directives[0].Pos.Col,
+ }, nil
+ }
+
+ return &lexical.LexEntry{
+ Modes: modes,
+ Kind: spec.LexKindName(prod.LHS),
+ Pattern: pattern,
+ Push: push,
+ Pop: pop,
+ }, skip, nil, nil
+}
+
+type productionsAndActions struct {
+ prods *productionSet
+ augStartSym symbol.Symbol
+ astActs map[productionID][]*astActionEntry
+ prodPrecsTerm map[productionID]symbol.Symbol
+ prodPrecsOrdSym map[productionID]string
+ prodPrecPoss map[productionID]*parser.Position
+ recoverProds map[productionID]struct{}
+}
+
+func (b *GrammarBuilder) genProductionsAndActions(root *parser.RootNode, symTab *symbol.SymbolTableReader, errSym symbol.Symbol, augStartSym symbol.Symbol, startSym symbol.Symbol) (*productionsAndActions, error) {
+ if len(root.Productions) == 0 {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrNoProduction,
+ })
+ return nil, nil
+ }
+
+ prods := newProductionSet()
+ astActs := map[productionID][]*astActionEntry{}
+ prodPrecsTerm := map[productionID]symbol.Symbol{}
+ prodPrecsOrdSym := map[productionID]string{}
+ prodPrecPoss := map[productionID]*parser.Position{}
+ recoverProds := map[productionID]struct{}{}
+
+ p, err := newProduction(augStartSym, []symbol.Symbol{
+ startSym,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ prods.append(p)
+
+ for _, prod := range root.Productions {
+ lhsSym, ok := symTab.ToSymbol(prod.LHS)
+ if !ok {
+ // All symbols are assumed to be pre-detected, so it's a bug if we cannot find them here.
+ return nil, fmt.Errorf("symbol '%v' is undefined", prod.LHS)
+ }
+
+ if len(prod.Directives) > 0 {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrInvalidProdDir,
+ Detail: "a production cannot have production directives",
+ Row: prod.Directives[0].Pos.Row,
+ Col: prod.Directives[0].Pos.Col,
+ })
+ continue
+ }
+
+ LOOP_RHS:
+ for _, alt := range prod.RHS {
+ altSyms := make([]symbol.Symbol, len(alt.Elements))
+ offsets := map[string]int{}
+ ambiguousIDOffsets := map[string]struct{}{}
+ for i, elem := range alt.Elements {
+ sym, ok := symTab.ToSymbol(elem.ID)
+ if !ok {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrUndefinedSym,
+ Detail: elem.ID,
+ Row: elem.Pos.Row,
+ Col: elem.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ altSyms[i] = sym
+
+ if elem.Label != nil {
+ if _, added := offsets[elem.Label.Name]; added {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateLabel,
+ Detail: elem.Label.Name,
+ Row: elem.Label.Pos.Row,
+ Col: elem.Label.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ if _, found := symTab.ToSymbol(elem.Label.Name); found {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrInvalidLabel,
+ Detail: elem.Label.Name,
+ Row: elem.Label.Pos.Row,
+ Col: elem.Label.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ offsets[elem.Label.Name] = i
+ }
+ // A symbol having a label can be specified by both the label and the symbol name.
+ // So record the symbol's position, whether or not it has a label.
+ if elem.ID != "" {
+ if _, exist := offsets[elem.ID]; exist {
+ // When the same symbol appears multiple times in an alternative, the symbol is ambiguous. When we need
+ // to specify the symbol in a directive, we cannot use the name of the ambiguous symbol. Instead, specify
+ // a label to resolve the ambiguity.
+ delete(offsets, elem.ID)
+ ambiguousIDOffsets[elem.ID] = struct{}{}
+ } else {
+ offsets[elem.ID] = i
+ }
+ }
+ }
+
+ p, err := newProduction(lhsSym, altSyms)
+ if err != nil {
+ return nil, err
+ }
+ if _, exist := prods.findByID(p.id); exist {
+ // Report the line number of a duplicate alternative.
+ // When the alternative is empty, we report the position of its LHS.
+ var row int
+ var col int
+ if len(alt.Elements) > 0 {
+ row = alt.Elements[0].Pos.Row
+ col = alt.Elements[0].Pos.Col
+ } else {
+ row = prod.Pos.Row
+ col = prod.Pos.Col
+ }
+
+ var detail string
+ {
+ var b strings.Builder
+ fmt.Fprintf(&b, "%v →", prod.LHS)
+ for _, elem := range alt.Elements {
+ switch {
+ case elem.ID != "":
+ fmt.Fprintf(&b, " %v", elem.ID)
+ case elem.Pattern != "":
+ fmt.Fprintf(&b, ` "%v"`, elem.Pattern)
+ }
+ }
+ if len(alt.Elements) == 0 {
+ fmt.Fprintf(&b, " ε")
+ }
+
+ detail = b.String()
+ }
+
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateProduction,
+ Detail: detail,
+ Row: row,
+ Col: col,
+ })
+ continue LOOP_RHS
+ }
+ prods.append(p)
+
+ dirConsumed := map[string]struct{}{}
+ for _, dir := range alt.Directives {
+ if _, consumed := dirConsumed[dir.Name]; consumed {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateDir,
+ Detail: dir.Name,
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ }
+ dirConsumed[dir.Name] = struct{}{}
+
+ switch dir.Name {
+ case "ast":
+ if len(dir.Parameters) == 0 {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'ast' directive needs at least one parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ astAct := make([]*astActionEntry, len(dir.Parameters))
+ consumedOffsets := map[int]struct{}{}
+ for i, param := range dir.Parameters {
+ if param.ID == "" {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'ast' directive can take only ID parameters",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+
+ if _, ambiguous := ambiguousIDOffsets[param.ID]; ambiguous {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrAmbiguousElem,
+ Detail: fmt.Sprintf("'%v' is ambiguous", param.ID),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+
+ offset, ok := offsets[param.ID]
+ if !ok {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("a symbol was not found in an alternative: %v", param.ID),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ if _, consumed := consumedOffsets[offset]; consumed {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateElem,
+ Detail: param.ID,
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ consumedOffsets[offset] = struct{}{}
+
+ if param.Expansion {
+ elem := alt.Elements[offset]
+ if elem.Pattern != "" {
+ // Currently, it is a bug to reach here because it is
+ // forbidden to have anything other than ID appear in
+ // production rules.
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("the expansion symbol cannot be applied to a pattern (%v: \"%v\")", param.ID, elem.Pattern),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ elemSym, ok := symTab.ToSymbol(elem.ID)
+ if !ok {
+ // If the symbol was not found, it's a bug.
+ return nil, fmt.Errorf("a symbol corresponding to an ID (%v) was not found", elem.ID)
+ }
+ if elemSym.IsTerminal() {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("the expansion symbol cannot be applied to a terminal symbol (%v: %v)", param.ID, elem.ID),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ }
+
+ astAct[i] = &astActionEntry{
+ position: offset + 1,
+ expansion: param.Expansion,
+ }
+ }
+ astActs[p.id] = astAct
+ case "prec":
+ if len(dir.Parameters) != 1 || (dir.Parameters[0].ID == "" && dir.Parameters[0].OrderedSymbol == "") {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'prec' directive needs just one ID parameter or ordered symbol",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ param := dir.Parameters[0]
+ switch {
+ case param.ID != "":
+ sym, ok := symTab.ToSymbol(param.ID)
+ if !ok {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("unknown terminal symbol: %v", param.ID),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ if sym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("'%v' directive cannot be applied to an error symbol", dir.Name),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ }
+ if !sym.IsTerminal() {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("the symbol must be a terminal: %v", param.ID),
+ Row: param.Pos.Row,
+ Col: param.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ prodPrecsTerm[p.id] = sym
+ prodPrecPoss[p.id] = &param.Pos
+ case param.OrderedSymbol != "":
+ prodPrecsOrdSym[p.id] = param.OrderedSymbol
+ prodPrecPoss[p.id] = &param.Pos
+ }
+ case "recover":
+ if len(dir.Parameters) > 0 {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'recover' directive needs no parameter",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ recoverProds[p.id] = struct{}{}
+ default:
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidName,
+ Detail: fmt.Sprintf("invalid directive name '%v'", dir.Name),
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue LOOP_RHS
+ }
+ }
+ }
+ }
+
+ return &productionsAndActions{
+ prods: prods,
+ augStartSym: augStartSym,
+ astActs: astActs,
+ prodPrecsTerm: prodPrecsTerm,
+ prodPrecsOrdSym: prodPrecsOrdSym,
+ prodPrecPoss: prodPrecPoss,
+ recoverProds: recoverProds,
+ }, nil
+}
+
+func (b *GrammarBuilder) genPrecAndAssoc(symTab *symbol.SymbolTableReader, errSym symbol.Symbol, prodsAndActs *productionsAndActions) (*precAndAssoc, error) {
+ termPrec := map[symbol.SymbolNum]int{}
+ termAssoc := map[symbol.SymbolNum]assocType{}
+ ordSymPrec := map[string]int{}
+ {
+ var precGroup []*parser.DirectiveNode
+ for _, dir := range b.AST.Directives {
+ if dir.Name == "prec" {
+ if dir.Parameters == nil || len(dir.Parameters) != 1 || dir.Parameters[0].Group == nil {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "'prec' needs just one directive group",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue
+ }
+ precGroup = dir.Parameters[0].Group
+ continue
+ }
+
+ if dir.Name != "name" && dir.Name != "prec" {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidName,
+ Detail: dir.Name,
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ continue
+ }
+ }
+
+ precN := precMin
+ for _, dir := range precGroup {
+ var assocTy assocType
+ switch dir.Name {
+ case "left":
+ assocTy = assocTypeLeft
+ case "right":
+ assocTy = assocTypeRight
+ case "assign":
+ assocTy = assocTypeNil
+ default:
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidName,
+ Detail: dir.Name,
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ return nil, nil
+ }
+
+ if len(dir.Parameters) == 0 {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "associativity needs at least one symbol",
+ Row: dir.Pos.Row,
+ Col: dir.Pos.Col,
+ })
+ return nil, nil
+ }
+ ASSOC_PARAM_LOOP:
+ for _, p := range dir.Parameters {
+ switch {
+ case p.ID != "":
+ sym, ok := symTab.ToSymbol(p.ID)
+ if !ok {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("'%v' is undefined", p.ID),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ return nil, nil
+ }
+ if sym == errSym {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("'%v' directive cannot be applied to an error symbol", dir.Name),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ return nil, nil
+ }
+ if !sym.IsTerminal() {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: fmt.Sprintf("associativity can take only terminal symbol ('%v' is a non-terminal)", p.ID),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ return nil, nil
+ }
+ if prec, alreadySet := termPrec[sym.Num()]; alreadySet {
+ if prec == precN {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateAssoc,
+ Detail: fmt.Sprintf("'%v' already has the same associativity and precedence", p.ID),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ } else if assoc := termAssoc[sym.Num()]; assoc == assocTy {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateAssoc,
+ Detail: fmt.Sprintf("'%v' already has different precedence", p.ID),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ } else {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateAssoc,
+ Detail: fmt.Sprintf("'%v' already has different associativity and precedence", p.ID),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ }
+ break ASSOC_PARAM_LOOP
+ }
+
+ termPrec[sym.Num()] = precN
+ termAssoc[sym.Num()] = assocTy
+ case p.OrderedSymbol != "":
+ if prec, alreadySet := ordSymPrec[p.OrderedSymbol]; alreadySet {
+ if prec == precN {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateAssoc,
+ Detail: fmt.Sprintf("'$%v' already has the same precedence", p.OrderedSymbol),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ } else {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDuplicateAssoc,
+ Detail: fmt.Sprintf("'$%v' already has different precedence", p.OrderedSymbol),
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ }
+ break ASSOC_PARAM_LOOP
+ }
+
+ ordSymPrec[p.OrderedSymbol] = precN
+ default:
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrDirInvalidParam,
+ Detail: "a parameter must be an ID or an ordered symbol",
+ Row: p.Pos.Row,
+ Col: p.Pos.Col,
+ })
+ return nil, nil
+ }
+ }
+
+ precN++
+ }
+ }
+ if len(b.errs) > 0 {
+ return nil, nil
+ }
+
+ prodPrec := map[productionNum]int{}
+ prodAssoc := map[productionNum]assocType{}
+ for _, prod := range prodsAndActs.prods.getAllProductions() {
+ // A #prec directive changes only precedence, not associativity.
+ if term, ok := prodsAndActs.prodPrecsTerm[prod.id]; ok {
+ if prec, ok := termPrec[term.Num()]; ok {
+ prodPrec[prod.num] = prec
+ prodAssoc[prod.num] = assocTypeNil
+ } else {
+ text, _ := symTab.ToText(term)
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrUndefinedPrec,
+ Detail: text,
+ Row: prodsAndActs.prodPrecPoss[prod.id].Row,
+ Col: prodsAndActs.prodPrecPoss[prod.id].Col,
+ })
+ }
+ } else if ordSym, ok := prodsAndActs.prodPrecsOrdSym[prod.id]; ok {
+ if prec, ok := ordSymPrec[ordSym]; ok {
+ prodPrec[prod.num] = prec
+ prodAssoc[prod.num] = assocTypeNil
+ } else {
+ b.errs = append(b.errs, &verr.SpecError{
+ Cause: semErrUndefinedOrdSym,
+ Detail: fmt.Sprintf("$%v", ordSym),
+ Row: prodsAndActs.prodPrecPoss[prod.id].Row,
+ Col: prodsAndActs.prodPrecPoss[prod.id].Col,
+ })
+ }
+ } else {
+ // A production inherits precedence and associativity from the right-most terminal symbol.
+ mostrightTerm := symbol.SymbolNil
+ for _, sym := range prod.rhs {
+ if !sym.IsTerminal() {
+ continue
+ }
+ mostrightTerm = sym
+ }
+ if !mostrightTerm.IsNil() {
+ prodPrec[prod.num] = termPrec[mostrightTerm.Num()]
+ prodAssoc[prod.num] = termAssoc[mostrightTerm.Num()]
+ }
+ }
+ }
+ if len(b.errs) > 0 {
+ return nil, nil
+ }
+
+ return &precAndAssoc{
+ termPrec: termPrec,
+ termAssoc: termAssoc,
+ prodPrec: prodPrec,
+ prodAssoc: prodAssoc,
+ }, nil
+}
+
+func compile(gram *Grammar, opts ...BuildOption) (*spec.CompiledGrammar, *spec.Report, error) {
+ config := &buildConfig{}
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ lexSpec, err, cErrs := lexical.Compile(gram.lexSpec, lexical.CompressionLevelMax)
+ if err != nil {
+ if len(cErrs) > 0 {
+ var b strings.Builder
+ writeCompileError(&b, cErrs[0])
+ for _, cerr := range cErrs[1:] {
+ fmt.Fprintf(&b, "\n")
+ writeCompileError(&b, cerr)
+ }
+ return nil, nil, fmt.Errorf(b.String())
+ }
+ return nil, nil, err
+ }
+
+ kind2Term := make([]int, len(lexSpec.KindNames))
+ for i, k := range lexSpec.KindNames {
+ if k == spec.LexKindNameNil {
+ kind2Term[spec.LexKindIDNil] = symbol.SymbolNil.Num().Int()
+ continue
+ }
+
+ sym, ok := gram.symbolTable.ToSymbol(k.String())
+ if !ok {
+ return nil, nil, fmt.Errorf("terminal symbol '%v' was not found in a symbol table", k)
+ }
+ kind2Term[i] = sym.Num().Int()
+ }
+
+ termTexts, err := gram.symbolTable.TerminalTexts()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ var termSkip []int
+ {
+ r := gram.symbolTable.Reader()
+ // I want to use gram.symbolTable.terminalSymbols() here instead of gram.symbolTable.terminalTexts(),
+ // but gram.symbolTable.terminalSymbols() is different in length from terminalTexts
+ // because it does not contain a predefined symbol, like EOF.
+ // Therefore, we use terminalTexts, although it takes more time to lookup for symbols.
+ termSkip = make([]int, len(termTexts))
+ for _, t := range termTexts {
+ s, _ := r.ToSymbol(t)
+ for _, sk := range gram.skipSymbols {
+ if s != sk {
+ continue
+ }
+ termSkip[s.Num()] = 1
+ break
+ }
+ }
+ }
+
+ nonTerms, err := gram.symbolTable.NonTerminalTexts()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ firstSet, err := genFirstSet(gram.productionSet)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ lr0, err := genLR0Automaton(gram.productionSet, gram.augmentedStartSymbol, gram.errorSymbol)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ var tab *ParsingTable
+ var report *spec.Report
+ {
+ lalr1, err := genLALR1Automaton(lr0, gram.productionSet, firstSet)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ b := &lrTableBuilder{
+ automaton: lalr1.lr0Automaton,
+ prods: gram.productionSet,
+ termCount: len(termTexts),
+ nonTermCount: len(nonTerms),
+ symTab: gram.symbolTable,
+ precAndAssoc: gram.precAndAssoc,
+ }
+ tab, err = b.build()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if config.isReportingEnabled {
+ report, err = b.genReport(tab, gram)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+ }
+
+ action := make([]int, len(tab.actionTable))
+ for i, e := range tab.actionTable {
+ action[i] = int(e)
+ }
+ goTo := make([]int, len(tab.goToTable))
+ for i, e := range tab.goToTable {
+ goTo[i] = int(e)
+ }
+
+ lhsSyms := make([]int, len(gram.productionSet.getAllProductions())+1)
+ altSymCounts := make([]int, len(gram.productionSet.getAllProductions())+1)
+ recoverProds := make([]int, len(gram.productionSet.getAllProductions())+1)
+ astActEnties := make([][]int, len(gram.productionSet.getAllProductions())+1)
+ for _, p := range gram.productionSet.getAllProductions() {
+ lhsSyms[p.num] = p.lhs.Num().Int()
+ altSymCounts[p.num] = p.rhsLen
+
+ if _, ok := gram.recoverProductions[p.id]; ok {
+ recoverProds[p.num] = 1
+ }
+
+ astAct, ok := gram.astActions[p.id]
+ if !ok {
+ continue
+ }
+ astActEntry := make([]int, len(astAct))
+ for i, e := range astAct {
+ if e.expansion {
+ astActEntry[i] = e.position * -1
+ } else {
+ astActEntry[i] = e.position
+ }
+ }
+ astActEnties[p.num] = astActEntry
+ }
+
+ return &spec.CompiledGrammar{
+ Name: gram.name,
+ Lexical: lexSpec,
+ Syntactic: &spec.SyntacticSpec{
+ Action: action,
+ GoTo: goTo,
+ StateCount: tab.stateCount,
+ InitialState: tab.InitialState.Int(),
+ StartProduction: productionNumStart.Int(),
+ LHSSymbols: lhsSyms,
+ AlternativeSymbolCounts: altSymCounts,
+ Terminals: termTexts,
+ TerminalCount: tab.terminalCount,
+ TerminalSkip: termSkip,
+ KindToTerminal: kind2Term,
+ NonTerminals: nonTerms,
+ NonTerminalCount: tab.nonTerminalCount,
+ EOFSymbol: symbol.SymbolEOF.Num().Int(),
+ ErrorSymbol: gram.errorSymbol.Num().Int(),
+ ErrorTrapperStates: tab.errorTrapperStates,
+ RecoverProductions: recoverProds,
+ },
+ ASTAction: &spec.ASTAction{
+ Entries: astActEnties,
+ },
+ }, report, nil
+}
+
+func writeCompileError(w io.Writer, cErr *lexical.CompileError) {
+ if cErr.Fragment {
+ fmt.Fprintf(w, "fragment ")
+ }
+ fmt.Fprintf(w, "%v: %v", cErr.Kind, cErr.Cause)
+ if cErr.Detail != "" {
+ fmt.Fprintf(w, ": %v", cErr.Detail)
+ }
+}
diff --git a/src/urubu/grammar/item.go b/src/urubu/grammar/item.go
new file mode 100644
index 0000000..6c5fe42
--- /dev/null
+++ b/src/urubu/grammar/item.go
@@ -0,0 +1,206 @@
+package grammar
+
+import (
+ "crypto/sha256"
+ "encoding/binary"
+ "fmt"
+ "sort"
+ "strconv"
+
+ "urubu/grammar/symbol"
+)
+
+type lrItemID [32]byte
+
+func (id lrItemID) String() string {
+ return fmt.Sprintf("%x", id.num())
+}
+
+func (id lrItemID) num() uint32 {
+ return binary.LittleEndian.Uint32(id[:])
+}
+
+type lookAhead struct {
+ symbols map[symbol.Symbol]struct{}
+
+ // When propagation is true, an item propagates look-ahead symbols to other items.
+ propagation bool
+}
+
+type lrItem struct {
+ id lrItemID
+ prod productionID
+
+ // E → E + T
+ //
+ // Dot | Dotted Symbol | Item
+ // ----+---------------+------------
+ // 0 | E | E →・E + T
+ // 1 | + | E → E・+ T
+ // 2 | T | E → E +・T
+ // 3 | Nil | E → E + T・
+ dot int
+ dottedSymbol symbol.Symbol
+
+ // When initial is true, the LHS of the production is the augmented start symbol and dot is 0.
+ // It looks like S' →・S.
+ initial bool
+
+ // When reducible is true, the item looks like E → E + T・.
+ reducible bool
+
+ // When kernel is true, the item is kernel item.
+ kernel bool
+
+ // lookAhead stores look-ahead symbols, and they are terminal symbols.
+ // The item is reducible only when the look-ahead symbols appear as the next input symbol.
+ lookAhead lookAhead
+}
+
+func newLR0Item(prod *production, dot int) (*lrItem, error) {
+ if prod == nil {
+ return nil, fmt.Errorf("production must be non-nil")
+ }
+
+ if dot < 0 || dot > prod.rhsLen {
+ return nil, fmt.Errorf("dot must be between 0 and %v", prod.rhsLen)
+ }
+
+ var id lrItemID
+ {
+ b := []byte{}
+ b = append(b, prod.id[:]...)
+ bDot := make([]byte, 8)
+ binary.LittleEndian.PutUint64(bDot, uint64(dot))
+ b = append(b, bDot...)
+ id = sha256.Sum256(b)
+ }
+
+ dottedSymbol := symbol.SymbolNil
+ if dot < prod.rhsLen {
+ dottedSymbol = prod.rhs[dot]
+ }
+
+ initial := false
+ if prod.lhs.IsStart() && dot == 0 {
+ initial = true
+ }
+
+ reducible := false
+ if dot == prod.rhsLen {
+ reducible = true
+ }
+
+ kernel := false
+ if initial || dot > 0 {
+ kernel = true
+ }
+
+ item := &lrItem{
+ id: id,
+ prod: prod.id,
+ dot: dot,
+ dottedSymbol: dottedSymbol,
+ initial: initial,
+ reducible: reducible,
+ kernel: kernel,
+ }
+
+ return item, nil
+}
+
+type kernelID [32]byte
+
+func (id kernelID) String() string {
+ return fmt.Sprintf("%x", binary.LittleEndian.Uint32(id[:]))
+}
+
+type kernel struct {
+ id kernelID
+ items []*lrItem
+}
+
+func newKernel(items []*lrItem) (*kernel, error) {
+ if len(items) == 0 {
+ return nil, fmt.Errorf("a kernel need at least one item")
+ }
+
+ // Remove duplicates from items.
+ var sortedItems []*lrItem
+ {
+ m := map[lrItemID]*lrItem{}
+ for _, item := range items {
+ if !item.kernel {
+ return nil, fmt.Errorf("not a kernel item: %v", item)
+ }
+ m[item.id] = item
+ }
+ sortedItems = []*lrItem{}
+ for _, item := range m {
+ sortedItems = append(sortedItems, item)
+ }
+ sort.Slice(sortedItems, func(i, j int) bool {
+ return sortedItems[i].id.num() < sortedItems[j].id.num()
+ })
+ }
+
+ var id kernelID
+ {
+ b := []byte{}
+ for _, item := range sortedItems {
+ b = append(b, item.id[:]...)
+ }
+ id = sha256.Sum256(b)
+ }
+
+ return &kernel{
+ id: id,
+ items: sortedItems,
+ }, nil
+}
+
+type stateNum int
+
+const stateNumInitial = stateNum(0)
+
+func (n stateNum) Int() int {
+ return int(n)
+}
+
+func (n stateNum) String() string {
+ return strconv.Itoa(int(n))
+}
+
+func (n stateNum) next() stateNum {
+ return stateNum(n + 1)
+}
+
+type lrState struct {
+ *kernel
+ num stateNum
+ next map[symbol.Symbol]kernelID
+ reducible map[productionID]struct{}
+
+ // emptyProdItems stores items that have an empty production like `p → ε` and is reducible.
+ // Thus the items emptyProdItems stores are like `p → ・ε`. emptyProdItems is needed to store
+ // look-ahead symbols because the kernel items don't include these items.
+ //
+ // For instance, we have the following productions, and A is a terminal symbol.
+ //
+ // s' → s
+ // s → A | ε
+ //
+ // CLOSURE({s' → ・s}) generates the following closure, but the kernel of this closure doesn't
+ // include `s → ・ε`.
+ //
+ // s' → ・s
+ // s → ・A
+ // s → ・ε
+ emptyProdItems []*lrItem
+
+ // When isErrorTrapper is `true`, the item can shift the `error` symbol. The item has the following form.
+ // The `α` and `β` can be empty.
+ //
+ // A → α・error β
+ isErrorTrapper bool
+}
diff --git a/src/urubu/grammar/lalr1.go b/src/urubu/grammar/lalr1.go
new file mode 100644
index 0000000..8373568
--- /dev/null
+++ b/src/urubu/grammar/lalr1.go
@@ -0,0 +1,318 @@
+package grammar
+
+import (
+ "fmt"
+
+ "urubu/grammar/symbol"
+)
+
+type stateAndLRItem struct {
+ kernelID kernelID
+ itemID lrItemID
+}
+
+type propagation struct {
+ src *stateAndLRItem
+ dest []*stateAndLRItem
+}
+
+type lalr1Automaton struct {
+ *lr0Automaton
+}
+
+func genLALR1Automaton(lr0 *lr0Automaton, prods *productionSet, first *firstSet) (*lalr1Automaton, error) {
+ // Set the look-ahead symbol <EOF> to the initial item: [S' → ・S, $]
+ iniState := lr0.states[lr0.initialState]
+ iniState.items[0].lookAhead.symbols = map[symbol.Symbol]struct{}{
+ symbol.SymbolEOF: {},
+ }
+
+ var props []*propagation
+ for _, state := range lr0.states {
+ for _, kItem := range state.items {
+ items, err := genLALR1Closure(kItem, prods, first)
+ if err != nil {
+ return nil, err
+ }
+
+ kItem.lookAhead.propagation = true
+
+ var propDests []*stateAndLRItem
+ for _, item := range items {
+ if item.reducible {
+ p, ok := prods.findByID(item.prod)
+ if !ok {
+ return nil, fmt.Errorf("production not found: %v", item.prod)
+ }
+
+ if p.isEmpty() {
+ var reducibleItem *lrItem
+ for _, it := range state.emptyProdItems {
+ if it.id != item.id {
+ continue
+ }
+
+ reducibleItem = it
+ break
+ }
+ if reducibleItem == nil {
+ return nil, fmt.Errorf("reducible item not found: %v", item.id)
+ }
+ if reducibleItem.lookAhead.symbols == nil {
+ reducibleItem.lookAhead.symbols = map[symbol.Symbol]struct{}{}
+ }
+ for a := range item.lookAhead.symbols {
+ reducibleItem.lookAhead.symbols[a] = struct{}{}
+ }
+
+ propDests = append(propDests, &stateAndLRItem{
+ kernelID: state.id,
+ itemID: item.id,
+ })
+ }
+
+ continue
+ }
+
+ nextKID := state.next[item.dottedSymbol]
+ var nextItemID lrItemID
+ {
+ p, ok := prods.findByID(item.prod)
+ if !ok {
+ return nil, fmt.Errorf("production not found: %v", item.prod)
+ }
+ it, err := newLR0Item(p, item.dot+1)
+ if err != nil {
+ return nil, fmt.Errorf("failed to generate an item ID: %v", err)
+ }
+ nextItemID = it.id
+ }
+
+ if item.lookAhead.propagation {
+ propDests = append(propDests, &stateAndLRItem{
+ kernelID: nextKID,
+ itemID: nextItemID,
+ })
+ } else {
+ nextState := lr0.states[nextKID]
+ var nextItem *lrItem
+ for _, it := range nextState.items {
+ if it.id != nextItemID {
+ continue
+ }
+ nextItem = it
+ break
+ }
+ if nextItem == nil {
+ return nil, fmt.Errorf("item not found: %v", nextItemID)
+ }
+
+ if nextItem.lookAhead.symbols == nil {
+ nextItem.lookAhead.symbols = map[symbol.Symbol]struct{}{}
+ }
+
+ for a := range item.lookAhead.symbols {
+ nextItem.lookAhead.symbols[a] = struct{}{}
+ }
+ }
+ }
+ if len(propDests) == 0 {
+ continue
+ }
+
+ props = append(props, &propagation{
+ src: &stateAndLRItem{
+ kernelID: state.id,
+ itemID: kItem.id,
+ },
+ dest: propDests,
+ })
+ }
+ }
+
+ err := propagateLookAhead(lr0, props)
+ if err != nil {
+ return nil, fmt.Errorf("failed to propagate look-ahead symbols: %v", err)
+ }
+
+ return &lalr1Automaton{
+ lr0Automaton: lr0,
+ }, nil
+}
+
+func genLALR1Closure(srcItem *lrItem, prods *productionSet, first *firstSet) ([]*lrItem, error) {
+ items := []*lrItem{}
+ knownItems := map[lrItemID]map[symbol.Symbol]struct{}{}
+ knownItemsProp := map[lrItemID]struct{}{}
+ uncheckedItems := []*lrItem{}
+ items = append(items, srcItem)
+ uncheckedItems = append(uncheckedItems, srcItem)
+ for len(uncheckedItems) > 0 {
+ nextUncheckedItems := []*lrItem{}
+ for _, item := range uncheckedItems {
+ if item.dottedSymbol.IsTerminal() {
+ continue
+ }
+
+ p, ok := prods.findByID(item.prod)
+ if !ok {
+ return nil, fmt.Errorf("production not found: %v", item.prod)
+ }
+
+ var fstSyms []symbol.Symbol
+ var isFstNullable bool
+ {
+ fst, err := first.find(p, item.dot+1)
+ if err != nil {
+ return nil, err
+ }
+
+ fstSyms = make([]symbol.Symbol, len(fst.symbols))
+ i := 0
+ for s := range fst.symbols {
+ fstSyms[i] = s
+ i++
+ }
+ if fst.empty {
+ isFstNullable = true
+ }
+ }
+
+ ps, _ := prods.findByLHS(item.dottedSymbol)
+ for _, prod := range ps {
+ var lookAhead []symbol.Symbol
+ {
+ var lookAheadCount int
+ if isFstNullable {
+ lookAheadCount = len(fstSyms) + len(item.lookAhead.symbols)
+ } else {
+ lookAheadCount = len(fstSyms)
+ }
+
+ lookAhead = make([]symbol.Symbol, lookAheadCount)
+ i := 0
+ for _, s := range fstSyms {
+ lookAhead[i] = s
+ i++
+ }
+ if isFstNullable {
+ for a := range item.lookAhead.symbols {
+ lookAhead[i] = a
+ i++
+ }
+ }
+ }
+
+ for _, a := range lookAhead {
+ newItem, err := newLR0Item(prod, 0)
+ if err != nil {
+ return nil, err
+ }
+ if items, exist := knownItems[newItem.id]; exist {
+ if _, exist := items[a]; exist {
+ continue
+ }
+ }
+
+ newItem.lookAhead.symbols = map[symbol.Symbol]struct{}{
+ a: {},
+ }
+
+ items = append(items, newItem)
+ if knownItems[newItem.id] == nil {
+ knownItems[newItem.id] = map[symbol.Symbol]struct{}{}
+ }
+ knownItems[newItem.id][a] = struct{}{}
+ nextUncheckedItems = append(nextUncheckedItems, newItem)
+ }
+
+ if isFstNullable {
+ newItem, err := newLR0Item(prod, 0)
+ if err != nil {
+ return nil, err
+ }
+ if _, exist := knownItemsProp[newItem.id]; exist {
+ continue
+ }
+
+ newItem.lookAhead.propagation = true
+
+ items = append(items, newItem)
+ knownItemsProp[newItem.id] = struct{}{}
+ nextUncheckedItems = append(nextUncheckedItems, newItem)
+ }
+ }
+ }
+ uncheckedItems = nextUncheckedItems
+ }
+
+ return items, nil
+}
+
+func propagateLookAhead(lr0 *lr0Automaton, props []*propagation) error {
+ for {
+ changed := false
+ for _, prop := range props {
+ srcState, ok := lr0.states[prop.src.kernelID]
+ if !ok {
+ return fmt.Errorf("source state not found: %v", prop.src.kernelID)
+ }
+ var srcItem *lrItem
+ for _, item := range srcState.items {
+ if item.id != prop.src.itemID {
+ continue
+ }
+ srcItem = item
+ break
+ }
+ if srcItem == nil {
+ return fmt.Errorf("source item not found: %v", prop.src.itemID)
+ }
+
+ for _, dest := range prop.dest {
+ destState, ok := lr0.states[dest.kernelID]
+ if !ok {
+ return fmt.Errorf("destination state not found: %v", dest.kernelID)
+ }
+ var destItem *lrItem
+ for _, item := range destState.items {
+ if item.id != dest.itemID {
+ continue
+ }
+ destItem = item
+ break
+ }
+ if destItem == nil {
+ for _, item := range destState.emptyProdItems {
+ if item.id != dest.itemID {
+ continue
+ }
+ destItem = item
+ break
+ }
+ if destItem == nil {
+ return fmt.Errorf("destination item not found: %v", dest.itemID)
+ }
+ }
+
+ for a := range srcItem.lookAhead.symbols {
+ if _, ok := destItem.lookAhead.symbols[a]; ok {
+ continue
+ }
+
+ if destItem.lookAhead.symbols == nil {
+ destItem.lookAhead.symbols = map[symbol.Symbol]struct{}{}
+ }
+
+ destItem.lookAhead.symbols[a] = struct{}{}
+ changed = true
+ }
+ }
+ }
+ if !changed {
+ break
+ }
+ }
+
+ return nil
+}
diff --git a/src/urubu/grammar/lexical/compiler.go b/src/urubu/grammar/lexical/compiler.go
new file mode 100644
index 0000000..637018a
--- /dev/null
+++ b/src/urubu/grammar/lexical/compiler.go
@@ -0,0 +1,413 @@
+package lexical
+
+import (
+ "bytes"
+ "fmt"
+
+ "urubu/compressor"
+ "urubu/grammar/lexical/dfa"
+ psr "urubu/grammar/lexical/parser"
+ spec "urubu/spec/grammar"
+)
+
+type CompileError struct {
+ Kind spec.LexKindName
+ Fragment bool
+ Cause error
+ Detail string
+}
+
+func Compile(lexspec *LexSpec, compLv int) (*spec.LexicalSpec, error, []*CompileError) {
+ err := lexspec.Validate()
+ if err != nil {
+ return nil, fmt.Errorf("invalid lexical specification:\n%w", err), nil
+ }
+
+ modeEntries, modeNames, modeName2ID, fragmetns := groupEntriesByLexMode(lexspec.Entries)
+
+ modeSpecs := []*spec.CompiledLexModeSpec{
+ nil,
+ }
+ for i, es := range modeEntries[1:] {
+ modeName := modeNames[i+1]
+ modeSpec, err, cerrs := compile(es, modeName2ID, fragmetns, compLv)
+ if err != nil {
+ return nil, fmt.Errorf("failed to compile in %v mode: %w", modeName, err), cerrs
+ }
+ modeSpecs = append(modeSpecs, modeSpec)
+ }
+
+ var kindNames []spec.LexKindName
+ var name2ID map[spec.LexKindName]spec.LexKindID
+ {
+ name2ID = map[spec.LexKindName]spec.LexKindID{}
+ id := spec.LexKindIDMin
+ for _, modeSpec := range modeSpecs[1:] {
+ for _, name := range modeSpec.KindNames[1:] {
+ if _, ok := name2ID[name]; ok {
+ continue
+ }
+ name2ID[name] = id
+ id++
+ }
+ }
+
+ kindNames = make([]spec.LexKindName, len(name2ID)+1)
+ for name, id := range name2ID {
+ kindNames[id] = name
+ }
+ }
+
+ var kindIDs [][]spec.LexKindID
+ {
+ kindIDs = make([][]spec.LexKindID, len(modeSpecs))
+ for i, modeSpec := range modeSpecs[1:] {
+ ids := make([]spec.LexKindID, len(modeSpec.KindNames))
+ for modeID, name := range modeSpec.KindNames {
+ if modeID == 0 {
+ continue
+ }
+ ids[modeID] = name2ID[name]
+ }
+ kindIDs[i+1] = ids
+ }
+ }
+
+ return &spec.LexicalSpec{
+ InitialModeID: spec.LexModeIDDefault,
+ ModeNames: modeNames,
+ KindNames: kindNames,
+ KindIDs: kindIDs,
+ CompressionLevel: compLv,
+ Specs: modeSpecs,
+ }, nil, nil
+}
+
+func groupEntriesByLexMode(entries []*LexEntry) ([][]*LexEntry, []spec.LexModeName, map[spec.LexModeName]spec.LexModeID, map[spec.LexKindName]*LexEntry) {
+ modeNames := []spec.LexModeName{
+ spec.LexModeNameNil,
+ spec.LexModeNameDefault,
+ }
+ modeName2ID := map[spec.LexModeName]spec.LexModeID{
+ spec.LexModeNameNil: spec.LexModeIDNil,
+ spec.LexModeNameDefault: spec.LexModeIDDefault,
+ }
+ lastModeID := spec.LexModeIDDefault
+ modeEntries := [][]*LexEntry{
+ nil,
+ {},
+ }
+ fragments := map[spec.LexKindName]*LexEntry{}
+ for _, e := range entries {
+ if e.Fragment {
+ fragments[e.Kind] = e
+ continue
+ }
+ ms := e.Modes
+ if len(ms) == 0 {
+ ms = []spec.LexModeName{
+ spec.LexModeNameDefault,
+ }
+ }
+ for _, modeName := range ms {
+ modeID, ok := modeName2ID[modeName]
+ if !ok {
+ modeID = lastModeID + 1
+ lastModeID = modeID
+ modeName2ID[modeName] = modeID
+ modeNames = append(modeNames, modeName)
+ modeEntries = append(modeEntries, []*LexEntry{})
+ }
+ modeEntries[modeID] = append(modeEntries[modeID], e)
+ }
+ }
+ return modeEntries, modeNames, modeName2ID, fragments
+}
+
+func compile(
+ entries []*LexEntry,
+ modeName2ID map[spec.LexModeName]spec.LexModeID,
+ fragments map[spec.LexKindName]*LexEntry,
+ compLv int,
+) (*spec.CompiledLexModeSpec, error, []*CompileError) {
+ var kindNames []spec.LexKindName
+ kindIDToName := map[spec.LexModeKindID]spec.LexKindName{}
+ var patterns map[spec.LexModeKindID][]byte
+ {
+ kindNames = append(kindNames, spec.LexKindNameNil)
+ patterns = map[spec.LexModeKindID][]byte{}
+ for i, e := range entries {
+ kindID := spec.LexModeKindID(i + 1)
+
+ kindNames = append(kindNames, e.Kind)
+ kindIDToName[kindID] = e.Kind
+ patterns[kindID] = []byte(e.Pattern)
+ }
+ }
+
+ push := []spec.LexModeID{
+ spec.LexModeIDNil,
+ }
+ pop := []int{
+ 0,
+ }
+ for _, e := range entries {
+ pushV := spec.LexModeIDNil
+ if e.Push != "" {
+ pushV = modeName2ID[e.Push]
+ }
+ push = append(push, pushV)
+ popV := 0
+ if e.Pop {
+ popV = 1
+ }
+ pop = append(pop, popV)
+ }
+
+ fragmentPatterns := map[spec.LexKindName][]byte{}
+ for k, e := range fragments {
+ fragmentPatterns[k] = []byte(e.Pattern)
+ }
+
+ fragmentCPTrees := make(map[spec.LexKindName]psr.CPTree, len(fragmentPatterns))
+ {
+ var cerrs []*CompileError
+ for kind, pat := range fragmentPatterns {
+ p := psr.NewParser(kind, bytes.NewReader(pat))
+ t, err := p.Parse()
+ if err != nil {
+ if err == psr.ParseErr {
+ detail, cause := p.Error()
+ cerrs = append(cerrs, &CompileError{
+ Kind: kind,
+ Fragment: true,
+ Cause: cause,
+ Detail: detail,
+ })
+ } else {
+ cerrs = append(cerrs, &CompileError{
+ Kind: kind,
+ Fragment: true,
+ Cause: err,
+ })
+ }
+ continue
+ }
+ fragmentCPTrees[kind] = t
+ }
+ if len(cerrs) > 0 {
+ return nil, fmt.Errorf("compile error"), cerrs
+ }
+
+ err := psr.CompleteFragments(fragmentCPTrees)
+ if err != nil {
+ if err == psr.ParseErr {
+ for _, frag := range fragmentCPTrees {
+ kind, frags, err := frag.Describe()
+ if err != nil {
+ return nil, err, nil
+ }
+
+ cerrs = append(cerrs, &CompileError{
+ Kind: kind,
+ Fragment: true,
+ Cause: fmt.Errorf("fragment contains undefined fragments or cycles"),
+ Detail: fmt.Sprintf("%v", frags),
+ })
+ }
+
+ return nil, fmt.Errorf("compile error"), cerrs
+ }
+
+ return nil, err, nil
+ }
+ }
+
+ cpTrees := map[spec.LexModeKindID]psr.CPTree{}
+ {
+ pats := make([]*psr.PatternEntry, len(patterns)+1)
+ pats[spec.LexModeKindIDNil] = &psr.PatternEntry{
+ ID: spec.LexModeKindIDNil,
+ }
+ for id, pattern := range patterns {
+ pats[id] = &psr.PatternEntry{
+ ID: id,
+ Pattern: pattern,
+ }
+ }
+
+ var cerrs []*CompileError
+ for _, pat := range pats {
+ if pat.ID == spec.LexModeKindIDNil {
+ continue
+ }
+
+ p := psr.NewParser(kindIDToName[pat.ID], bytes.NewReader(pat.Pattern))
+ t, err := p.Parse()
+ if err != nil {
+ if err == psr.ParseErr {
+ detail, cause := p.Error()
+ cerrs = append(cerrs, &CompileError{
+ Kind: kindIDToName[pat.ID],
+ Fragment: false,
+ Cause: cause,
+ Detail: detail,
+ })
+ } else {
+ cerrs = append(cerrs, &CompileError{
+ Kind: kindIDToName[pat.ID],
+ Fragment: false,
+ Cause: err,
+ })
+ }
+ continue
+ }
+
+ complete, err := psr.ApplyFragments(t, fragmentCPTrees)
+ if err != nil {
+ return nil, err, nil
+ }
+ if !complete {
+ _, frags, err := t.Describe()
+ if err != nil {
+ return nil, err, nil
+ }
+
+ cerrs = append(cerrs, &CompileError{
+ Kind: kindIDToName[pat.ID],
+ Fragment: false,
+ Cause: fmt.Errorf("pattern contains undefined fragments"),
+ Detail: fmt.Sprintf("%v", frags),
+ })
+ continue
+ }
+
+ cpTrees[pat.ID] = t
+ }
+ if len(cerrs) > 0 {
+ return nil, fmt.Errorf("compile error"), cerrs
+ }
+ }
+
+ var tranTab *spec.TransitionTable
+ {
+ root, symTab, err := dfa.ConvertCPTreeToByteTree(cpTrees)
+ if err != nil {
+ return nil, err, nil
+ }
+ d := dfa.GenDFA(root, symTab)
+ tranTab, err = dfa.GenTransitionTable(d)
+ if err != nil {
+ return nil, err, nil
+ }
+ }
+
+ var err error
+ switch compLv {
+ case 2:
+ tranTab, err = compressTransitionTableLv2(tranTab)
+ if err != nil {
+ return nil, err, nil
+ }
+ case 1:
+ tranTab, err = compressTransitionTableLv1(tranTab)
+ if err != nil {
+ return nil, err, nil
+ }
+ }
+
+ return &spec.CompiledLexModeSpec{
+ KindNames: kindNames,
+ Push: push,
+ Pop: pop,
+ DFA: tranTab,
+ }, nil, nil
+}
+
+const (
+ CompressionLevelMin = 0
+ CompressionLevelMax = 2
+)
+
+func compressTransitionTableLv2(tranTab *spec.TransitionTable) (*spec.TransitionTable, error) {
+ ueTab := compressor.NewUniqueEntriesTable()
+ {
+ orig, err := compressor.NewOriginalTable(convertStateIDSliceToIntSlice(tranTab.UncompressedTransition), tranTab.ColCount)
+ if err != nil {
+ return nil, err
+ }
+ err = ueTab.Compress(orig)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ rdTab := compressor.NewRowDisplacementTable(0)
+ {
+ orig, err := compressor.NewOriginalTable(ueTab.UniqueEntries, ueTab.OriginalColCount)
+ if err != nil {
+ return nil, err
+ }
+ err = rdTab.Compress(orig)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ tranTab.Transition = &spec.UniqueEntriesTable{
+ UniqueEntries: &spec.RowDisplacementTable{
+ OriginalRowCount: rdTab.OriginalRowCount,
+ OriginalColCount: rdTab.OriginalColCount,
+ EmptyValue: spec.StateIDNil,
+ Entries: convertIntSliceToStateIDSlice(rdTab.Entries),
+ Bounds: rdTab.Bounds,
+ RowDisplacement: rdTab.RowDisplacement,
+ },
+ RowNums: ueTab.RowNums,
+ OriginalRowCount: ueTab.OriginalRowCount,
+ OriginalColCount: ueTab.OriginalColCount,
+ }
+ tranTab.UncompressedTransition = nil
+
+ return tranTab, nil
+}
+
+func compressTransitionTableLv1(tranTab *spec.TransitionTable) (*spec.TransitionTable, error) {
+ ueTab := compressor.NewUniqueEntriesTable()
+ {
+ orig, err := compressor.NewOriginalTable(convertStateIDSliceToIntSlice(tranTab.UncompressedTransition), tranTab.ColCount)
+ if err != nil {
+ return nil, err
+ }
+ err = ueTab.Compress(orig)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ tranTab.Transition = &spec.UniqueEntriesTable{
+ UncompressedUniqueEntries: convertIntSliceToStateIDSlice(ueTab.UniqueEntries),
+ RowNums: ueTab.RowNums,
+ OriginalRowCount: ueTab.OriginalRowCount,
+ OriginalColCount: ueTab.OriginalColCount,
+ }
+ tranTab.UncompressedTransition = nil
+
+ return tranTab, nil
+}
+
+func convertStateIDSliceToIntSlice(s []spec.StateID) []int {
+ is := make([]int, len(s))
+ for i, v := range s {
+ is[i] = v.Int()
+ }
+ return is
+}
+
+func convertIntSliceToStateIDSlice(s []int) []spec.StateID {
+ ss := make([]spec.StateID, len(s))
+ for i, v := range s {
+ ss[i] = spec.StateID(v)
+ }
+ return ss
+}
diff --git a/src/urubu/grammar/lexical/dfa/dfa.go b/src/urubu/grammar/lexical/dfa/dfa.go
new file mode 100644
index 0000000..48bd8b4
--- /dev/null
+++ b/src/urubu/grammar/lexical/dfa/dfa.go
@@ -0,0 +1,173 @@
+package dfa
+
+import (
+ "sort"
+
+ spec "urubu/spec/grammar"
+)
+
+type symbolTable struct {
+ symPos2Byte map[symbolPosition]byteRange
+ endPos2ID map[symbolPosition]spec.LexModeKindID
+}
+
+func genSymbolTable(root byteTree) *symbolTable {
+ symTab := &symbolTable{
+ symPos2Byte: map[symbolPosition]byteRange{},
+ endPos2ID: map[symbolPosition]spec.LexModeKindID{},
+ }
+ return genSymTab(symTab, root)
+}
+
+func genSymTab(symTab *symbolTable, node byteTree) *symbolTable {
+ if node == nil {
+ return symTab
+ }
+
+ switch n := node.(type) {
+ case *symbolNode:
+ symTab.symPos2Byte[n.pos] = byteRange{
+ from: n.from,
+ to: n.to,
+ }
+ case *endMarkerNode:
+ symTab.endPos2ID[n.pos] = n.id
+ default:
+ left, right := node.children()
+ genSymTab(symTab, left)
+ genSymTab(symTab, right)
+ }
+ return symTab
+}
+
+type DFA struct {
+ States []string
+ InitialState string
+ AcceptingStatesTable map[string]spec.LexModeKindID
+ TransitionTable map[string][256]string
+}
+
+func GenDFA(root byteTree, symTab *symbolTable) *DFA {
+ initialState := root.first()
+ initialStateHash := initialState.hash()
+ stateMap := map[string]*symbolPositionSet{
+ initialStateHash: initialState,
+ }
+ tranTab := map[string][256]string{}
+ {
+ follow := genFollowTable(root)
+ unmarkedStates := map[string]*symbolPositionSet{
+ initialStateHash: initialState,
+ }
+ for len(unmarkedStates) > 0 {
+ nextUnmarkedStates := map[string]*symbolPositionSet{}
+ for hash, state := range unmarkedStates {
+ tranTabOfState := [256]*symbolPositionSet{}
+ for _, pos := range state.set() {
+ if pos.isEndMark() {
+ continue
+ }
+ valRange := symTab.symPos2Byte[pos]
+ for symVal := valRange.from; symVal <= valRange.to; symVal++ {
+ if tranTabOfState[symVal] == nil {
+ tranTabOfState[symVal] = newSymbolPositionSet()
+ }
+ tranTabOfState[symVal].merge(follow[pos])
+ }
+ }
+ for _, t := range tranTabOfState {
+ if t == nil {
+ continue
+ }
+ h := t.hash()
+ if _, ok := stateMap[h]; ok {
+ continue
+ }
+ stateMap[h] = t
+ nextUnmarkedStates[h] = t
+ }
+ tabOfState := [256]string{}
+ for v, t := range tranTabOfState {
+ if t == nil {
+ continue
+ }
+ tabOfState[v] = t.hash()
+ }
+ tranTab[hash] = tabOfState
+ }
+ unmarkedStates = nextUnmarkedStates
+ }
+ }
+
+ accTab := map[string]spec.LexModeKindID{}
+ {
+ for h, s := range stateMap {
+ for _, pos := range s.set() {
+ if !pos.isEndMark() {
+ continue
+ }
+ priorID, ok := accTab[h]
+ if !ok {
+ accTab[h] = symTab.endPos2ID[pos]
+ } else {
+ id := symTab.endPos2ID[pos]
+ if id < priorID {
+ accTab[h] = id
+ }
+ }
+ }
+ }
+ }
+
+ var states []string
+ {
+ for s := range stateMap {
+ states = append(states, s)
+ }
+ sort.Slice(states, func(i, j int) bool {
+ return states[i] < states[j]
+ })
+ }
+
+ return &DFA{
+ States: states,
+ InitialState: initialStateHash,
+ AcceptingStatesTable: accTab,
+ TransitionTable: tranTab,
+ }
+}
+
+func GenTransitionTable(dfa *DFA) (*spec.TransitionTable, error) {
+ stateHash2ID := map[string]spec.StateID{}
+ for i, s := range dfa.States {
+ // Since 0 represents an invalid value in a transition table,
+ // assign a number greater than or equal to 1 to states.
+ stateHash2ID[s] = spec.StateID(i + spec.StateIDMin.Int())
+ }
+
+ acc := make([]spec.LexModeKindID, len(dfa.States)+1)
+ for _, s := range dfa.States {
+ id, ok := dfa.AcceptingStatesTable[s]
+ if !ok {
+ continue
+ }
+ acc[stateHash2ID[s]] = id
+ }
+
+ rowCount := len(dfa.States) + 1
+ colCount := 256
+ tran := make([]spec.StateID, rowCount*colCount)
+ for s, tab := range dfa.TransitionTable {
+ for v, to := range tab {
+ tran[stateHash2ID[s].Int()*256+v] = stateHash2ID[to]
+ }
+ }
+
+ return &spec.TransitionTable{
+ InitialStateID: stateHash2ID[dfa.InitialState],
+ AcceptingStates: acc,
+ UncompressedTransition: tran,
+ RowCount: rowCount,
+ ColCount: colCount,
+ }, nil
+}
diff --git a/src/urubu/grammar/lexical/dfa/symbol_position.go b/src/urubu/grammar/lexical/dfa/symbol_position.go
new file mode 100644
index 0000000..f154251
--- /dev/null
+++ b/src/urubu/grammar/lexical/dfa/symbol_position.go
@@ -0,0 +1,182 @@
+package dfa
+
+import (
+ "encoding/binary"
+ "fmt"
+ "strings"
+)
+
+type symbolPosition uint16
+
+const (
+ symbolPositionNil symbolPosition = 0x0000
+
+ symbolPositionMin uint16 = 0x0001
+ symbolPositionMax uint16 = 0x7fff
+
+ symbolPositionMaskSymbol uint16 = 0x0000
+ symbolPositionMaskEndMark uint16 = 0x8000
+
+ symbolPositionMaskValue uint16 = 0x7fff
+)
+
+func newSymbolPosition(n uint16, endMark bool) (symbolPosition, error) {
+ if n < symbolPositionMin || n > symbolPositionMax {
+ return symbolPositionNil, fmt.Errorf("symbol position must be within %v to %v: n: %v, endMark: %v", symbolPositionMin, symbolPositionMax, n, endMark)
+ }
+ if endMark {
+ return symbolPosition(n | symbolPositionMaskEndMark), nil
+ }
+ return symbolPosition(n | symbolPositionMaskSymbol), nil
+}
+
+func (p symbolPosition) String() string {
+ if p.isEndMark() {
+ return fmt.Sprintf("end#%v", uint16(p)&symbolPositionMaskValue)
+ }
+ return fmt.Sprintf("sym#%v", uint16(p)&symbolPositionMaskValue)
+}
+
+func (p symbolPosition) isEndMark() bool {
+ return uint16(p)&symbolPositionMaskEndMark > 1
+}
+
+func (p symbolPosition) describe() (uint16, bool) {
+ v := uint16(p) & symbolPositionMaskValue
+ if p.isEndMark() {
+ return v, true
+ }
+ return v, false
+}
+
+type symbolPositionSet struct {
+ // `s` represents a set of symbol positions.
+ // However, immediately after adding a symbol position, the elements may be duplicated.
+ // When you need an aligned set with no duplicates, you can get such value via the set function.
+ s []symbolPosition
+ sorted bool
+}
+
+func newSymbolPositionSet() *symbolPositionSet {
+ return &symbolPositionSet{
+ s: []symbolPosition{},
+ sorted: false,
+ }
+}
+
+func (s *symbolPositionSet) String() string {
+ if len(s.s) <= 0 {
+ return "{}"
+ }
+ ps := s.sortAndRemoveDuplicates()
+ var b strings.Builder
+ fmt.Fprintf(&b, "{")
+ for i, p := range ps {
+ if i <= 0 {
+ fmt.Fprintf(&b, "%v", p)
+ continue
+ }
+ fmt.Fprintf(&b, ", %v", p)
+ }
+ fmt.Fprintf(&b, "}")
+ return b.String()
+}
+
+func (s *symbolPositionSet) set() []symbolPosition {
+ s.sortAndRemoveDuplicates()
+ return s.s
+}
+
+func (s *symbolPositionSet) add(pos symbolPosition) *symbolPositionSet {
+ s.s = append(s.s, pos)
+ s.sorted = false
+ return s
+}
+
+func (s *symbolPositionSet) merge(t *symbolPositionSet) *symbolPositionSet {
+ s.s = append(s.s, t.s...)
+ s.sorted = false
+ return s
+}
+
+func (s *symbolPositionSet) hash() string {
+ if len(s.s) <= 0 {
+ return ""
+ }
+ sorted := s.sortAndRemoveDuplicates()
+ var buf []byte
+ for _, p := range sorted {
+ b := make([]byte, 8)
+ binary.PutUvarint(b, uint64(p))
+ buf = append(buf, b...)
+ }
+ // Convert to a string to be able to use it as a key of a map.
+ // But note this byte sequence is made from values of symbol positions,
+ // so this is not a well-formed UTF-8 sequence.
+ return string(buf)
+}
+
+func (s *symbolPositionSet) sortAndRemoveDuplicates() []symbolPosition {
+ if s.sorted {
+ return s.s
+ }
+
+ sortSymbolPositions(s.s, 0, len(s.s)-1)
+
+ // Remove duplicates.
+ lastV := s.s[0]
+ nextIdx := 1
+ for _, v := range s.s[1:] {
+ if v == lastV {
+ continue
+ }
+ s.s[nextIdx] = v
+ nextIdx++
+ lastV = v
+ }
+ s.s = s.s[:nextIdx]
+ s.sorted = true
+
+ return s.s
+}
+
+// sortSymbolPositions sorts a slice of symbol positions as it uses quick sort.
+func sortSymbolPositions(ps []symbolPosition, left, right int) {
+ if left >= right {
+ return
+ }
+ var pivot symbolPosition
+ {
+ // Use a median as a pivot.
+ p1 := ps[left]
+ p2 := ps[(left+right)/2]
+ p3 := ps[right]
+ if p1 > p2 {
+ p1, p2 = p2, p1
+ }
+ if p2 > p3 {
+ p2 = p3
+ if p1 > p2 {
+ p2 = p1
+ }
+ }
+ pivot = p2
+ }
+ i := left
+ j := right
+ for i <= j {
+ for ps[i] < pivot {
+ i++
+ }
+ for ps[j] > pivot {
+ j--
+ }
+ if i <= j {
+ ps[i], ps[j] = ps[j], ps[i]
+ i++
+ j--
+ }
+ }
+ sortSymbolPositions(ps, left, j)
+ sortSymbolPositions(ps, i, right)
+}
diff --git a/src/urubu/grammar/lexical/dfa/tree.go b/src/urubu/grammar/lexical/dfa/tree.go
new file mode 100644
index 0000000..8a11aee
--- /dev/null
+++ b/src/urubu/grammar/lexical/dfa/tree.go
@@ -0,0 +1,567 @@
+package dfa
+
+import (
+ "fmt"
+ "io"
+ "sort"
+
+ "urubu/grammar/lexical/parser"
+ spec "urubu/spec/grammar"
+ "urubu/utf8"
+)
+
+type byteTree interface {
+ fmt.Stringer
+ children() (byteTree, byteTree)
+ nullable() bool
+ first() *symbolPositionSet
+ last() *symbolPositionSet
+ clone() byteTree
+}
+
+var (
+ _ byteTree = &symbolNode{}
+ _ byteTree = &endMarkerNode{}
+ _ byteTree = &concatNode{}
+ _ byteTree = &altNode{}
+ _ byteTree = &repeatNode{}
+ _ byteTree = &optionNode{}
+)
+
+type byteRange struct {
+ from byte
+ to byte
+}
+
+type symbolNode struct {
+ byteRange
+ pos symbolPosition
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newSymbolNode(value byte) *symbolNode {
+ return &symbolNode{
+ byteRange: byteRange{
+ from: value,
+ to: value,
+ },
+ pos: symbolPositionNil,
+ }
+}
+
+func newRangeSymbolNode(from, to byte) *symbolNode {
+ return &symbolNode{
+ byteRange: byteRange{
+ from: from,
+ to: to,
+ },
+ pos: symbolPositionNil,
+ }
+}
+
+func (n *symbolNode) String() string {
+ return fmt.Sprintf("symbol: value: %v-%v, pos: %v", n.from, n.to, n.pos)
+}
+
+func (n *symbolNode) children() (byteTree, byteTree) {
+ return nil, nil
+}
+
+func (n *symbolNode) nullable() bool {
+ return false
+}
+
+func (n *symbolNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.add(n.pos)
+ }
+ return n.firstMemo
+}
+
+func (n *symbolNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.add(n.pos)
+ }
+ return n.lastMemo
+}
+
+func (n *symbolNode) clone() byteTree {
+ return newRangeSymbolNode(n.from, n.to)
+}
+
+type endMarkerNode struct {
+ id spec.LexModeKindID
+ pos symbolPosition
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newEndMarkerNode(id spec.LexModeKindID) *endMarkerNode {
+ return &endMarkerNode{
+ id: id,
+ pos: symbolPositionNil,
+ }
+}
+
+func (n *endMarkerNode) String() string {
+ return fmt.Sprintf("end: pos: %v", n.pos)
+}
+
+func (n *endMarkerNode) children() (byteTree, byteTree) {
+ return nil, nil
+}
+
+func (n *endMarkerNode) nullable() bool {
+ return false
+}
+
+func (n *endMarkerNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.add(n.pos)
+ }
+ return n.firstMemo
+}
+
+func (n *endMarkerNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.add(n.pos)
+ }
+ return n.lastMemo
+}
+
+func (n *endMarkerNode) clone() byteTree {
+ return newEndMarkerNode(n.id)
+}
+
+type concatNode struct {
+ left byteTree
+ right byteTree
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newConcatNode(left, right byteTree) *concatNode {
+ return &concatNode{
+ left: left,
+ right: right,
+ }
+}
+
+func (n *concatNode) String() string {
+ return "concat"
+}
+
+func (n *concatNode) children() (byteTree, byteTree) {
+ return n.left, n.right
+}
+
+func (n *concatNode) nullable() bool {
+ return n.left.nullable() && n.right.nullable()
+}
+
+func (n *concatNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.merge(n.left.first())
+ if n.left.nullable() {
+ n.firstMemo.merge(n.right.first())
+ }
+ n.firstMemo.sortAndRemoveDuplicates()
+ }
+ return n.firstMemo
+}
+
+func (n *concatNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.merge(n.right.last())
+ if n.right.nullable() {
+ n.lastMemo.merge(n.left.last())
+ }
+ n.lastMemo.sortAndRemoveDuplicates()
+ }
+ return n.lastMemo
+}
+
+func (n *concatNode) clone() byteTree {
+ return newConcatNode(n.left.clone(), n.right.clone())
+}
+
+type altNode struct {
+ left byteTree
+ right byteTree
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newAltNode(left, right byteTree) *altNode {
+ return &altNode{
+ left: left,
+ right: right,
+ }
+}
+
+func (n *altNode) String() string {
+ return "alt"
+}
+
+func (n *altNode) children() (byteTree, byteTree) {
+ return n.left, n.right
+}
+
+func (n *altNode) nullable() bool {
+ return n.left.nullable() || n.right.nullable()
+}
+
+func (n *altNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.merge(n.left.first())
+ n.firstMemo.merge(n.right.first())
+ n.firstMemo.sortAndRemoveDuplicates()
+ }
+ return n.firstMemo
+}
+
+func (n *altNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.merge(n.left.last())
+ n.lastMemo.merge(n.right.last())
+ n.lastMemo.sortAndRemoveDuplicates()
+ }
+ return n.lastMemo
+}
+
+func (n *altNode) clone() byteTree {
+ return newAltNode(n.left.clone(), n.right.clone())
+}
+
+type repeatNode struct {
+ left byteTree
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newRepeatNode(left byteTree) *repeatNode {
+ return &repeatNode{
+ left: left,
+ }
+}
+
+func (n *repeatNode) String() string {
+ return "repeat"
+}
+
+func (n *repeatNode) children() (byteTree, byteTree) {
+ return n.left, nil
+}
+
+func (n *repeatNode) nullable() bool {
+ return true
+}
+
+func (n *repeatNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.merge(n.left.first())
+ n.firstMemo.sortAndRemoveDuplicates()
+ }
+ return n.firstMemo
+}
+
+func (n *repeatNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.merge(n.left.last())
+ n.lastMemo.sortAndRemoveDuplicates()
+ }
+ return n.lastMemo
+}
+
+func (n *repeatNode) clone() byteTree {
+ return newRepeatNode(n.left.clone())
+}
+
+type optionNode struct {
+ left byteTree
+ firstMemo *symbolPositionSet
+ lastMemo *symbolPositionSet
+}
+
+func newOptionNode(left byteTree) *optionNode {
+ return &optionNode{
+ left: left,
+ }
+}
+
+func (n *optionNode) String() string {
+ return "option"
+}
+
+func (n *optionNode) children() (byteTree, byteTree) {
+ return n.left, nil
+}
+
+func (n *optionNode) nullable() bool {
+ return true
+}
+
+func (n *optionNode) first() *symbolPositionSet {
+ if n.firstMemo == nil {
+ n.firstMemo = newSymbolPositionSet()
+ n.firstMemo.merge(n.left.first())
+ n.firstMemo.sortAndRemoveDuplicates()
+ }
+ return n.firstMemo
+}
+
+func (n *optionNode) last() *symbolPositionSet {
+ if n.lastMemo == nil {
+ n.lastMemo = newSymbolPositionSet()
+ n.lastMemo.merge(n.left.last())
+ n.lastMemo.sortAndRemoveDuplicates()
+ }
+ return n.lastMemo
+}
+
+func (n *optionNode) clone() byteTree {
+ return newOptionNode(n.left.clone())
+}
+
+type followTable map[symbolPosition]*symbolPositionSet
+
+func genFollowTable(root byteTree) followTable {
+ follow := followTable{}
+ calcFollow(follow, root)
+ return follow
+}
+
+func calcFollow(follow followTable, ast byteTree) {
+ if ast == nil {
+ return
+ }
+ left, right := ast.children()
+ calcFollow(follow, left)
+ calcFollow(follow, right)
+ switch n := ast.(type) {
+ case *concatNode:
+ l, r := n.children()
+ for _, p := range l.last().set() {
+ if _, ok := follow[p]; !ok {
+ follow[p] = newSymbolPositionSet()
+ }
+ follow[p].merge(r.first())
+ }
+ case *repeatNode:
+ for _, p := range n.last().set() {
+ if _, ok := follow[p]; !ok {
+ follow[p] = newSymbolPositionSet()
+ }
+ follow[p].merge(n.first())
+ }
+ }
+}
+
+func positionSymbols(node byteTree, n uint16) (uint16, error) {
+ if node == nil {
+ return n, nil
+ }
+
+ l, r := node.children()
+ p := n
+ p, err := positionSymbols(l, p)
+ if err != nil {
+ return p, err
+ }
+ p, err = positionSymbols(r, p)
+ if err != nil {
+ return p, err
+ }
+ switch n := node.(type) {
+ case *symbolNode:
+ n.pos, err = newSymbolPosition(p, false)
+ if err != nil {
+ return p, err
+ }
+ p++
+ case *endMarkerNode:
+ n.pos, err = newSymbolPosition(p, true)
+ if err != nil {
+ return p, err
+ }
+ p++
+ }
+ node.first()
+ node.last()
+ return p, nil
+}
+
+func concat(ts ...byteTree) byteTree {
+ nonNilNodes := []byteTree{}
+ for _, t := range ts {
+ if t == nil {
+ continue
+ }
+ nonNilNodes = append(nonNilNodes, t)
+ }
+ if len(nonNilNodes) <= 0 {
+ return nil
+ }
+ if len(nonNilNodes) == 1 {
+ return nonNilNodes[0]
+ }
+ concat := newConcatNode(nonNilNodes[0], nonNilNodes[1])
+ for _, t := range nonNilNodes[2:] {
+ concat = newConcatNode(concat, t)
+ }
+ return concat
+}
+
+func oneOf(ts ...byteTree) byteTree {
+ nonNilNodes := []byteTree{}
+ for _, t := range ts {
+ if t == nil {
+ continue
+ }
+ nonNilNodes = append(nonNilNodes, t)
+ }
+ if len(nonNilNodes) <= 0 {
+ return nil
+ }
+ if len(nonNilNodes) == 1 {
+ return nonNilNodes[0]
+ }
+ alt := newAltNode(nonNilNodes[0], nonNilNodes[1])
+ for _, t := range nonNilNodes[2:] {
+ alt = newAltNode(alt, t)
+ }
+ return alt
+}
+
+//nolint:unused
+func printByteTree(w io.Writer, t byteTree, ruledLine string, childRuledLinePrefix string, withAttrs bool) {
+ if t == nil {
+ return
+ }
+ fmt.Fprintf(w, "%v%v", ruledLine, t)
+ if withAttrs {
+ fmt.Fprintf(w, ", nullable: %v, first: %v, last: %v", t.nullable(), t.first(), t.last())
+ }
+ fmt.Fprintf(w, "\n")
+ left, right := t.children()
+ children := []byteTree{}
+ if left != nil {
+ children = append(children, left)
+ }
+ if right != nil {
+ children = append(children, right)
+ }
+ num := len(children)
+ for i, child := range children {
+ line := "└─ "
+ if num > 1 {
+ if i == 0 {
+ line = "├─ "
+ } else if i < num-1 {
+ line = "│ "
+ }
+ }
+ prefix := "│ "
+ if i >= num-1 {
+ prefix = " "
+ }
+ printByteTree(w, child, childRuledLinePrefix+line, childRuledLinePrefix+prefix, withAttrs)
+ }
+}
+
+func ConvertCPTreeToByteTree(cpTrees map[spec.LexModeKindID]parser.CPTree) (byteTree, *symbolTable, error) {
+ var ids []spec.LexModeKindID
+ for id := range cpTrees {
+ ids = append(ids, id)
+ }
+ sort.Slice(ids, func(i, j int) bool {
+ return ids[i] < ids[j]
+ })
+
+ var bt byteTree
+ for _, id := range ids {
+ cpTree := cpTrees[id]
+ t, err := convCPTreeToByteTree(cpTree)
+ if err != nil {
+ return nil, nil, err
+ }
+ bt = oneOf(bt, concat(t, newEndMarkerNode(id)))
+ }
+ _, err := positionSymbols(bt, symbolPositionMin)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return bt, genSymbolTable(bt), nil
+}
+
+func convCPTreeToByteTree(cpTree parser.CPTree) (byteTree, error) {
+ if from, to, ok := cpTree.Range(); ok {
+ bs, err := utf8.GenCharBlocks(from, to)
+ if err != nil {
+ return nil, err
+ }
+ var a byteTree
+ for _, b := range bs {
+ var c byteTree
+ for i := 0; i < len(b.From); i++ {
+ c = concat(c, newRangeSymbolNode(b.From[i], b.To[i]))
+ }
+ a = oneOf(a, c)
+ }
+ return a, nil
+ }
+
+ if tree, ok := cpTree.Repeatable(); ok {
+ t, err := convCPTreeToByteTree(tree)
+ if err != nil {
+ return nil, err
+ }
+ return newRepeatNode(t), nil
+ }
+
+ if tree, ok := cpTree.Optional(); ok {
+ t, err := convCPTreeToByteTree(tree)
+ if err != nil {
+ return nil, err
+ }
+ return newOptionNode(t), nil
+ }
+
+ if left, right, ok := cpTree.Concatenation(); ok {
+ l, err := convCPTreeToByteTree(left)
+ if err != nil {
+ return nil, err
+ }
+ r, err := convCPTreeToByteTree(right)
+ if err != nil {
+ return nil, err
+ }
+ return newConcatNode(l, r), nil
+ }
+
+ if left, right, ok := cpTree.Alternatives(); ok {
+ l, err := convCPTreeToByteTree(left)
+ if err != nil {
+ return nil, err
+ }
+ r, err := convCPTreeToByteTree(right)
+ if err != nil {
+ return nil, err
+ }
+ return newAltNode(l, r), nil
+ }
+
+ return nil, fmt.Errorf("invalid tree type: %T", cpTree)
+}
diff --git a/src/urubu/grammar/lexical/entry.go b/src/urubu/grammar/lexical/entry.go
new file mode 100644
index 0000000..44af8ea
--- /dev/null
+++ b/src/urubu/grammar/lexical/entry.go
@@ -0,0 +1,171 @@
+package lexical
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ spec "urubu/spec/grammar"
+)
+
+type LexEntry struct {
+ Kind spec.LexKindName
+ Pattern string
+ Modes []spec.LexModeName
+ Push spec.LexModeName
+ Pop bool
+ Fragment bool
+}
+
+type LexSpec struct {
+ Entries []*LexEntry
+}
+
+func (s *LexSpec) Validate() error {
+ if len(s.Entries) <= 0 {
+ return fmt.Errorf("the lexical specification must have at least one entry")
+ }
+ {
+ ks := map[string]struct{}{}
+ fks := map[string]struct{}{}
+ for _, e := range s.Entries {
+ // Allow duplicate names between fragments and non-fragments.
+ if e.Fragment {
+ if _, exist := fks[e.Kind.String()]; exist {
+ return fmt.Errorf("kinds `%v` are duplicates", e.Kind)
+ }
+ fks[e.Kind.String()] = struct{}{}
+ } else {
+ if _, exist := ks[e.Kind.String()]; exist {
+ return fmt.Errorf("kinds `%v` are duplicates", e.Kind)
+ }
+ ks[e.Kind.String()] = struct{}{}
+ }
+ }
+ }
+ {
+ kinds := []string{}
+ modes := []string{
+ spec.LexModeNameDefault.String(), // This is a predefined mode.
+ }
+ for _, e := range s.Entries {
+ if e.Fragment {
+ continue
+ }
+
+ kinds = append(kinds, e.Kind.String())
+
+ for _, m := range e.Modes {
+ modes = append(modes, m.String())
+ }
+ }
+
+ kindErrs := findSpellingInconsistenciesErrors(kinds, nil)
+ modeErrs := findSpellingInconsistenciesErrors(modes, func(ids []string) error {
+ if SnakeCaseToUpperCamelCase(ids[0]) == SnakeCaseToUpperCamelCase(spec.LexModeNameDefault.String()) {
+ var b strings.Builder
+ fmt.Fprintf(&b, "%+v", ids[0])
+ for _, id := range ids[1:] {
+ fmt.Fprintf(&b, ", %+v", id)
+ }
+ return fmt.Errorf("these identifiers are treated as the same. please use the same spelling as predefined '%v': %v", spec.LexModeNameDefault, b.String())
+ }
+ return nil
+ })
+ errs := append(kindErrs, modeErrs...)
+ if len(errs) > 0 {
+ var b strings.Builder
+ fmt.Fprintf(&b, "%v", errs[0])
+ for _, err := range errs[1:] {
+ fmt.Fprintf(&b, "\n%v", err)
+ }
+ return fmt.Errorf(b.String())
+ }
+ }
+
+ return nil
+}
+
+func findSpellingInconsistenciesErrors(ids []string, hook func(ids []string) error) []error {
+ duplicated := FindSpellingInconsistencies(ids)
+ if len(duplicated) == 0 {
+ return nil
+ }
+
+ var errs []error
+ for _, dup := range duplicated {
+ if hook != nil {
+ err := hook(dup)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ }
+
+ var b strings.Builder
+ fmt.Fprintf(&b, "%+v", dup[0])
+ for _, id := range dup[1:] {
+ fmt.Fprintf(&b, ", %+v", id)
+ }
+ err := fmt.Errorf("these identifiers are treated as the same. please use the same spelling: %v", b.String())
+ errs = append(errs, err)
+ }
+
+ return errs
+}
+
+// FindSpellingInconsistencies finds spelling inconsistencies in identifiers. The identifiers are considered to be the same
+// if they are spelled the same when expressed in UpperCamelCase. For example, `left_paren` and `LeftParen` are spelled the same
+// in UpperCamelCase. Thus they are considere to be spelling inconsistency.
+func FindSpellingInconsistencies(ids []string) [][]string {
+ m := map[string][]string{}
+ for _, id := range removeDuplicates(ids) {
+ c := SnakeCaseToUpperCamelCase(id)
+ m[c] = append(m[c], id)
+ }
+
+ var duplicated [][]string
+ for _, camels := range m {
+ if len(camels) == 1 {
+ continue
+ }
+ duplicated = append(duplicated, camels)
+ }
+
+ for _, dup := range duplicated {
+ sort.Slice(dup, func(i, j int) bool {
+ return dup[i] < dup[j]
+ })
+ }
+ sort.Slice(duplicated, func(i, j int) bool {
+ return duplicated[i][0] < duplicated[j][0]
+ })
+
+ return duplicated
+}
+
+func removeDuplicates(s []string) []string {
+ m := map[string]struct{}{}
+ for _, v := range s {
+ m[v] = struct{}{}
+ }
+
+ var unique []string
+ for v := range m {
+ unique = append(unique, v)
+ }
+
+ return unique
+}
+
+func SnakeCaseToUpperCamelCase(snake string) string {
+ elems := strings.Split(snake, "_")
+ for i, e := range elems {
+ if len(e) == 0 {
+ continue
+ }
+ elems[i] = strings.ToUpper(string(e[0])) + e[1:]
+ }
+
+ return strings.Join(elems, "")
+}
diff --git a/src/urubu/grammar/lexical/parser/error.go b/src/urubu/grammar/lexical/parser/error.go
new file mode 100644
index 0000000..be81da4
--- /dev/null
+++ b/src/urubu/grammar/lexical/parser/error.go
@@ -0,0 +1,36 @@
+package parser
+
+import "fmt"
+
+var (
+ ParseErr = fmt.Errorf("parse error")
+
+ // lexical errors
+ synErrIncompletedEscSeq = fmt.Errorf("incompleted escape sequence; unexpected EOF following \\")
+ synErrInvalidEscSeq = fmt.Errorf("invalid escape sequence")
+ synErrInvalidCodePoint = fmt.Errorf("code points must consist of just 4 or 6 hex digits")
+ synErrCharPropInvalidSymbol = fmt.Errorf("invalid character property symbol")
+ SynErrFragmentInvalidSymbol = fmt.Errorf("invalid fragment symbol")
+
+ // syntax errors
+ synErrUnexpectedToken = fmt.Errorf("unexpected token")
+ synErrNullPattern = fmt.Errorf("a pattern must be a non-empty byte sequence")
+ synErrUnmatchablePattern = fmt.Errorf("a pattern cannot match any characters")
+ synErrAltLackOfOperand = fmt.Errorf("an alternation expression must have operands")
+ synErrRepNoTarget = fmt.Errorf("a repeat expression must have an operand")
+ synErrGroupNoElem = fmt.Errorf("a grouping expression must include at least one character")
+ synErrGroupUnclosed = fmt.Errorf("unclosed grouping expression")
+ synErrGroupNoInitiator = fmt.Errorf(") needs preceding (")
+ synErrGroupInvalidForm = fmt.Errorf("invalid grouping expression")
+ synErrBExpNoElem = fmt.Errorf("a bracket expression must include at least one character")
+ synErrBExpUnclosed = fmt.Errorf("unclosed bracket expression")
+ synErrBExpInvalidForm = fmt.Errorf("invalid bracket expression")
+ synErrRangeInvalidOrder = fmt.Errorf("a range expression with invalid order")
+ synErrRangePropIsUnavailable = fmt.Errorf("a property expression is unavailable in a range expression")
+ synErrRangeInvalidForm = fmt.Errorf("invalid range expression")
+ synErrCPExpInvalidForm = fmt.Errorf("invalid code point expression")
+ synErrCPExpOutOfRange = fmt.Errorf("a code point must be between U+0000 to U+10FFFF")
+ synErrCharPropExpInvalidForm = fmt.Errorf("invalid character property expression")
+ synErrCharPropUnsupported = fmt.Errorf("unsupported character property")
+ synErrFragmentExpInvalidForm = fmt.Errorf("invalid fragment expression")
+)
diff --git a/src/urubu/grammar/lexical/parser/fragment.go b/src/urubu/grammar/lexical/parser/fragment.go
new file mode 100644
index 0000000..196c00b
--- /dev/null
+++ b/src/urubu/grammar/lexical/parser/fragment.go
@@ -0,0 +1,72 @@
+package parser
+
+import (
+ "fmt"
+
+ spec "urubu/spec/grammar"
+)
+
+type incompleteFragment struct {
+ kind spec.LexKindName
+ root *rootNode
+}
+
+func CompleteFragments(fragments map[spec.LexKindName]CPTree) error {
+ if len(fragments) == 0 {
+ return nil
+ }
+
+ completeFragments := map[spec.LexKindName]CPTree{}
+ incompleteFragments := []*incompleteFragment{}
+ for kind, tree := range fragments {
+ root, ok := tree.(*rootNode)
+ if !ok {
+ return fmt.Errorf("CompleteFragments can take only *rootNode: %T", tree)
+ }
+ if root.incomplete() {
+ incompleteFragments = append(incompleteFragments, &incompleteFragment{
+ kind: kind,
+ root: root,
+ })
+ } else {
+ completeFragments[kind] = root
+ }
+ }
+ for len(incompleteFragments) > 0 {
+ lastIncompCount := len(incompleteFragments)
+ remainingFragments := []*incompleteFragment{}
+ for _, e := range incompleteFragments {
+ complete, err := ApplyFragments(e.root, completeFragments)
+ if err != nil {
+ return err
+ }
+ if !complete {
+ remainingFragments = append(remainingFragments, e)
+ } else {
+ completeFragments[e.kind] = e.root
+ }
+ }
+ incompleteFragments = remainingFragments
+ if len(incompleteFragments) == lastIncompCount {
+ return ParseErr
+ }
+ }
+
+ return nil
+}
+
+func ApplyFragments(t CPTree, fragments map[spec.LexKindName]CPTree) (bool, error) {
+ root, ok := t.(*rootNode)
+ if !ok {
+ return false, fmt.Errorf("ApplyFragments can take only *rootNode type: %T", t)
+ }
+
+ for name, frag := range fragments {
+ err := root.applyFragment(name, frag)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ return !root.incomplete(), nil
+}
diff --git a/src/urubu/grammar/lexical/parser/lexer.go b/src/urubu/grammar/lexical/parser/lexer.go
new file mode 100644
index 0000000..3861825
--- /dev/null
+++ b/src/urubu/grammar/lexical/parser/lexer.go
@@ -0,0 +1,594 @@
+package parser
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "strings"
+)
+
+type tokenKind string
+
+const (
+ tokenKindChar tokenKind = "char"
+ tokenKindAnyChar tokenKind = "."
+ tokenKindRepeat tokenKind = "*"
+ tokenKindRepeatOneOrMore tokenKind = "+"
+ tokenKindOption tokenKind = "?"
+ tokenKindAlt tokenKind = "|"
+ tokenKindGroupOpen tokenKind = "("
+ tokenKindGroupClose tokenKind = ")"
+ tokenKindBExpOpen tokenKind = "["
+ tokenKindInverseBExpOpen tokenKind = "[^"
+ tokenKindBExpClose tokenKind = "]"
+ tokenKindCharRange tokenKind = "-"
+ tokenKindCodePointLeader tokenKind = "\\u"
+ tokenKindCharPropLeader tokenKind = "\\p"
+ tokenKindFragmentLeader tokenKind = "\\f"
+ tokenKindLBrace tokenKind = "{"
+ tokenKindRBrace tokenKind = "}"
+ tokenKindEqual tokenKind = "="
+ tokenKindCodePoint tokenKind = "code point"
+ tokenKindCharPropSymbol tokenKind = "character property symbol"
+ tokenKindFragmentSymbol tokenKind = "fragment symbol"
+ tokenKindEOF tokenKind = "eof"
+)
+
+type token struct {
+ kind tokenKind
+ char rune
+ propSymbol string
+ codePoint string
+ fragmentSymbol string
+}
+
+const nullChar = '\u0000'
+
+func newToken(kind tokenKind, char rune) *token {
+ return &token{
+ kind: kind,
+ char: char,
+ }
+}
+
+func newCodePointToken(codePoint string) *token {
+ return &token{
+ kind: tokenKindCodePoint,
+ codePoint: codePoint,
+ }
+}
+
+func newCharPropSymbolToken(propSymbol string) *token {
+ return &token{
+ kind: tokenKindCharPropSymbol,
+ propSymbol: propSymbol,
+ }
+}
+
+func newFragmentSymbolToken(fragmentSymbol string) *token {
+ return &token{
+ kind: tokenKindFragmentSymbol,
+ fragmentSymbol: fragmentSymbol,
+ }
+}
+
+type lexerMode string
+
+const (
+ lexerModeDefault lexerMode = "default"
+ lexerModeBExp lexerMode = "bracket expression"
+ lexerModeCPExp lexerMode = "code point expression"
+ lexerModeCharPropExp lexerMode = "character property expression"
+ lexerModeFragmentExp lexerMode = "fragment expression"
+)
+
+type lexerModeStack struct {
+ stack []lexerMode
+}
+
+func newLexerModeStack() *lexerModeStack {
+ return &lexerModeStack{
+ stack: []lexerMode{
+ lexerModeDefault,
+ },
+ }
+}
+
+func (s *lexerModeStack) top() lexerMode {
+ return s.stack[len(s.stack)-1]
+}
+
+func (s *lexerModeStack) push(m lexerMode) {
+ s.stack = append(s.stack, m)
+}
+
+func (s *lexerModeStack) pop() {
+ s.stack = s.stack[:len(s.stack)-1]
+}
+
+type rangeState string
+
+// [a-z]
+// ^^^^
+// |||`-- ready
+// ||`-- expect range terminator
+// |`-- read range initiator
+// `-- ready
+const (
+ rangeStateReady rangeState = "ready"
+ rangeStateReadRangeInitiator rangeState = "read range initiator"
+ rangeStateExpectRangeTerminator rangeState = "expect range terminator"
+)
+
+type lexer struct {
+ src *bufio.Reader
+ peekChar2 rune
+ peekEOF2 bool
+ peekChar1 rune
+ peekEOF1 bool
+ lastChar rune
+ reachedEOF bool
+ prevChar1 rune
+ prevEOF1 bool
+ prevChar2 rune
+ pervEOF2 bool
+ modeStack *lexerModeStack
+ rangeState rangeState
+
+ errCause error
+ errDetail string
+}
+
+func newLexer(src io.Reader) *lexer {
+ return &lexer{
+ src: bufio.NewReader(src),
+ peekChar2: nullChar,
+ peekEOF2: false,
+ peekChar1: nullChar,
+ peekEOF1: false,
+ lastChar: nullChar,
+ reachedEOF: false,
+ prevChar1: nullChar,
+ prevEOF1: false,
+ prevChar2: nullChar,
+ pervEOF2: false,
+ modeStack: newLexerModeStack(),
+ rangeState: rangeStateReady,
+ }
+}
+
+func (l *lexer) error() (string, error) {
+ return l.errDetail, l.errCause
+}
+
+func (l *lexer) next() (*token, error) {
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ return newToken(tokenKindEOF, nullChar), nil
+ }
+
+ switch l.modeStack.top() {
+ case lexerModeBExp:
+ tok, err := l.nextInBExp(c)
+ if err != nil {
+ return nil, err
+ }
+ if tok.kind == tokenKindChar || tok.kind == tokenKindCodePointLeader || tok.kind == tokenKindCharPropLeader {
+ switch l.rangeState {
+ case rangeStateReady:
+ l.rangeState = rangeStateReadRangeInitiator
+ case rangeStateExpectRangeTerminator:
+ l.rangeState = rangeStateReady
+ }
+ }
+ switch tok.kind {
+ case tokenKindBExpClose:
+ l.modeStack.pop()
+ case tokenKindCharRange:
+ l.rangeState = rangeStateExpectRangeTerminator
+ case tokenKindCodePointLeader:
+ l.modeStack.push(lexerModeCPExp)
+ case tokenKindCharPropLeader:
+ l.modeStack.push(lexerModeCharPropExp)
+ }
+ return tok, nil
+ case lexerModeCPExp:
+ tok, err := l.nextInCodePoint(c)
+ if err != nil {
+ return nil, err
+ }
+ switch tok.kind {
+ case tokenKindRBrace:
+ l.modeStack.pop()
+ }
+ return tok, nil
+ case lexerModeCharPropExp:
+ tok, err := l.nextInCharProp(c)
+ if err != nil {
+ return nil, err
+ }
+ switch tok.kind {
+ case tokenKindRBrace:
+ l.modeStack.pop()
+ }
+ return tok, nil
+ case lexerModeFragmentExp:
+ tok, err := l.nextInFragment(c)
+ if err != nil {
+ return nil, err
+ }
+ switch tok.kind {
+ case tokenKindRBrace:
+ l.modeStack.pop()
+ }
+ return tok, nil
+ default:
+ tok, err := l.nextInDefault(c)
+ if err != nil {
+ return nil, err
+ }
+ switch tok.kind {
+ case tokenKindBExpOpen:
+ l.modeStack.push(lexerModeBExp)
+ l.rangeState = rangeStateReady
+ case tokenKindInverseBExpOpen:
+ l.modeStack.push(lexerModeBExp)
+ l.rangeState = rangeStateReady
+ case tokenKindCodePointLeader:
+ l.modeStack.push(lexerModeCPExp)
+ case tokenKindCharPropLeader:
+ l.modeStack.push(lexerModeCharPropExp)
+ case tokenKindFragmentLeader:
+ l.modeStack.push(lexerModeFragmentExp)
+ }
+ return tok, nil
+ }
+}
+
+func (l *lexer) nextInDefault(c rune) (*token, error) {
+ switch c {
+ case '*':
+ return newToken(tokenKindRepeat, nullChar), nil
+ case '+':
+ return newToken(tokenKindRepeatOneOrMore, nullChar), nil
+ case '?':
+ return newToken(tokenKindOption, nullChar), nil
+ case '.':
+ return newToken(tokenKindAnyChar, nullChar), nil
+ case '|':
+ return newToken(tokenKindAlt, nullChar), nil
+ case '(':
+ return newToken(tokenKindGroupOpen, nullChar), nil
+ case ')':
+ return newToken(tokenKindGroupClose, nullChar), nil
+ case '[':
+ c1, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindBExpOpen, nullChar), nil
+ }
+ if c1 != '^' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindBExpOpen, nullChar), nil
+ }
+ c2, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindInverseBExpOpen, nullChar), nil
+ }
+ if c2 != ']' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindInverseBExpOpen, nullChar), nil
+ }
+ err = l.restore()
+ if err != nil {
+ return nil, err
+ }
+ err = l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindBExpOpen, nullChar), nil
+ case '\\':
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ l.errCause = synErrIncompletedEscSeq
+ return nil, ParseErr
+ }
+ if c == 'u' {
+ return newToken(tokenKindCodePointLeader, nullChar), nil
+ }
+ if c == 'p' {
+ return newToken(tokenKindCharPropLeader, nullChar), nil
+ }
+ if c == 'f' {
+ return newToken(tokenKindFragmentLeader, nullChar), nil
+ }
+ if c == '\\' || c == '.' || c == '*' || c == '+' || c == '?' || c == '|' || c == '(' || c == ')' || c == '[' || c == ']' {
+ return newToken(tokenKindChar, c), nil
+ }
+ l.errCause = synErrInvalidEscSeq
+ l.errDetail = fmt.Sprintf("\\%v is not supported", string(c))
+ return nil, ParseErr
+ default:
+ return newToken(tokenKindChar, c), nil
+ }
+}
+
+func (l *lexer) nextInBExp(c rune) (*token, error) {
+ switch c {
+ case '-':
+ if l.rangeState != rangeStateReadRangeInitiator {
+ return newToken(tokenKindChar, c), nil
+ }
+ c1, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindChar, c), nil
+ }
+ if c1 != ']' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindCharRange, nullChar), nil
+ }
+ err = l.restore()
+ if err != nil {
+ return nil, err
+ }
+ return newToken(tokenKindChar, c), nil
+ case ']':
+ return newToken(tokenKindBExpClose, nullChar), nil
+ case '\\':
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ l.errCause = synErrIncompletedEscSeq
+ return nil, ParseErr
+ }
+ if c == 'u' {
+ return newToken(tokenKindCodePointLeader, nullChar), nil
+ }
+ if c == 'p' {
+ return newToken(tokenKindCharPropLeader, nullChar), nil
+ }
+ if c == '\\' || c == '^' || c == '-' || c == ']' {
+ return newToken(tokenKindChar, c), nil
+ }
+ l.errCause = synErrInvalidEscSeq
+ l.errDetail = fmt.Sprintf("\\%v is not supported in a bracket expression", string(c))
+ return nil, ParseErr
+ default:
+ return newToken(tokenKindChar, c), nil
+ }
+}
+
+func (l *lexer) nextInCodePoint(c rune) (*token, error) {
+ switch c {
+ case '{':
+ return newToken(tokenKindLBrace, nullChar), nil
+ case '}':
+ return newToken(tokenKindRBrace, nullChar), nil
+ default:
+ if !isHexDigit(c) {
+ l.errCause = synErrInvalidCodePoint
+ return nil, ParseErr
+ }
+ var b strings.Builder
+ fmt.Fprint(&b, string(c))
+ n := 1
+ for {
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ if c == '}' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ if !isHexDigit(c) || n >= 6 {
+ l.errCause = synErrInvalidCodePoint
+ return nil, ParseErr
+ }
+ fmt.Fprint(&b, string(c))
+ n++
+ }
+ cp := b.String()
+ cpLen := len(cp)
+ if !(cpLen == 4 || cpLen == 6) {
+ l.errCause = synErrInvalidCodePoint
+ return nil, ParseErr
+ }
+ return newCodePointToken(b.String()), nil
+ }
+}
+
+func isHexDigit(c rune) bool {
+ if c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' {
+ return true
+ }
+ return false
+}
+
+func (l *lexer) nextInCharProp(c rune) (*token, error) {
+ switch c {
+ case '{':
+ return newToken(tokenKindLBrace, nullChar), nil
+ case '}':
+ return newToken(tokenKindRBrace, nullChar), nil
+ case '=':
+ return newToken(tokenKindEqual, nullChar), nil
+ default:
+ var b strings.Builder
+ fmt.Fprint(&b, string(c))
+ n := 1
+ for {
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ if c == '}' || c == '=' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ fmt.Fprint(&b, string(c))
+ n++
+ }
+ sym := strings.TrimSpace(b.String())
+ if len(sym) == 0 {
+ l.errCause = synErrCharPropInvalidSymbol
+ return nil, ParseErr
+ }
+ return newCharPropSymbolToken(sym), nil
+ }
+}
+
+func (l *lexer) nextInFragment(c rune) (*token, error) {
+ switch c {
+ case '{':
+ return newToken(tokenKindLBrace, nullChar), nil
+ case '}':
+ return newToken(tokenKindRBrace, nullChar), nil
+ default:
+ var b strings.Builder
+ fmt.Fprint(&b, string(c))
+ n := 1
+ for {
+ c, eof, err := l.read()
+ if err != nil {
+ return nil, err
+ }
+ if eof {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ if c == '}' {
+ err := l.restore()
+ if err != nil {
+ return nil, err
+ }
+ break
+ }
+ fmt.Fprint(&b, string(c))
+ n++
+ }
+ sym := strings.TrimSpace(b.String())
+ if len(sym) == 0 {
+ l.errCause = SynErrFragmentInvalidSymbol
+ return nil, ParseErr
+ }
+ return newFragmentSymbolToken(sym), nil
+ }
+}
+
+func (l *lexer) read() (rune, bool, error) {
+ if l.reachedEOF {
+ return l.lastChar, l.reachedEOF, nil
+ }
+ if l.peekChar1 != nullChar || l.peekEOF1 {
+ l.prevChar2 = l.prevChar1
+ l.pervEOF2 = l.prevEOF1
+ l.prevChar1 = l.lastChar
+ l.prevEOF1 = l.reachedEOF
+ l.lastChar = l.peekChar1
+ l.reachedEOF = l.peekEOF1
+ l.peekChar1 = l.peekChar2
+ l.peekEOF1 = l.peekEOF2
+ l.peekChar2 = nullChar
+ l.peekEOF2 = false
+ return l.lastChar, l.reachedEOF, nil
+ }
+ c, _, err := l.src.ReadRune()
+ if err != nil {
+ if err == io.EOF {
+ l.prevChar2 = l.prevChar1
+ l.pervEOF2 = l.prevEOF1
+ l.prevChar1 = l.lastChar
+ l.prevEOF1 = l.reachedEOF
+ l.lastChar = nullChar
+ l.reachedEOF = true
+ return l.lastChar, l.reachedEOF, nil
+ }
+ return nullChar, false, err
+ }
+ l.prevChar2 = l.prevChar1
+ l.pervEOF2 = l.prevEOF1
+ l.prevChar1 = l.lastChar
+ l.prevEOF1 = l.reachedEOF
+ l.lastChar = c
+ l.reachedEOF = false
+ return l.lastChar, l.reachedEOF, nil
+}
+
+func (l *lexer) restore() error {
+ if l.lastChar == nullChar && !l.reachedEOF {
+ return fmt.Errorf("failed to call restore() because the last character is null")
+ }
+ l.peekChar2 = l.peekChar1
+ l.peekEOF2 = l.peekEOF1
+ l.peekChar1 = l.lastChar
+ l.peekEOF1 = l.reachedEOF
+ l.lastChar = l.prevChar1
+ l.reachedEOF = l.prevEOF1
+ l.prevChar1 = l.prevChar2
+ l.prevEOF1 = l.pervEOF2
+ l.prevChar2 = nullChar
+ l.pervEOF2 = false
+ return nil
+}
diff --git a/src/urubu/grammar/lexical/parser/parser.go b/src/urubu/grammar/lexical/parser/parser.go
new file mode 100644
index 0000000..425b553
--- /dev/null
+++ b/src/urubu/grammar/lexical/parser/parser.go
@@ -0,0 +1,531 @@
+package parser
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+
+ spec "urubu/spec/grammar"
+ "urubu/ucd"
+)
+
+type PatternEntry struct {
+ ID spec.LexModeKindID
+ Pattern []byte
+}
+
+type parser struct {
+ kind spec.LexKindName
+ lex *lexer
+ peekedTok *token
+ lastTok *token
+
+ // If and only if isContributoryPropertyExposed is true, the parser interprets contributory properties that
+ // appear in property expressions.
+ //
+ // The contributory properties are not exposed, and users cannot use those properties because the parser
+ // follows [UAX #44 5.13 Property APIs]. For instance, \p{Other_Alphabetic} is invalid.
+ //
+ // isContributoryPropertyExposed is set to true when the parser is generated recursively. The parser needs to
+ // interpret derived properties internally because the derived properties consist of other properties that
+ // may contain the contributory properties.
+ //
+ // [UAX #44 5.13 Property APIs] says:
+ // > The following subtypes of Unicode character properties should generally not be exposed in APIs,
+ // > except in limited circumstances. They may not be useful, particularly in public API collections,
+ // > and may instead prove misleading to the users of such API collections.
+ // > * Contributory properties are not recommended for public APIs.
+ // > ...
+ // https://unicode.org/reports/tr44/#Property_APIs
+ isContributoryPropertyExposed bool
+
+ errCause error
+ errDetail string
+}
+
+func NewParser(kind spec.LexKindName, src io.Reader) *parser {
+ return &parser{
+ kind: kind,
+ lex: newLexer(src),
+ isContributoryPropertyExposed: false,
+ }
+}
+
+func (p *parser) exposeContributoryProperty() {
+ p.isContributoryPropertyExposed = true
+}
+
+func (p *parser) Error() (string, error) {
+ return p.errDetail, p.errCause
+}
+
+func (p *parser) Parse() (root CPTree, retErr error) {
+ defer func() {
+ err := recover()
+ if err != nil {
+ var ok bool
+ retErr, ok = err.(error)
+ if !ok {
+ panic(err)
+ }
+ return
+ }
+ }()
+
+ return newRootNode(p.kind, p.parseRegexp()), nil
+}
+
+func (p *parser) parseRegexp() CPTree {
+ alt := p.parseAlt()
+ if alt == nil {
+ if p.consume(tokenKindGroupClose) {
+ p.raiseParseError(synErrGroupNoInitiator, "")
+ }
+ p.raiseParseError(synErrNullPattern, "")
+ }
+ if p.consume(tokenKindGroupClose) {
+ p.raiseParseError(synErrGroupNoInitiator, "")
+ }
+ p.expect(tokenKindEOF)
+ return alt
+}
+
+func (p *parser) parseAlt() CPTree {
+ left := p.parseConcat()
+ if left == nil {
+ if p.consume(tokenKindAlt) {
+ p.raiseParseError(synErrAltLackOfOperand, "")
+ }
+ return nil
+ }
+ for {
+ if !p.consume(tokenKindAlt) {
+ break
+ }
+ right := p.parseConcat()
+ if right == nil {
+ p.raiseParseError(synErrAltLackOfOperand, "")
+ }
+ left = newAltNode(left, right)
+ }
+ return left
+}
+
+func (p *parser) parseConcat() CPTree {
+ left := p.parseRepeat()
+ for {
+ right := p.parseRepeat()
+ if right == nil {
+ break
+ }
+ left = newConcatNode(left, right)
+ }
+ return left
+}
+
+func (p *parser) parseRepeat() CPTree {
+ group := p.parseGroup()
+ if group == nil {
+ if p.consume(tokenKindRepeat) {
+ p.raiseParseError(synErrRepNoTarget, "* needs an operand")
+ }
+ if p.consume(tokenKindRepeatOneOrMore) {
+ p.raiseParseError(synErrRepNoTarget, "+ needs an operand")
+ }
+ if p.consume(tokenKindOption) {
+ p.raiseParseError(synErrRepNoTarget, "? needs an operand")
+ }
+ return nil
+ }
+ if p.consume(tokenKindRepeat) {
+ return newRepeatNode(group)
+ }
+ if p.consume(tokenKindRepeatOneOrMore) {
+ return newRepeatOneOrMoreNode(group)
+ }
+ if p.consume(tokenKindOption) {
+ return newOptionNode(group)
+ }
+ return group
+}
+
+func (p *parser) parseGroup() CPTree {
+ if p.consume(tokenKindGroupOpen) {
+ alt := p.parseAlt()
+ if alt == nil {
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrGroupUnclosed, "")
+ }
+ p.raiseParseError(synErrGroupNoElem, "")
+ }
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrGroupUnclosed, "")
+ }
+ if !p.consume(tokenKindGroupClose) {
+ p.raiseParseError(synErrGroupInvalidForm, "")
+ }
+ return alt
+ }
+ return p.parseSingleChar()
+}
+
+func (p *parser) parseSingleChar() CPTree {
+ if p.consume(tokenKindAnyChar) {
+ return genAnyCharAST()
+ }
+ if p.consume(tokenKindBExpOpen) {
+ left := p.parseBExpElem()
+ if left == nil {
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrBExpUnclosed, "")
+ }
+ p.raiseParseError(synErrBExpNoElem, "")
+ }
+ for {
+ right := p.parseBExpElem()
+ if right == nil {
+ break
+ }
+ left = newAltNode(left, right)
+ }
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrBExpUnclosed, "")
+ }
+ p.expect(tokenKindBExpClose)
+ return left
+ }
+ if p.consume(tokenKindInverseBExpOpen) {
+ elem := p.parseBExpElem()
+ if elem == nil {
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrBExpUnclosed, "")
+ }
+ p.raiseParseError(synErrBExpNoElem, "")
+ }
+ inverse := exclude(elem, genAnyCharAST())
+ if inverse == nil {
+ p.raiseParseError(synErrUnmatchablePattern, "")
+ }
+ for {
+ elem := p.parseBExpElem()
+ if elem == nil {
+ break
+ }
+ inverse = exclude(elem, inverse)
+ if inverse == nil {
+ p.raiseParseError(synErrUnmatchablePattern, "")
+ }
+ }
+ if p.consume(tokenKindEOF) {
+ p.raiseParseError(synErrBExpUnclosed, "")
+ }
+ p.expect(tokenKindBExpClose)
+ return inverse
+ }
+ if p.consume(tokenKindCodePointLeader) {
+ return p.parseCodePoint()
+ }
+ if p.consume(tokenKindCharPropLeader) {
+ return p.parseCharProp()
+ }
+ if p.consume(tokenKindFragmentLeader) {
+ return p.parseFragment()
+ }
+ c := p.parseNormalChar()
+ if c == nil {
+ if p.consume(tokenKindBExpClose) {
+ p.raiseParseError(synErrBExpInvalidForm, "")
+ }
+ return nil
+ }
+ return c
+}
+
+func (p *parser) parseBExpElem() CPTree {
+ var left CPTree
+ switch {
+ case p.consume(tokenKindCodePointLeader):
+ left = p.parseCodePoint()
+ case p.consume(tokenKindCharPropLeader):
+ left = p.parseCharProp()
+ if p.consume(tokenKindCharRange) {
+ p.raiseParseError(synErrRangePropIsUnavailable, "")
+ }
+ default:
+ left = p.parseNormalChar()
+ }
+ if left == nil {
+ return nil
+ }
+ if !p.consume(tokenKindCharRange) {
+ return left
+ }
+ var right CPTree
+ switch {
+ case p.consume(tokenKindCodePointLeader):
+ right = p.parseCodePoint()
+ case p.consume(tokenKindCharPropLeader):
+ p.raiseParseError(synErrRangePropIsUnavailable, "")
+ default:
+ right = p.parseNormalChar()
+ }
+ if right == nil {
+ p.raiseParseError(synErrRangeInvalidForm, "")
+ }
+ from, _, _ := left.Range()
+ _, to, _ := right.Range()
+ if !isValidOrder(from, to) {
+ p.raiseParseError(synErrRangeInvalidOrder, fmt.Sprintf("%X..%X", from, to))
+ }
+ return newRangeSymbolNode(from, to)
+}
+
+func (p *parser) parseCodePoint() CPTree {
+ if !p.consume(tokenKindLBrace) {
+ p.raiseParseError(synErrCPExpInvalidForm, "")
+ }
+ if !p.consume(tokenKindCodePoint) {
+ p.raiseParseError(synErrCPExpInvalidForm, "")
+ }
+
+ n, err := strconv.ParseInt(p.lastTok.codePoint, 16, 64)
+ if err != nil {
+ panic(fmt.Errorf("failed to decode a code point (%v) into a int: %v", p.lastTok.codePoint, err))
+ }
+ if n < 0x0000 || n > 0x10FFFF {
+ p.raiseParseError(synErrCPExpOutOfRange, "")
+ }
+
+ sym := newSymbolNode(rune(n))
+
+ if !p.consume(tokenKindRBrace) {
+ p.raiseParseError(synErrCPExpInvalidForm, "")
+ }
+
+ return sym
+}
+
+func (p *parser) parseCharProp() CPTree {
+ if !p.consume(tokenKindLBrace) {
+ p.raiseParseError(synErrCharPropExpInvalidForm, "")
+ }
+ var sym1, sym2 string
+ if !p.consume(tokenKindCharPropSymbol) {
+ p.raiseParseError(synErrCharPropExpInvalidForm, "")
+ }
+ sym1 = p.lastTok.propSymbol
+ if p.consume(tokenKindEqual) {
+ if !p.consume(tokenKindCharPropSymbol) {
+ p.raiseParseError(synErrCharPropExpInvalidForm, "")
+ }
+ sym2 = p.lastTok.propSymbol
+ }
+
+ var alt CPTree
+ var propName, propVal string
+ if sym2 != "" {
+ propName = sym1
+ propVal = sym2
+ } else {
+ propName = ""
+ propVal = sym1
+ }
+ if !p.isContributoryPropertyExposed && ucd.IsContributoryProperty(propName) {
+ p.raiseParseError(synErrCharPropUnsupported, propName)
+ }
+ pat, err := ucd.NormalizeCharacterProperty(propName, propVal)
+ if err != nil {
+ p.raiseParseError(synErrCharPropUnsupported, err.Error())
+ }
+ if pat != "" {
+ p := NewParser(p.kind, bytes.NewReader([]byte(pat)))
+ p.exposeContributoryProperty()
+ ast, err := p.Parse()
+ if err != nil {
+ panic(err)
+ }
+ alt = ast
+ } else {
+ cpRanges, inverse, err := ucd.FindCodePointRanges(propName, propVal)
+ if err != nil {
+ p.raiseParseError(synErrCharPropUnsupported, err.Error())
+ }
+ if inverse {
+ r := cpRanges[0]
+ alt = exclude(newRangeSymbolNode(r.From, r.To), genAnyCharAST())
+ if alt == nil {
+ p.raiseParseError(synErrUnmatchablePattern, "")
+ }
+ for _, r := range cpRanges[1:] {
+ alt = exclude(newRangeSymbolNode(r.From, r.To), alt)
+ if alt == nil {
+ p.raiseParseError(synErrUnmatchablePattern, "")
+ }
+ }
+ } else {
+ for _, r := range cpRanges {
+ alt = genAltNode(
+ alt,
+ newRangeSymbolNode(r.From, r.To),
+ )
+ }
+ }
+ }
+
+ if !p.consume(tokenKindRBrace) {
+ p.raiseParseError(synErrCharPropExpInvalidForm, "")
+ }
+
+ return alt
+}
+
+func (p *parser) parseFragment() CPTree {
+ if !p.consume(tokenKindLBrace) {
+ p.raiseParseError(synErrFragmentExpInvalidForm, "")
+ }
+ if !p.consume(tokenKindFragmentSymbol) {
+ p.raiseParseError(synErrFragmentExpInvalidForm, "")
+ }
+ sym := p.lastTok.fragmentSymbol
+
+ if !p.consume(tokenKindRBrace) {
+ p.raiseParseError(synErrFragmentExpInvalidForm, "")
+ }
+
+ return newFragmentNode(spec.LexKindName(sym), nil)
+}
+
+func (p *parser) parseNormalChar() CPTree {
+ if !p.consume(tokenKindChar) {
+ return nil
+ }
+ return newSymbolNode(p.lastTok.char)
+}
+
+func exclude(symbol, base CPTree) CPTree {
+ if left, right, ok := symbol.Alternatives(); ok {
+ return exclude(right, exclude(left, base))
+ }
+
+ if left, right, ok := base.Alternatives(); ok {
+ return genAltNode(
+ exclude(symbol, left),
+ exclude(symbol, right),
+ )
+ }
+
+ if bFrom, bTo, ok := base.Range(); ok {
+ sFrom, sTo, ok := symbol.Range()
+ if !ok {
+ panic(fmt.Errorf("invalid symbol tree: %T", symbol))
+ }
+
+ switch {
+ case sFrom > bFrom && sTo < bTo:
+ return genAltNode(
+ newRangeSymbolNode(bFrom, sFrom-1),
+ newRangeSymbolNode(sTo+1, bTo),
+ )
+ case sFrom <= bFrom && sTo >= bFrom && sTo < bTo:
+ return newRangeSymbolNode(sTo+1, bTo)
+ case sFrom > bFrom && sFrom <= bTo && sTo >= bTo:
+ return newRangeSymbolNode(bFrom, sFrom-1)
+ case sFrom <= bFrom && sTo >= bTo:
+ return nil
+ default:
+ return base
+ }
+ }
+
+ panic(fmt.Errorf("invalid base tree: %T", base))
+}
+
+func genAnyCharAST() CPTree {
+ return newRangeSymbolNode(0x0, 0x10FFFF)
+}
+
+func isValidOrder(from, to rune) bool {
+ return from <= to
+}
+
+func genConcatNode(cs ...CPTree) CPTree {
+ nonNilNodes := []CPTree{}
+ for _, c := range cs {
+ if c == nil {
+ continue
+ }
+ nonNilNodes = append(nonNilNodes, c)
+ }
+ if len(nonNilNodes) <= 0 {
+ return nil
+ }
+ if len(nonNilNodes) == 1 {
+ return nonNilNodes[0]
+ }
+ concat := newConcatNode(nonNilNodes[0], nonNilNodes[1])
+ for _, c := range nonNilNodes[2:] {
+ concat = newConcatNode(concat, c)
+ }
+ return concat
+}
+
+func genAltNode(cs ...CPTree) CPTree {
+ nonNilNodes := []CPTree{}
+ for _, c := range cs {
+ if c == nil {
+ continue
+ }
+ nonNilNodes = append(nonNilNodes, c)
+ }
+ if len(nonNilNodes) <= 0 {
+ return nil
+ }
+ if len(nonNilNodes) == 1 {
+ return nonNilNodes[0]
+ }
+ alt := newAltNode(nonNilNodes[0], nonNilNodes[1])
+ for _, c := range nonNilNodes[2:] {
+ alt = newAltNode(alt, c)
+ }
+ return alt
+}
+
+func (p *parser) expect(expected tokenKind) {
+ if !p.consume(expected) {
+ tok := p.peekedTok
+ p.raiseParseError(synErrUnexpectedToken, fmt.Sprintf("expected: %v, actual: %v", expected, tok.kind))
+ }
+}
+
+func (p *parser) consume(expected tokenKind) bool {
+ var tok *token
+ var err error
+ if p.peekedTok != nil {
+ tok = p.peekedTok
+ p.peekedTok = nil
+ } else {
+ tok, err = p.lex.next()
+ if err != nil {
+ if err == ParseErr {
+ detail, cause := p.lex.error()
+ p.raiseParseError(cause, detail)
+ }
+ panic(err)
+ }
+ }
+ p.lastTok = tok
+ if tok.kind == expected {
+ return true
+ }
+ p.peekedTok = tok
+ p.lastTok = nil
+
+ return false
+}
+
+func (p *parser) raiseParseError(err error, detail string) {
+ p.errCause = err
+ p.errDetail = detail
+ panic(ParseErr)
+}
diff --git a/src/urubu/grammar/lexical/parser/tree.go b/src/urubu/grammar/lexical/parser/tree.go
new file mode 100644
index 0000000..df03d37
--- /dev/null
+++ b/src/urubu/grammar/lexical/parser/tree.go
@@ -0,0 +1,459 @@
+package parser
+
+import (
+ "fmt"
+ "io"
+ "sort"
+
+ spec "urubu/spec/grammar"
+)
+
+type CPRange struct {
+ From rune
+ To rune
+}
+
+type CPTree interface {
+ fmt.Stringer
+ Range() (rune, rune, bool)
+ Optional() (CPTree, bool)
+ Repeatable() (CPTree, bool)
+ Concatenation() (CPTree, CPTree, bool)
+ Alternatives() (CPTree, CPTree, bool)
+ Describe() (spec.LexKindName, []spec.LexKindName, error)
+
+ children() (CPTree, CPTree)
+ clone() CPTree
+}
+
+var (
+ _ CPTree = &rootNode{}
+ _ CPTree = &symbolNode{}
+ _ CPTree = &concatNode{}
+ _ CPTree = &altNode{}
+ _ CPTree = &quantifierNode{}
+ _ CPTree = &fragmentNode{}
+)
+
+type rootNode struct {
+ kind spec.LexKindName
+ tree CPTree
+ fragments map[spec.LexKindName][]*fragmentNode
+}
+
+func newRootNode(kind spec.LexKindName, t CPTree) *rootNode {
+ fragments := map[spec.LexKindName][]*fragmentNode{}
+ collectFragments(t, fragments)
+
+ return &rootNode{
+ kind: kind,
+ tree: t,
+ fragments: fragments,
+ }
+}
+
+func collectFragments(n CPTree, fragments map[spec.LexKindName][]*fragmentNode) {
+ if n == nil {
+ return
+ }
+
+ if f, ok := n.(*fragmentNode); ok {
+ fragments[f.kind] = append(fragments[f.kind], f)
+ return
+ }
+
+ l, r := n.children()
+ collectFragments(l, fragments)
+ collectFragments(r, fragments)
+}
+
+func (n *rootNode) String() string {
+ return fmt.Sprintf("root: %v: %v fragments", n.kind, len(n.fragments))
+}
+
+func (n *rootNode) Range() (rune, rune, bool) {
+ return n.tree.Range()
+}
+
+func (n *rootNode) Optional() (CPTree, bool) {
+ return n.tree.Optional()
+}
+
+func (n *rootNode) Repeatable() (CPTree, bool) {
+ return n.tree.Repeatable()
+}
+
+func (n *rootNode) Concatenation() (CPTree, CPTree, bool) {
+ return n.tree.Concatenation()
+}
+
+func (n *rootNode) Alternatives() (CPTree, CPTree, bool) {
+ return n.tree.Alternatives()
+}
+
+func (n *rootNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ var frags []spec.LexKindName
+ for f := range n.fragments {
+ frags = append(frags, spec.LexKindName(f))
+ }
+ sort.Slice(frags, func(i, j int) bool {
+ return frags[i] < frags[j]
+ })
+
+ return n.kind, frags, nil
+}
+
+func (n *rootNode) children() (CPTree, CPTree) {
+ return n.tree.children()
+}
+
+func (n *rootNode) clone() CPTree {
+ return n.tree.clone()
+}
+
+func (n *rootNode) incomplete() bool {
+ return len(n.fragments) > 0
+}
+
+func (n *rootNode) applyFragment(kind spec.LexKindName, fragment CPTree) error {
+ root, ok := fragment.(*rootNode)
+ if !ok {
+ return fmt.Errorf("applyFragment can take only *rootNode: %T", fragment)
+ }
+ if root.incomplete() {
+ return fmt.Errorf("fragment is incomplete")
+ }
+
+ fs, ok := n.fragments[kind]
+ if !ok {
+ return nil
+ }
+ for _, f := range fs {
+ f.tree = root.clone()
+ }
+ delete(n.fragments, kind)
+
+ return nil
+}
+
+type symbolNode struct {
+ CPRange
+}
+
+func newSymbolNode(cp rune) *symbolNode {
+ return &symbolNode{
+ CPRange: CPRange{
+ From: cp,
+ To: cp,
+ },
+ }
+}
+
+func newRangeSymbolNode(from, to rune) *symbolNode {
+ return &symbolNode{
+ CPRange: CPRange{
+ From: from,
+ To: to,
+ },
+ }
+}
+
+func (n *symbolNode) String() string {
+ return fmt.Sprintf("symbol: %X..%X", n.From, n.To)
+}
+
+func (n *symbolNode) Range() (rune, rune, bool) {
+ return n.From, n.To, true
+}
+
+func (n *symbolNode) Optional() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *symbolNode) Repeatable() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *symbolNode) Concatenation() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *symbolNode) Alternatives() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *symbolNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ return spec.LexKindNameNil, nil, fmt.Errorf("%T cannot describe", n)
+}
+
+func (n *symbolNode) children() (CPTree, CPTree) {
+ return nil, nil
+}
+
+func (n *symbolNode) clone() CPTree {
+ return newRangeSymbolNode(n.From, n.To)
+}
+
+type concatNode struct {
+ left CPTree
+ right CPTree
+}
+
+func newConcatNode(left, right CPTree) *concatNode {
+ return &concatNode{
+ left: left,
+ right: right,
+ }
+}
+
+func (n *concatNode) String() string {
+ return "concat"
+}
+
+func (n *concatNode) Range() (rune, rune, bool) {
+ return 0, 0, false
+}
+
+func (n *concatNode) Optional() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *concatNode) Repeatable() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *concatNode) Concatenation() (CPTree, CPTree, bool) {
+ return n.left, n.right, true
+}
+
+func (n *concatNode) Alternatives() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *concatNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ return spec.LexKindNameNil, nil, fmt.Errorf("%T cannot describe", n)
+}
+
+func (n *concatNode) children() (CPTree, CPTree) {
+ return n.left, n.right
+}
+
+func (n *concatNode) clone() CPTree {
+ if n == nil {
+ return nil
+ }
+ return newConcatNode(n.left.clone(), n.right.clone())
+}
+
+type altNode struct {
+ left CPTree
+ right CPTree
+}
+
+func newAltNode(left, right CPTree) *altNode {
+ return &altNode{
+ left: left,
+ right: right,
+ }
+}
+
+func (n *altNode) String() string {
+ return "alt"
+}
+
+func (n *altNode) Range() (rune, rune, bool) {
+ return 0, 0, false
+}
+
+func (n *altNode) Optional() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *altNode) Repeatable() (CPTree, bool) {
+ return nil, false
+}
+
+func (n *altNode) Concatenation() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *altNode) Alternatives() (CPTree, CPTree, bool) {
+ return n.left, n.right, true
+}
+
+func (n *altNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ return spec.LexKindNameNil, nil, fmt.Errorf("%T cannot describe", n)
+}
+
+func (n *altNode) children() (CPTree, CPTree) {
+ return n.left, n.right
+}
+
+func (n *altNode) clone() CPTree {
+ return newAltNode(n.left.clone(), n.right.clone())
+}
+
+type quantifierNode struct {
+ optional bool
+ repeatable bool
+ tree CPTree
+}
+
+func (n *quantifierNode) String() string {
+ switch {
+ case n.repeatable:
+ return "repeatable (>= 0 times)"
+ case n.optional:
+ return "optional (0 or 1 times)"
+ default:
+ return "invalid quantifier"
+ }
+}
+
+func newRepeatNode(t CPTree) *quantifierNode {
+ return &quantifierNode{
+ repeatable: true,
+ tree: t,
+ }
+}
+
+func newRepeatOneOrMoreNode(t CPTree) *concatNode {
+ return newConcatNode(
+ t,
+ &quantifierNode{
+ repeatable: true,
+ tree: t.clone(),
+ })
+}
+
+func newOptionNode(t CPTree) *quantifierNode {
+ return &quantifierNode{
+ optional: true,
+ tree: t,
+ }
+}
+
+func (n *quantifierNode) Range() (rune, rune, bool) {
+ return 0, 0, false
+}
+
+func (n *quantifierNode) Optional() (CPTree, bool) {
+ return n.tree, n.optional
+}
+
+func (n *quantifierNode) Repeatable() (CPTree, bool) {
+ return n.tree, n.repeatable
+}
+
+func (n *quantifierNode) Concatenation() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *quantifierNode) Alternatives() (CPTree, CPTree, bool) {
+ return nil, nil, false
+}
+
+func (n *quantifierNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ return spec.LexKindNameNil, nil, fmt.Errorf("%T cannot describe", n)
+}
+
+func (n *quantifierNode) children() (CPTree, CPTree) {
+ return n.tree, nil
+}
+
+func (n *quantifierNode) clone() CPTree {
+ if n.repeatable {
+ return newRepeatNode(n.tree.clone())
+ }
+ return newOptionNode(n.tree.clone())
+}
+
+type fragmentNode struct {
+ kind spec.LexKindName
+ tree CPTree
+}
+
+func newFragmentNode(kind spec.LexKindName, t CPTree) *fragmentNode {
+ return &fragmentNode{
+ kind: kind,
+ tree: t,
+ }
+}
+
+func (n *fragmentNode) String() string {
+ return fmt.Sprintf("fragment: %v", n.kind)
+}
+
+func (n *fragmentNode) Range() (rune, rune, bool) {
+ return n.tree.Range()
+}
+
+func (n *fragmentNode) Optional() (CPTree, bool) {
+ return n.tree.Optional()
+}
+
+func (n *fragmentNode) Repeatable() (CPTree, bool) {
+ return n.tree.Repeatable()
+}
+
+func (n *fragmentNode) Concatenation() (CPTree, CPTree, bool) {
+ return n.tree.Concatenation()
+}
+
+func (n *fragmentNode) Alternatives() (CPTree, CPTree, bool) {
+ return n.tree.Alternatives()
+}
+
+func (n *fragmentNode) Describe() (spec.LexKindName, []spec.LexKindName, error) {
+ return spec.LexKindNameNil, nil, fmt.Errorf("%T cannot describe", n)
+}
+
+func (n *fragmentNode) children() (CPTree, CPTree) {
+ return n.tree.children()
+}
+
+func (n *fragmentNode) clone() CPTree {
+ if n.tree == nil {
+ return newFragmentNode(n.kind, nil)
+ }
+ return newFragmentNode(n.kind, n.tree.clone())
+}
+
+//nolint:unused
+func printCPTree(w io.Writer, t CPTree, ruledLine string, childRuledLinePrefix string) {
+ if t == nil {
+ return
+ }
+ fmt.Fprintf(w, "%v%v\n", ruledLine, t)
+ children := []CPTree{}
+ switch n := t.(type) {
+ case *rootNode:
+ children = append(children, n.tree)
+ case *fragmentNode:
+ children = append(children, n.tree)
+ default:
+ left, right := t.children()
+ if left != nil {
+ children = append(children, left)
+ }
+ if right != nil {
+ children = append(children, right)
+ }
+ }
+ num := len(children)
+ for i, child := range children {
+ line := "└─ "
+ if num > 1 {
+ if i == 0 {
+ line = "├─ "
+ } else if i < num-1 {
+ line = "│ "
+ }
+ }
+ prefix := "│ "
+ if i >= num-1 {
+ prefix = " "
+ }
+ printCPTree(w, child, childRuledLinePrefix+line, childRuledLinePrefix+prefix)
+ }
+}
diff --git a/src/urubu/grammar/lr0.go b/src/urubu/grammar/lr0.go
new file mode 100644
index 0000000..92a2137
--- /dev/null
+++ b/src/urubu/grammar/lr0.go
@@ -0,0 +1,197 @@
+package grammar
+
+import (
+ "fmt"
+ "sort"
+
+ "urubu/grammar/symbol"
+)
+
+type lr0Automaton struct {
+ initialState kernelID
+ states map[kernelID]*lrState
+}
+
+func genLR0Automaton(prods *productionSet, startSym symbol.Symbol, errSym symbol.Symbol) (*lr0Automaton, error) {
+ if !startSym.IsStart() {
+ return nil, fmt.Errorf("passed symbold is not a start symbol")
+ }
+
+ automaton := &lr0Automaton{
+ states: map[kernelID]*lrState{},
+ }
+
+ currentState := stateNumInitial
+ knownKernels := map[kernelID]struct{}{}
+ uncheckedKernels := []*kernel{}
+
+ // Generate an initial kernel.
+ {
+ prods, _ := prods.findByLHS(startSym)
+ initialItem, err := newLR0Item(prods[0], 0)
+ if err != nil {
+ return nil, err
+ }
+
+ k, err := newKernel([]*lrItem{initialItem})
+ if err != nil {
+ return nil, err
+ }
+
+ automaton.initialState = k.id
+ knownKernels[k.id] = struct{}{}
+ uncheckedKernels = append(uncheckedKernels, k)
+ }
+
+ for len(uncheckedKernels) > 0 {
+ nextUncheckedKernels := []*kernel{}
+ for _, k := range uncheckedKernels {
+ state, neighbours, err := genStateAndNeighbourKernels(k, prods, errSym)
+ if err != nil {
+ return nil, err
+ }
+ state.num = currentState
+ currentState = currentState.next()
+
+ automaton.states[state.id] = state
+
+ for _, k := range neighbours {
+ if _, known := knownKernels[k.id]; known {
+ continue
+ }
+ knownKernels[k.id] = struct{}{}
+ nextUncheckedKernels = append(nextUncheckedKernels, k)
+ }
+ }
+ uncheckedKernels = nextUncheckedKernels
+ }
+
+ return automaton, nil
+}
+
+func genStateAndNeighbourKernels(k *kernel, prods *productionSet, errSym symbol.Symbol) (*lrState, []*kernel, error) {
+ items, err := genLR0Closure(k, prods)
+ if err != nil {
+ return nil, nil, err
+ }
+ neighbours, err := genNeighbourKernels(items, prods)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ next := map[symbol.Symbol]kernelID{}
+ kernels := []*kernel{}
+ for _, n := range neighbours {
+ next[n.symbol] = n.kernel.id
+ kernels = append(kernels, n.kernel)
+ }
+
+ reducible := map[productionID]struct{}{}
+ var emptyProdItems []*lrItem
+ isErrorTrapper := false
+ for _, item := range items {
+ if item.dottedSymbol == errSym {
+ isErrorTrapper = true
+ }
+
+ if item.reducible {
+ reducible[item.prod] = struct{}{}
+
+ prod, ok := prods.findByID(item.prod)
+ if !ok {
+ return nil, nil, fmt.Errorf("reducible production not found: %v", item.prod)
+ }
+ if prod.isEmpty() {
+ emptyProdItems = append(emptyProdItems, item)
+ }
+ }
+ }
+
+ return &lrState{
+ kernel: k,
+ next: next,
+ reducible: reducible,
+ emptyProdItems: emptyProdItems,
+ isErrorTrapper: isErrorTrapper,
+ }, kernels, nil
+}
+
+func genLR0Closure(k *kernel, prods *productionSet) ([]*lrItem, error) {
+ items := []*lrItem{}
+ knownItems := map[lrItemID]struct{}{}
+ uncheckedItems := []*lrItem{}
+ for _, item := range k.items {
+ items = append(items, item)
+ uncheckedItems = append(uncheckedItems, item)
+ }
+ for len(uncheckedItems) > 0 {
+ nextUncheckedItems := []*lrItem{}
+ for _, item := range uncheckedItems {
+ if item.dottedSymbol.IsTerminal() {
+ continue
+ }
+
+ ps, _ := prods.findByLHS(item.dottedSymbol)
+ for _, prod := range ps {
+ item, err := newLR0Item(prod, 0)
+ if err != nil {
+ return nil, err
+ }
+ if _, exist := knownItems[item.id]; exist {
+ continue
+ }
+ items = append(items, item)
+ knownItems[item.id] = struct{}{}
+ nextUncheckedItems = append(nextUncheckedItems, item)
+ }
+ }
+ uncheckedItems = nextUncheckedItems
+ }
+
+ return items, nil
+}
+
+type neighbourKernel struct {
+ symbol symbol.Symbol
+ kernel *kernel
+}
+
+func genNeighbourKernels(items []*lrItem, prods *productionSet) ([]*neighbourKernel, error) {
+ kItemMap := map[symbol.Symbol][]*lrItem{}
+ for _, item := range items {
+ if item.dottedSymbol.IsNil() {
+ continue
+ }
+ prod, ok := prods.findByID(item.prod)
+ if !ok {
+ return nil, fmt.Errorf("a production was not found: %v", item.prod)
+ }
+ kItem, err := newLR0Item(prod, item.dot+1)
+ if err != nil {
+ return nil, err
+ }
+ kItemMap[item.dottedSymbol] = append(kItemMap[item.dottedSymbol], kItem)
+ }
+
+ nextSyms := []symbol.Symbol{}
+ for sym := range kItemMap {
+ nextSyms = append(nextSyms, sym)
+ }
+ sort.Slice(nextSyms, func(i, j int) bool {
+ return nextSyms[i] < nextSyms[j]
+ })
+
+ kernels := []*neighbourKernel{}
+ for _, sym := range nextSyms {
+ k, err := newKernel(kItemMap[sym])
+ if err != nil {
+ return nil, err
+ }
+ kernels = append(kernels, &neighbourKernel{
+ symbol: sym,
+ kernel: k,
+ })
+ }
+
+ return kernels, nil
+}
diff --git a/src/urubu/grammar/parsing_table.go b/src/urubu/grammar/parsing_table.go
new file mode 100644
index 0000000..48ea9fe
--- /dev/null
+++ b/src/urubu/grammar/parsing_table.go
@@ -0,0 +1,553 @@
+package grammar
+
+import (
+ "fmt"
+ "sort"
+
+ "urubu/grammar/symbol"
+ spec "urubu/spec/grammar"
+)
+
+type ActionType string
+
+const (
+ ActionTypeShift = ActionType("shift")
+ ActionTypeReduce = ActionType("reduce")
+ ActionTypeError = ActionType("error")
+)
+
+type actionEntry int
+
+const actionEntryEmpty = actionEntry(0)
+
+func newShiftActionEntry(state stateNum) actionEntry {
+ return actionEntry(state * -1)
+}
+
+func newReduceActionEntry(prod productionNum) actionEntry {
+ return actionEntry(prod)
+}
+
+func (e actionEntry) isEmpty() bool {
+ return e == actionEntryEmpty
+}
+
+func (e actionEntry) describe() (ActionType, stateNum, productionNum) {
+ if e == actionEntryEmpty {
+ return ActionTypeError, stateNumInitial, productionNumNil
+ }
+ if e < 0 {
+ return ActionTypeShift, stateNum(e * -1), productionNumNil
+ }
+ return ActionTypeReduce, stateNumInitial, productionNum(e)
+}
+
+type GoToType string
+
+const (
+ GoToTypeRegistered = GoToType("registered")
+ GoToTypeError = GoToType("error")
+)
+
+type goToEntry uint
+
+const goToEntryEmpty = goToEntry(0)
+
+func newGoToEntry(state stateNum) goToEntry {
+ return goToEntry(state)
+}
+
+func (e goToEntry) describe() (GoToType, stateNum) {
+ if e == goToEntryEmpty {
+ return GoToTypeError, stateNumInitial
+ }
+ return GoToTypeRegistered, stateNum(e)
+}
+
+type conflictResolutionMethod int
+
+func (m conflictResolutionMethod) Int() int {
+ return int(m)
+}
+
+const (
+ ResolvedByPrec conflictResolutionMethod = 1
+ ResolvedByAssoc conflictResolutionMethod = 2
+ ResolvedByShift conflictResolutionMethod = 3
+ ResolvedByProdOrder conflictResolutionMethod = 4
+)
+
+type conflict interface {
+ conflict()
+}
+
+type shiftReduceConflict struct {
+ state stateNum
+ sym symbol.Symbol
+ nextState stateNum
+ prodNum productionNum
+ resolvedBy conflictResolutionMethod
+}
+
+func (c *shiftReduceConflict) conflict() {
+}
+
+type reduceReduceConflict struct {
+ state stateNum
+ sym symbol.Symbol
+ prodNum1 productionNum
+ prodNum2 productionNum
+ resolvedBy conflictResolutionMethod
+}
+
+func (c *reduceReduceConflict) conflict() {
+}
+
+var (
+ _ conflict = &shiftReduceConflict{}
+ _ conflict = &reduceReduceConflict{}
+)
+
+type ParsingTable struct {
+ actionTable []actionEntry
+ goToTable []goToEntry
+ stateCount int
+ terminalCount int
+ nonTerminalCount int
+
+ // errorTrapperStates's index means a state number, and when `errorTrapperStates[stateNum]` is `1`,
+ // the state has an item having the following form. The `α` and `β` can be empty.
+ //
+ // A → α・error β
+ errorTrapperStates []int
+
+ InitialState stateNum
+}
+
+func (t *ParsingTable) getAction(state stateNum, sym symbol.SymbolNum) (ActionType, stateNum, productionNum) {
+ pos := state.Int()*t.terminalCount + sym.Int()
+ return t.actionTable[pos].describe()
+}
+
+func (t *ParsingTable) getGoTo(state stateNum, sym symbol.SymbolNum) (GoToType, stateNum) {
+ pos := state.Int()*t.nonTerminalCount + sym.Int()
+ return t.goToTable[pos].describe()
+}
+
+func (t *ParsingTable) readAction(row int, col int) actionEntry {
+ return t.actionTable[row*t.terminalCount+col]
+}
+
+func (t *ParsingTable) writeAction(row int, col int, act actionEntry) {
+ t.actionTable[row*t.terminalCount+col] = act
+}
+
+func (t *ParsingTable) writeGoTo(state stateNum, sym symbol.Symbol, nextState stateNum) {
+ pos := state.Int()*t.nonTerminalCount + sym.Num().Int()
+ t.goToTable[pos] = newGoToEntry(nextState)
+}
+
+type lrTableBuilder struct {
+ automaton *lr0Automaton
+ prods *productionSet
+ termCount int
+ nonTermCount int
+ symTab *symbol.SymbolTableReader
+ precAndAssoc *precAndAssoc
+
+ conflicts []conflict
+}
+
+func (b *lrTableBuilder) build() (*ParsingTable, error) {
+ var ptab *ParsingTable
+ {
+ initialState := b.automaton.states[b.automaton.initialState]
+ ptab = &ParsingTable{
+ actionTable: make([]actionEntry, len(b.automaton.states)*b.termCount),
+ goToTable: make([]goToEntry, len(b.automaton.states)*b.nonTermCount),
+ stateCount: len(b.automaton.states),
+ terminalCount: b.termCount,
+ nonTerminalCount: b.nonTermCount,
+ errorTrapperStates: make([]int, len(b.automaton.states)),
+ InitialState: initialState.num,
+ }
+ }
+
+ for _, state := range b.automaton.states {
+ if state.isErrorTrapper {
+ ptab.errorTrapperStates[state.num] = 1
+ }
+
+ for sym, kID := range state.next {
+ nextState := b.automaton.states[kID]
+ if sym.IsTerminal() {
+ b.writeShiftAction(ptab, state.num, sym, nextState.num)
+ } else {
+ ptab.writeGoTo(state.num, sym, nextState.num)
+ }
+ }
+
+ for prodID := range state.reducible {
+ reducibleProd, ok := b.prods.findByID(prodID)
+ if !ok {
+ return nil, fmt.Errorf("reducible production not found: %v", prodID)
+ }
+
+ var reducibleItem *lrItem
+ for _, item := range state.items {
+ if item.prod != reducibleProd.id {
+ continue
+ }
+
+ reducibleItem = item
+ break
+ }
+ if reducibleItem == nil {
+ for _, item := range state.emptyProdItems {
+ if item.prod != reducibleProd.id {
+ continue
+ }
+
+ reducibleItem = item
+ break
+ }
+ if reducibleItem == nil {
+ return nil, fmt.Errorf("reducible item not found; state: %v, production: %v", state.num, reducibleProd.num)
+ }
+ }
+
+ for a := range reducibleItem.lookAhead.symbols {
+ b.writeReduceAction(ptab, state.num, a, reducibleProd.num)
+ }
+ }
+ }
+
+ return ptab, nil
+}
+
+// writeShiftAction writes a shift action to the parsing table. When a shift/reduce conflict occurred,
+// we prioritize the shift action.
+func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym symbol.Symbol, nextState stateNum) {
+ act := tab.readAction(state.Int(), sym.Num().Int())
+ if !act.isEmpty() {
+ ty, _, p := act.describe()
+ if ty == ActionTypeReduce {
+ act, method := b.resolveSRConflict(sym.Num(), p)
+ b.conflicts = append(b.conflicts, &shiftReduceConflict{
+ state: state,
+ sym: sym,
+ nextState: nextState,
+ prodNum: p,
+ resolvedBy: method,
+ })
+ if act == ActionTypeShift {
+ tab.writeAction(state.Int(), sym.Num().Int(), newShiftActionEntry(nextState))
+ }
+ return
+ }
+ }
+ tab.writeAction(state.Int(), sym.Num().Int(), newShiftActionEntry(nextState))
+}
+
+// writeReduceAction writes a reduce action to the parsing table. When a shift/reduce conflict occurred,
+// we prioritize the shift action, and when a reduce/reduce conflict we prioritize the action that reduces
+// the production with higher priority. Productions defined earlier in the grammar file have a higher priority.
+func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sym symbol.Symbol, prod productionNum) {
+ act := tab.readAction(state.Int(), sym.Num().Int())
+ if !act.isEmpty() {
+ ty, s, p := act.describe()
+ switch ty {
+ case ActionTypeReduce:
+ if p == prod {
+ return
+ }
+
+ b.conflicts = append(b.conflicts, &reduceReduceConflict{
+ state: state,
+ sym: sym,
+ prodNum1: p,
+ prodNum2: prod,
+ resolvedBy: ResolvedByProdOrder,
+ })
+ if p < prod {
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(p))
+ } else {
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
+ }
+ case ActionTypeShift:
+ act, method := b.resolveSRConflict(sym.Num(), prod)
+ b.conflicts = append(b.conflicts, &shiftReduceConflict{
+ state: state,
+ sym: sym,
+ nextState: s,
+ prodNum: prod,
+ resolvedBy: method,
+ })
+ if act == ActionTypeReduce {
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
+ }
+ }
+ return
+ }
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
+}
+
+func (b *lrTableBuilder) resolveSRConflict(sym symbol.SymbolNum, prod productionNum) (ActionType, conflictResolutionMethod) {
+ symPrec := b.precAndAssoc.terminalPrecedence(sym)
+ prodPrec := b.precAndAssoc.productionPredence(prod)
+ if symPrec == 0 || prodPrec == 0 {
+ return ActionTypeShift, ResolvedByShift
+ }
+ if symPrec == prodPrec {
+ assoc := b.precAndAssoc.productionAssociativity(prod)
+ if assoc != assocTypeLeft {
+ return ActionTypeShift, ResolvedByAssoc
+ }
+ return ActionTypeReduce, ResolvedByAssoc
+ }
+ if symPrec < prodPrec {
+ return ActionTypeShift, ResolvedByPrec
+ }
+ return ActionTypeReduce, ResolvedByPrec
+}
+
+func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Report, error) {
+ var terms []*spec.Terminal
+ {
+ termSyms := b.symTab.TerminalSymbols()
+ terms = make([]*spec.Terminal, len(termSyms)+1)
+
+ for _, sym := range termSyms {
+ name, ok := b.symTab.ToText(sym)
+ if !ok {
+ return nil, fmt.Errorf("failed to generate terminals: symbol not found: %v", sym)
+ }
+
+ term := &spec.Terminal{
+ Number: sym.Num().Int(),
+ Name: name,
+ }
+
+ prec := b.precAndAssoc.terminalPrecedence(sym.Num())
+ if prec != precNil {
+ term.Precedence = prec
+ }
+
+ assoc := b.precAndAssoc.terminalAssociativity(sym.Num())
+ switch assoc {
+ case assocTypeLeft:
+ term.Associativity = "l"
+ case assocTypeRight:
+ term.Associativity = "r"
+ }
+
+ terms[sym.Num()] = term
+ }
+ }
+
+ var nonTerms []*spec.NonTerminal
+ {
+ nonTermSyms := b.symTab.NonTerminalSymbols()
+ nonTerms = make([]*spec.NonTerminal, len(nonTermSyms)+1)
+ for _, sym := range nonTermSyms {
+ name, ok := b.symTab.ToText(sym)
+ if !ok {
+ return nil, fmt.Errorf("failed to generate non-terminals: symbol not found: %v", sym)
+ }
+
+ nonTerms[sym.Num()] = &spec.NonTerminal{
+ Number: sym.Num().Int(),
+ Name: name,
+ }
+ }
+ }
+
+ var prods []*spec.Production
+ {
+ ps := gram.productionSet.getAllProductions()
+ prods = make([]*spec.Production, len(ps)+1)
+ for _, p := range ps {
+ rhs := make([]int, len(p.rhs))
+ for i, e := range p.rhs {
+ if e.IsTerminal() {
+ rhs[i] = e.Num().Int()
+ } else {
+ rhs[i] = e.Num().Int() * -1
+ }
+ }
+
+ prod := &spec.Production{
+ Number: p.num.Int(),
+ LHS: p.lhs.Num().Int(),
+ RHS: rhs,
+ }
+
+ prec := b.precAndAssoc.productionPredence(p.num)
+ if prec != precNil {
+ prod.Precedence = prec
+ }
+
+ assoc := b.precAndAssoc.productionAssociativity(p.num)
+ switch assoc {
+ case assocTypeLeft:
+ prod.Associativity = "l"
+ case assocTypeRight:
+ prod.Associativity = "r"
+ }
+
+ prods[p.num.Int()] = prod
+ }
+ }
+
+ var states []*spec.State
+ {
+ srConflicts := map[stateNum][]*shiftReduceConflict{}
+ rrConflicts := map[stateNum][]*reduceReduceConflict{}
+ for _, con := range b.conflicts {
+ switch c := con.(type) {
+ case *shiftReduceConflict:
+ srConflicts[c.state] = append(srConflicts[c.state], c)
+ case *reduceReduceConflict:
+ rrConflicts[c.state] = append(rrConflicts[c.state], c)
+ }
+ }
+
+ states = make([]*spec.State, len(b.automaton.states))
+ for _, s := range b.automaton.states {
+ kernel := make([]*spec.Item, len(s.items))
+ for i, item := range s.items {
+ p, ok := b.prods.findByID(item.prod)
+ if !ok {
+ return nil, fmt.Errorf("failed to generate states: production of kernel item not found: %v", item.prod)
+ }
+
+ kernel[i] = &spec.Item{
+ Production: p.num.Int(),
+ Dot: item.dot,
+ }
+ }
+
+ sort.Slice(kernel, func(i, j int) bool {
+ if kernel[i].Production < kernel[j].Production {
+ return true
+ }
+ if kernel[i].Production > kernel[j].Production {
+ return false
+ }
+ return kernel[i].Dot < kernel[j].Dot
+ })
+
+ var shift []*spec.Transition
+ var reduce []*spec.Reduce
+ var goTo []*spec.Transition
+ {
+ TERMINALS_LOOP:
+ for _, t := range b.symTab.TerminalSymbols() {
+ act, next, prod := tab.getAction(s.num, t.Num())
+ switch act {
+ case ActionTypeShift:
+ shift = append(shift, &spec.Transition{
+ Symbol: t.Num().Int(),
+ State: next.Int(),
+ })
+ case ActionTypeReduce:
+ for _, r := range reduce {
+ if r.Production == prod.Int() {
+ r.LookAhead = append(r.LookAhead, t.Num().Int())
+ continue TERMINALS_LOOP
+ }
+ }
+ reduce = append(reduce, &spec.Reduce{
+ LookAhead: []int{t.Num().Int()},
+ Production: prod.Int(),
+ })
+ }
+ }
+
+ for _, n := range b.symTab.NonTerminalSymbols() {
+ ty, next := tab.getGoTo(s.num, n.Num())
+ if ty == GoToTypeRegistered {
+ goTo = append(goTo, &spec.Transition{
+ Symbol: n.Num().Int(),
+ State: next.Int(),
+ })
+ }
+ }
+
+ sort.Slice(shift, func(i, j int) bool {
+ return shift[i].State < shift[j].State
+ })
+ sort.Slice(reduce, func(i, j int) bool {
+ return reduce[i].Production < reduce[j].Production
+ })
+ sort.Slice(goTo, func(i, j int) bool {
+ return goTo[i].State < goTo[j].State
+ })
+ }
+
+ sr := []*spec.SRConflict{}
+ rr := []*spec.RRConflict{}
+ {
+ for _, c := range srConflicts[s.num] {
+ conflict := &spec.SRConflict{
+ Symbol: c.sym.Num().Int(),
+ State: c.nextState.Int(),
+ Production: c.prodNum.Int(),
+ ResolvedBy: c.resolvedBy.Int(),
+ }
+
+ ty, s, p := tab.getAction(s.num, c.sym.Num())
+ switch ty {
+ case ActionTypeShift:
+ n := s.Int()
+ conflict.AdoptedState = &n
+ case ActionTypeReduce:
+ n := p.Int()
+ conflict.AdoptedProduction = &n
+ }
+
+ sr = append(sr, conflict)
+ }
+
+ sort.Slice(sr, func(i, j int) bool {
+ return sr[i].Symbol < sr[j].Symbol
+ })
+
+ for _, c := range rrConflicts[s.num] {
+ conflict := &spec.RRConflict{
+ Symbol: c.sym.Num().Int(),
+ Production1: c.prodNum1.Int(),
+ Production2: c.prodNum2.Int(),
+ ResolvedBy: c.resolvedBy.Int(),
+ }
+
+ _, _, p := tab.getAction(s.num, c.sym.Num())
+ conflict.AdoptedProduction = p.Int()
+
+ rr = append(rr, conflict)
+ }
+
+ sort.Slice(rr, func(i, j int) bool {
+ return rr[i].Symbol < rr[j].Symbol
+ })
+ }
+
+ states[s.num.Int()] = &spec.State{
+ Number: s.num.Int(),
+ Kernel: kernel,
+ Shift: shift,
+ Reduce: reduce,
+ GoTo: goTo,
+ SRConflict: sr,
+ RRConflict: rr,
+ }
+ }
+ }
+
+ return &spec.Report{
+ Terminals: terms,
+ NonTerminals: nonTerms,
+ Productions: prods,
+ States: states,
+ }, nil
+}
diff --git a/src/urubu/grammar/production.go b/src/urubu/grammar/production.go
new file mode 100644
index 0000000..8f6c103
--- /dev/null
+++ b/src/urubu/grammar/production.go
@@ -0,0 +1,117 @@
+package grammar
+
+import (
+ "crypto/sha256"
+ "encoding/hex"
+ "fmt"
+
+ "urubu/grammar/symbol"
+)
+
+type productionID [32]byte
+
+func (id productionID) String() string {
+ return hex.EncodeToString(id[:])
+}
+
+func genProductionID(lhs symbol.Symbol, rhs []symbol.Symbol) productionID {
+ seq := lhs.Byte()
+ for _, sym := range rhs {
+ seq = append(seq, sym.Byte()...)
+ }
+ return productionID(sha256.Sum256(seq))
+}
+
+type productionNum uint16
+
+const (
+ productionNumNil = productionNum(0)
+ productionNumStart = productionNum(1)
+ productionNumMin = productionNum(2)
+)
+
+func (n productionNum) Int() int {
+ return int(n)
+}
+
+type production struct {
+ id productionID
+ num productionNum
+ lhs symbol.Symbol
+ rhs []symbol.Symbol
+ rhsLen int
+}
+
+func newProduction(lhs symbol.Symbol, rhs []symbol.Symbol) (*production, error) {
+ if lhs.IsNil() {
+ return nil, fmt.Errorf("LHS must be a non-nil symbol; LHS: %v, RHS: %v", lhs, rhs)
+ }
+ for _, sym := range rhs {
+ if sym.IsNil() {
+ return nil, fmt.Errorf("a symbol of RHS must be a non-nil symbol; LHS: %v, RHS: %v", lhs, rhs)
+ }
+ }
+
+ return &production{
+ id: genProductionID(lhs, rhs),
+ lhs: lhs,
+ rhs: rhs,
+ rhsLen: len(rhs),
+ }, nil
+}
+
+func (p *production) isEmpty() bool {
+ return p.rhsLen == 0
+}
+
+type productionSet struct {
+ lhs2Prods map[symbol.Symbol][]*production
+ id2Prod map[productionID]*production
+ num productionNum
+}
+
+func newProductionSet() *productionSet {
+ return &productionSet{
+ lhs2Prods: map[symbol.Symbol][]*production{},
+ id2Prod: map[productionID]*production{},
+ num: productionNumMin,
+ }
+}
+
+func (ps *productionSet) append(prod *production) {
+ if _, ok := ps.id2Prod[prod.id]; ok {
+ return
+ }
+
+ if prod.lhs.IsStart() {
+ prod.num = productionNumStart
+ } else {
+ prod.num = ps.num
+ ps.num++
+ }
+
+ if prods, ok := ps.lhs2Prods[prod.lhs]; ok {
+ ps.lhs2Prods[prod.lhs] = append(prods, prod)
+ } else {
+ ps.lhs2Prods[prod.lhs] = []*production{prod}
+ }
+ ps.id2Prod[prod.id] = prod
+}
+
+func (ps *productionSet) findByID(id productionID) (*production, bool) {
+ prod, ok := ps.id2Prod[id]
+ return prod, ok
+}
+
+func (ps *productionSet) findByLHS(lhs symbol.Symbol) ([]*production, bool) {
+ if lhs.IsNil() {
+ return nil, false
+ }
+
+ prods, ok := ps.lhs2Prods[lhs]
+ return prods, ok
+}
+
+func (ps *productionSet) getAllProductions() map[productionID]*production {
+ return ps.id2Prod
+}
diff --git a/src/urubu/grammar/semantic_error.go b/src/urubu/grammar/semantic_error.go
new file mode 100644
index 0000000..88a6b17
--- /dev/null
+++ b/src/urubu/grammar/semantic_error.go
@@ -0,0 +1,30 @@
+package grammar
+
+import "errors"
+
+var (
+ semErrNoGrammarName = errors.New("name is missing")
+ semErrSpellingInconsistency = errors.New("the identifiers are treated as the same. please use the same spelling")
+ semErrDuplicateAssoc = errors.New("associativity and precedence cannot be specified multiple times for a symbol")
+ semErrUndefinedPrec = errors.New("symbol must has precedence")
+ semErrUndefinedOrdSym = errors.New("undefined ordered symbol")
+ semErrUnusedProduction = errors.New("unused production")
+ semErrUnusedTerminal = errors.New("unused terminal")
+ semErrTermCannotBeSkipped = errors.New("a terminal used in productions cannot be skipped")
+ semErrNoProduction = errors.New("a grammar needs at least one production")
+ semErrUndefinedSym = errors.New("undefined symbol")
+ semErrDuplicateProduction = errors.New("duplicate production")
+ semErrDuplicateTerminal = errors.New("duplicate terminal")
+ semErrDuplicateFragment = errors.New("duplicate fragment")
+ semErrDuplicateName = errors.New("duplicate names are not allowed between terminals and non-terminals")
+ semErrErrSymIsReserved = errors.New("symbol 'error' is reserved as a terminal symbol")
+ semErrDuplicateLabel = errors.New("a label must be unique in an alternative")
+ semErrInvalidLabel = errors.New("a label must differ from terminal symbols or non-terminal symbols")
+ semErrDirInvalidName = errors.New("invalid directive name")
+ semErrDirInvalidParam = errors.New("invalid parameter")
+ semErrDuplicateDir = errors.New("a directive must not be duplicated")
+ semErrDuplicateElem = errors.New("duplicate element")
+ semErrAmbiguousElem = errors.New("ambiguous element")
+ semErrInvalidProdDir = errors.New("invalid production directive")
+ semErrInvalidAltDir = errors.New("invalid alternative directive")
+)
diff --git a/src/urubu/grammar/symbol/symbol.go b/src/urubu/grammar/symbol/symbol.go
new file mode 100644
index 0000000..f9e6a93
--- /dev/null
+++ b/src/urubu/grammar/symbol/symbol.go
@@ -0,0 +1,295 @@
+package symbol
+
+import (
+ "fmt"
+ "sort"
+)
+
+type symbolKind string
+
+const (
+ symbolKindNonTerminal = symbolKind("non-terminal")
+ symbolKindTerminal = symbolKind("terminal")
+)
+
+func (t symbolKind) String() string {
+ return string(t)
+}
+
+type SymbolNum uint16
+
+func (n SymbolNum) Int() int {
+ return int(n)
+}
+
+type Symbol uint16
+
+func (s Symbol) String() string {
+ kind, isStart, isEOF, num := s.describe()
+ var prefix string
+ switch {
+ case isStart:
+ prefix = "s"
+ case isEOF:
+ prefix = "e"
+ case kind == symbolKindNonTerminal:
+ prefix = "n"
+ case kind == symbolKindTerminal:
+ prefix = "t"
+ default:
+ prefix = "?"
+ }
+ return fmt.Sprintf("%v%v", prefix, num)
+}
+
+const (
+ maskKindPart = uint16(0x8000) // 1000 0000 0000 0000
+ maskNonTerminal = uint16(0x0000) // 0000 0000 0000 0000
+ maskTerminal = uint16(0x8000) // 1000 0000 0000 0000
+
+ maskSubKindpart = uint16(0x4000) // 0100 0000 0000 0000
+ maskNonStartAndEOF = uint16(0x0000) // 0000 0000 0000 0000
+ maskStartOrEOF = uint16(0x4000) // 0100 0000 0000 0000
+
+ maskNumberPart = uint16(0x3fff) // 0011 1111 1111 1111
+
+ symbolNumStart = uint16(0x0001) // 0000 0000 0000 0001
+ symbolNumEOF = uint16(0x0001) // 0000 0000 0000 0001
+
+ SymbolNil = Symbol(0) // 0000 0000 0000 0000
+ symbolStart = Symbol(maskNonTerminal | maskStartOrEOF | symbolNumStart) // 0100 0000 0000 0001
+ SymbolEOF = Symbol(maskTerminal | maskStartOrEOF | symbolNumEOF) // 1100 0000 0000 0001: The EOF symbol is treated as a terminal symbol.
+
+ // The symbol name contains `<` and `>` to avoid conflicting with user-defined symbols.
+ symbolNameEOF = "<eof>"
+
+ nonTerminalNumMin = SymbolNum(2) // The number 1 is used by a start symbol.
+ terminalNumMin = SymbolNum(2) // The number 1 is used by the EOF symbol.
+ symbolNumMax = SymbolNum(0xffff) >> 2 // 0011 1111 1111 1111
+)
+
+func newSymbol(kind symbolKind, isStart bool, num SymbolNum) (Symbol, error) {
+ if num > symbolNumMax {
+ return SymbolNil, fmt.Errorf("a symbol number exceeds the limit; limit: %v, passed: %v", symbolNumMax, num)
+ }
+ if kind == symbolKindTerminal && isStart {
+ return SymbolNil, fmt.Errorf("a start symbol must be a non-terminal symbol")
+ }
+
+ kindMask := maskNonTerminal
+ if kind == symbolKindTerminal {
+ kindMask = maskTerminal
+ }
+ startMask := maskNonStartAndEOF
+ if isStart {
+ startMask = maskStartOrEOF
+ }
+ return Symbol(kindMask | startMask | uint16(num)), nil
+}
+
+func (s Symbol) Num() SymbolNum {
+ _, _, _, num := s.describe()
+ return num
+}
+
+func (s Symbol) Byte() []byte {
+ if s.IsNil() {
+ return []byte{0, 0}
+ }
+ return []byte{byte(uint16(s) >> 8), byte(uint16(s) & 0x00ff)}
+}
+
+func (s Symbol) IsNil() bool {
+ _, _, _, num := s.describe()
+ return num == 0
+}
+
+func (s Symbol) IsStart() bool {
+ if s.IsNil() {
+ return false
+ }
+ _, isStart, _, _ := s.describe()
+ return isStart
+}
+
+func (s Symbol) isEOF() bool {
+ if s.IsNil() {
+ return false
+ }
+ _, _, isEOF, _ := s.describe()
+ return isEOF
+}
+
+func (s Symbol) isNonTerminal() bool {
+ if s.IsNil() {
+ return false
+ }
+ kind, _, _, _ := s.describe()
+ return kind == symbolKindNonTerminal
+}
+
+func (s Symbol) IsTerminal() bool {
+ if s.IsNil() {
+ return false
+ }
+ return !s.isNonTerminal()
+}
+
+func (s Symbol) describe() (symbolKind, bool, bool, SymbolNum) {
+ kind := symbolKindNonTerminal
+ if uint16(s)&maskKindPart > 0 {
+ kind = symbolKindTerminal
+ }
+ isStart := false
+ isEOF := false
+ if uint16(s)&maskSubKindpart > 0 {
+ if kind == symbolKindNonTerminal {
+ isStart = true
+ } else {
+ isEOF = true
+ }
+ }
+ num := SymbolNum(uint16(s) & maskNumberPart)
+ return kind, isStart, isEOF, num
+}
+
+type SymbolTable struct {
+ text2Sym map[string]Symbol
+ sym2Text map[Symbol]string
+ nonTermTexts []string
+ termTexts []string
+ nonTermNum SymbolNum
+ termNum SymbolNum
+}
+
+type SymbolTableWriter struct {
+ *SymbolTable
+}
+
+type SymbolTableReader struct {
+ *SymbolTable
+}
+
+func NewSymbolTable() *SymbolTable {
+ return &SymbolTable{
+ text2Sym: map[string]Symbol{
+ symbolNameEOF: SymbolEOF,
+ },
+ sym2Text: map[Symbol]string{
+ SymbolEOF: symbolNameEOF,
+ },
+ termTexts: []string{
+ "", // Nil
+ symbolNameEOF, // EOF
+ },
+ nonTermTexts: []string{
+ "", // Nil
+ "", // Start Symbol
+ },
+ nonTermNum: nonTerminalNumMin,
+ termNum: terminalNumMin,
+ }
+}
+
+func (t *SymbolTable) Writer() *SymbolTableWriter {
+ return &SymbolTableWriter{
+ SymbolTable: t,
+ }
+}
+
+func (t *SymbolTable) Reader() *SymbolTableReader {
+ return &SymbolTableReader{
+ SymbolTable: t,
+ }
+}
+
+func (w *SymbolTableWriter) RegisterStartSymbol(text string) (Symbol, error) {
+ w.text2Sym[text] = symbolStart
+ w.sym2Text[symbolStart] = text
+ w.nonTermTexts[symbolStart.Num().Int()] = text
+ return symbolStart, nil
+}
+
+func (w *SymbolTableWriter) RegisterNonTerminalSymbol(text string) (Symbol, error) {
+ if sym, ok := w.text2Sym[text]; ok {
+ return sym, nil
+ }
+ sym, err := newSymbol(symbolKindNonTerminal, false, w.nonTermNum)
+ if err != nil {
+ return SymbolNil, err
+ }
+ w.nonTermNum++
+ w.text2Sym[text] = sym
+ w.sym2Text[sym] = text
+ w.nonTermTexts = append(w.nonTermTexts, text)
+ return sym, nil
+}
+
+func (w *SymbolTableWriter) RegisterTerminalSymbol(text string) (Symbol, error) {
+ if sym, ok := w.text2Sym[text]; ok {
+ return sym, nil
+ }
+ sym, err := newSymbol(symbolKindTerminal, false, w.termNum)
+ if err != nil {
+ return SymbolNil, err
+ }
+ w.termNum++
+ w.text2Sym[text] = sym
+ w.sym2Text[sym] = text
+ w.termTexts = append(w.termTexts, text)
+ return sym, nil
+}
+
+func (r *SymbolTableReader) ToSymbol(text string) (Symbol, bool) {
+ if sym, ok := r.text2Sym[text]; ok {
+ return sym, true
+ }
+ return SymbolNil, false
+}
+
+func (r *SymbolTableReader) ToText(sym Symbol) (string, bool) {
+ text, ok := r.sym2Text[sym]
+ return text, ok
+}
+
+func (r *SymbolTableReader) TerminalSymbols() []Symbol {
+ syms := make([]Symbol, 0, r.termNum.Int()-terminalNumMin.Int())
+ for sym := range r.sym2Text {
+ if !sym.IsTerminal() || sym.IsNil() {
+ continue
+ }
+ syms = append(syms, sym)
+ }
+ sort.Slice(syms, func(i, j int) bool {
+ return syms[i] < syms[j]
+ })
+ return syms
+}
+
+func (r *SymbolTableReader) TerminalTexts() ([]string, error) {
+ if r.termNum == terminalNumMin {
+ return nil, fmt.Errorf("symbol table has no terminals")
+ }
+ return r.termTexts, nil
+}
+
+func (r *SymbolTableReader) NonTerminalSymbols() []Symbol {
+ syms := make([]Symbol, 0, r.nonTermNum.Int()-nonTerminalNumMin.Int())
+ for sym := range r.sym2Text {
+ if !sym.isNonTerminal() || sym.IsNil() {
+ continue
+ }
+ syms = append(syms, sym)
+ }
+ sort.Slice(syms, func(i, j int) bool {
+ return syms[i] < syms[j]
+ })
+ return syms
+}
+
+func (r *SymbolTableReader) NonTerminalTexts() ([]string, error) {
+ if r.nonTermNum == nonTerminalNumMin || r.nonTermTexts[symbolStart.Num().Int()] == "" {
+ return nil, fmt.Errorf("symbol table has no terminals or no start symbol")
+ }
+ return r.nonTermTexts, nil
+}
diff --git a/src/urubu/spec/grammar/description.go b/src/urubu/spec/grammar/description.go
new file mode 100644
index 0000000..0d2a0b7
--- /dev/null
+++ b/src/urubu/spec/grammar/description.go
@@ -0,0 +1,71 @@
+package grammar
+
+type Terminal struct {
+ Number int `json:"number"`
+ Name string `json:"name"`
+ Pattern string `json:"pattern"`
+ Precedence int `json:"prec"`
+ Associativity string `json:"assoc"`
+}
+
+type NonTerminal struct {
+ Number int `json:"number"`
+ Name string `json:"name"`
+}
+
+type Production struct {
+ Number int `json:"number"`
+ LHS int `json:"lhs"`
+ RHS []int `json:"rhs"`
+ Precedence int `json:"prec"`
+ Associativity string `json:"assoc"`
+}
+
+type Item struct {
+ Production int `json:"production"`
+ Dot int `json:"dot"`
+}
+
+type Transition struct {
+ Symbol int `json:"symbol"`
+ State int `json:"state"`
+}
+
+type Reduce struct {
+ LookAhead []int `json:"look_ahead"`
+ Production int `json:"production"`
+}
+
+type SRConflict struct {
+ Symbol int `json:"symbol"`
+ State int `json:"state"`
+ Production int `json:"production"`
+ AdoptedState *int `json:"adopted_state"`
+ AdoptedProduction *int `json:"adopted_production"`
+ ResolvedBy int `json:"resolved_by"`
+}
+
+type RRConflict struct {
+ Symbol int `json:"symbol"`
+ Production1 int `json:"production_1"`
+ Production2 int `json:"production_2"`
+ AdoptedProduction int `json:"adopted_production"`
+ ResolvedBy int `json:"resolved_by"`
+}
+
+type State struct {
+ Number int `json:"number"`
+ Kernel []*Item `json:"kernel"`
+ Shift []*Transition `json:"shift"`
+ Reduce []*Reduce `json:"reduce"`
+ GoTo []*Transition `json:"goto"`
+ SRConflict []*SRConflict `json:"sr_conflict"`
+ RRConflict []*RRConflict `json:"rr_conflict"`
+}
+
+type Report struct {
+ Terminals []*Terminal `json:"terminals"`
+ NonTerminals []*NonTerminal `json:"non_terminals"`
+ Productions []*Production `json:"productions"`
+ States []*State `json:"states"`
+}
diff --git a/src/urubu/spec/grammar/grammar.go b/src/urubu/spec/grammar/grammar.go
new file mode 100644
index 0000000..bf1ea89
--- /dev/null
+++ b/src/urubu/spec/grammar/grammar.go
@@ -0,0 +1,160 @@
+package grammar
+
+import "strconv"
+
+type CompiledGrammar struct {
+ Name string `json:"name"`
+ Lexical *LexicalSpec `json:"lexical"`
+ Syntactic *SyntacticSpec `json:"syntactic"`
+ ASTAction *ASTAction `json:"ast_action"`
+}
+
+// StateID represents an ID of a state of a transition table.
+type StateID int
+
+const (
+ // StateIDNil represents an empty entry of a transition table.
+ // When the driver reads this value, it raises an error meaning lexical analysis failed.
+ StateIDNil = StateID(0)
+
+ // StateIDMin is the minimum value of the state ID. All valid state IDs are represented as
+ // sequential numbers starting from this value.
+ StateIDMin = StateID(1)
+)
+
+func (id StateID) Int() int {
+ return int(id)
+}
+
+// LexModeID represents an ID of a lex mode.
+type LexModeID int
+
+const (
+ LexModeIDNil = LexModeID(0)
+ LexModeIDDefault = LexModeID(1)
+)
+
+func (n LexModeID) String() string {
+ return strconv.Itoa(int(n))
+}
+
+func (n LexModeID) Int() int {
+ return int(n)
+}
+
+func (n LexModeID) IsNil() bool {
+ return n == LexModeIDNil
+}
+
+// LexModeName represents a name of a lex mode.
+type LexModeName string
+
+const (
+ LexModeNameNil = LexModeName("")
+ LexModeNameDefault = LexModeName("default")
+)
+
+func (m LexModeName) String() string {
+ return string(m)
+}
+
+// LexKindID represents an ID of a lexical kind and is unique across all modes.
+type LexKindID int
+
+const (
+ LexKindIDNil = LexKindID(0)
+ LexKindIDMin = LexKindID(1)
+)
+
+func (id LexKindID) Int() int {
+ return int(id)
+}
+
+// LexModeKindID represents an ID of a lexical kind and is unique within a mode.
+// Use LexKindID to identify a kind across all modes uniquely.
+type LexModeKindID int
+
+const (
+ LexModeKindIDNil = LexModeKindID(0)
+ LexModeKindIDMin = LexModeKindID(1)
+)
+
+func (id LexModeKindID) Int() int {
+ return int(id)
+}
+
+// LexKindName represents a name of a lexical kind.
+type LexKindName string
+
+const LexKindNameNil = LexKindName("")
+
+func (k LexKindName) String() string {
+ return string(k)
+}
+
+type RowDisplacementTable struct {
+ OriginalRowCount int `json:"original_row_count"`
+ OriginalColCount int `json:"original_col_count"`
+ EmptyValue StateID `json:"empty_value"`
+ Entries []StateID `json:"entries"`
+ Bounds []int `json:"bounds"`
+ RowDisplacement []int `json:"row_displacement"`
+}
+
+type UniqueEntriesTable struct {
+ UniqueEntries *RowDisplacementTable `json:"unique_entries,omitempty"`
+ UncompressedUniqueEntries []StateID `json:"uncompressed_unique_entries,omitempty"`
+ RowNums []int `json:"row_nums"`
+ OriginalRowCount int `json:"original_row_count"`
+ OriginalColCount int `json:"original_col_count"`
+ EmptyValue int `json:"empty_value"`
+}
+
+type TransitionTable struct {
+ InitialStateID StateID `json:"initial_state_id"`
+ AcceptingStates []LexModeKindID `json:"accepting_states"`
+ RowCount int `json:"row_count"`
+ ColCount int `json:"col_count"`
+ Transition *UniqueEntriesTable `json:"transition,omitempty"`
+ UncompressedTransition []StateID `json:"uncompressed_transition,omitempty"`
+}
+
+type CompiledLexModeSpec struct {
+ KindNames []LexKindName `json:"kind_names"`
+ Push []LexModeID `json:"push"`
+ Pop []int `json:"pop"`
+ DFA *TransitionTable `json:"dfa"`
+}
+
+type LexicalSpec struct {
+ InitialModeID LexModeID `json:"initial_mode_id"`
+ ModeNames []LexModeName `json:"mode_names"`
+ KindNames []LexKindName `json:"kind_names"`
+ KindIDs [][]LexKindID `json:"kind_ids"`
+ CompressionLevel int `json:"compression_level"`
+ Specs []*CompiledLexModeSpec `json:"specs"`
+}
+
+type SyntacticSpec struct {
+ Action []int `json:"action"`
+ GoTo []int `json:"goto"`
+ StateCount int `json:"state_count"`
+ InitialState int `json:"initial_state"`
+ StartProduction int `json:"start_production"`
+ LHSSymbols []int `json:"lhs_symbols"`
+ AlternativeSymbolCounts []int `json:"alternative_symbol_counts"`
+ Terminals []string `json:"terminals"`
+ TerminalCount int `json:"terminal_count"`
+ TerminalSkip []int `json:"terminal_skip"`
+ KindToTerminal []int `json:"kind_to_terminal"`
+ NonTerminals []string `json:"non_terminals"`
+ NonTerminalCount int `json:"non_terminal_count"`
+ EOFSymbol int `json:"eof_symbol"`
+ ErrorSymbol int `json:"error_symbol"`
+ ErrorTrapperStates []int `json:"error_trapper_states"`
+ RecoverProductions []int `json:"recover_productions"`
+}
+
+type ASTAction struct {
+ Entries [][]int `json:"entries"`
+}
diff --git a/src/urubu/spec/grammar/parser/clexspec.json b/src/urubu/spec/grammar/parser/clexspec.json
new file mode 100644
index 0000000..d0ed3d3
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/clexspec.json
@@ -0,0 +1 @@
+{"name":"vartan","initial_mode_id":1,"mode_names":["","default","terminal","string_literal"],"kind_names":["","white_space","newline","line_comment","kw_fragment","identifier","terminal_open","string_literal_open","colon","or","semicolon","label_marker","expansion","directive_marker","ordered_symbol_marker","l_paren","r_paren","pattern","escape_symbol","terminal_close","char_seq","string_literal_close"],"kind_ids":[null,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],[0,17,18,19],[0,20,21]],"compression_level":2,"specs":[null,{"kind_names":["","white_space","newline","line_comment","kw_fragment","identifier","terminal_open","string_literal_open","colon","or","semicolon","label_marker","expansion","directive_marker","ordered_symbol_marker","l_paren","r_paren"],"push":[0,0,0,0,0,0,2,3,0,0,0,0,0,0,0,0,0],"pop":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dfa":{"initial_state_id":1,"accepting_states":[0,0,1,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,4,5,0,0,2,6,7,8,9,10,11,12,13,14,15,16],"row_count":47,"col_count":256,"transition":{"unique_entries":{"original_row_count":27,"original_col_count":256,"empty_value":0,"entries":[5,5,5,5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,9,9,9,9,9,9,9,9,9,9,9,9,11,13,13,15,18,18,18,21,2,35,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,36,43,44,0,0,37,45,46,0,0,0,0,33,4,32,32,32,32,32,32,32,32,32,32,38,40,0,0,0,0,41,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,24,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,39,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,25,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,26,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,27,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,32,32,32,32,32,32,28,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,32,32,32,32,32,32,32,30,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,2,0,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,34,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[5,5,5,5,5,5,5,5,5,5,-1,5,5,-1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,-1,-1,-1,-1,-1,-1,-1,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,-1,-1,-1,-1,17,-1,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,-1,-1,-1,-1,-1,-1,-1,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,-1,-1,-1,-1,18,-1,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,-1,-1,-1,-1,-1,-1,-1,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,-1,-1,-1,-1,19,-1,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,-1,-1,-1,-1,-1,-1,-1,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,-1,-1,-1,-1,20,-1,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,-1,-1,-1,-1,-1,-1,-1,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,-1,-1,-1,-1,21,-1,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,-1,-1,-1,-1,-1,-1,-1,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,-1,-1,-1,-1,23,-1,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,-1,-1,-1,-1,-1,-1,-1,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,-1,-1,-1,-1,24,-1,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,2,-1,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,25,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,236,1554,1555,1556,0,237,1323,301,1387,365,1291,429,493,557,1419,621,765,840,915,990,1065,1140,1215,1290,1558,1559]},"row_nums":[0,1,2,3,4,5,6,7,6,8,6,9,6,10,6,11,12,6,13,14,6,15,16,6,17,18,19,20,21,22,23,24,24,25,26,0,0,0,0,0,0,0,0,0,0,0,0],"original_row_count":47,"original_col_count":256,"empty_value":0}}},{"kind_names":["","pattern","escape_symbol","terminal_close"],"push":[0,0,0,0],"pop":[0,0,0,1],"dfa":{"initial_state_id":1,"accepting_states":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],"row_count":78,"col_count":256,"transition":{"unique_entries":{"original_row_count":46,"original_col_count":256,"empty_value":0,"entries":[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,77,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,20,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,5,5,5,5,5,5,5,5,5,5,5,7,9,9,11,14,14,14,17,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,24,24,24,24,24,24,24,24,24,24,24,24,26,28,28,30,33,33,33,36,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,60,62,62,62,62,62,62,62,62,62,62,62,62,64,66,66,68,71,71,71,74,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,58,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,0,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,41,43,43,43,43,43,43,43,43,43,43,43,43,45,47,47,49,52,52,52,55,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,0,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,0,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,-1,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,-1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,-1,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,-1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,-1,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,0,736,2548,852,2612,916,2372,980,1044,1108,2839,1172,245,2613,1236,2677,1300,2420,1364,1428,1492,2855,1556,735,2678,1620,2742,1684,2468,1748,1812,1876,2871,1940,490,2743,2004,2807,2068,2516,2132,2196,2260,2887,2324]},"row_nums":[0,1,2,3,2,4,2,5,2,6,2,7,8,2,9,10,2,11,12,2,13,2,14,2,15,2,16,2,17,2,18,19,2,20,21,2,22,23,2,24,2,25,2,26,2,27,2,28,2,29,30,2,31,32,2,33,34,2,35,2,36,2,37,2,38,2,39,2,40,41,2,42,43,2,44,45,2,0],"original_row_count":78,"original_col_count":256,"empty_value":0}}},{"kind_names":["","char_seq","string_literal_close"],"push":[0,0,0],"pop":[0,0,1],"dfa":{"initial_state_id":1,"accepting_states":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],"row_count":40,"col_count":256,"transition":{"unique_entries":{"original_row_count":24,"original_col_count":256,"empty_value":0,"entries":[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,39,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,5,5,5,5,5,5,5,5,5,5,5,7,9,9,11,14,14,14,17,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,24,24,24,24,24,24,24,24,24,24,24,24,26,28,28,30,33,33,33,36,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,-1,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,0,246,1194,362,1258,426,1114,490,554,618,1355,682,245,1259,746,1323,810,1162,874,938,1002,1371,1066]},"row_nums":[0,1,2,3,2,4,2,5,2,6,2,7,8,2,9,10,2,11,12,2,13,2,14,2,15,2,16,2,17,2,18,19,2,20,21,2,22,23,2,0],"original_row_count":40,"original_col_count":256,"empty_value":0}}}]}
diff --git a/src/urubu/spec/grammar/parser/lexer.go b/src/urubu/spec/grammar/parser/lexer.go
new file mode 100644
index 0000000..bd8a24f
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/lexer.go
@@ -0,0 +1,297 @@
+//go:generate maleeni compile lexspec.json -o clexspec.json
+//go:generate maleeni-go clexspec.json --package parser
+
+package parser
+
+import (
+ _ "embed"
+ "fmt"
+ "io"
+ "regexp"
+ "strings"
+
+ verr "urubu/error"
+)
+
+type tokenKind string
+
+const (
+ tokenKindKWFragment = tokenKind("fragment")
+ tokenKindID = tokenKind("id")
+ tokenKindTerminalPattern = tokenKind("terminal pattern")
+ tokenKindStringLiteral = tokenKind("string")
+ tokenKindColon = tokenKind(":")
+ tokenKindOr = tokenKind("|")
+ tokenKindSemicolon = tokenKind(";")
+ tokenKindLabelMarker = tokenKind("@")
+ tokenKindDirectiveMarker = tokenKind("#")
+ tokenKindExpantion = tokenKind("...")
+ tokenKindOrderedSymbolMarker = tokenKind("$")
+ tokenKindLParen = tokenKind("(")
+ tokenKindRParen = tokenKind(")")
+ tokenKindNewline = tokenKind("newline")
+ tokenKindEOF = tokenKind("eof")
+ tokenKindInvalid = tokenKind("invalid")
+)
+
+var (
+ reIDChar = regexp.MustCompile(`^[0-9a-z_]+$`)
+ reIDInvalidDigitsPos = regexp.MustCompile(`^[0-9]`)
+)
+
+type Position struct {
+ Row int
+ Col int
+}
+
+func newPosition(row, col int) Position {
+ return Position{
+ Row: row,
+ Col: col,
+ }
+}
+
+type token struct {
+ kind tokenKind
+ text string
+ pos Position
+}
+
+func newSymbolToken(kind tokenKind, pos Position) *token {
+ return &token{
+ kind: kind,
+ pos: pos,
+ }
+}
+
+func newIDToken(text string, pos Position) *token {
+ return &token{
+ kind: tokenKindID,
+ text: text,
+ pos: pos,
+ }
+}
+
+func newTerminalPatternToken(text string, pos Position) *token {
+ return &token{
+ kind: tokenKindTerminalPattern,
+ text: text,
+ pos: pos,
+ }
+}
+
+func newStringLiteralToken(text string, pos Position) *token {
+ return &token{
+ kind: tokenKindStringLiteral,
+ text: text,
+ pos: pos,
+ }
+}
+
+func newEOFToken() *token {
+ return &token{
+ kind: tokenKindEOF,
+ }
+}
+
+func newInvalidToken(text string, pos Position) *token {
+ return &token{
+ kind: tokenKindInvalid,
+ text: text,
+ pos: pos,
+ }
+}
+
+type lexer struct {
+ d *Lexer
+ buf *token
+}
+
+func newLexer(src io.Reader) (*lexer, error) {
+ d, err := NewLexer(NewLexSpec(), src)
+ if err != nil {
+ return nil, err
+ }
+ return &lexer{
+ d: d,
+ }, nil
+}
+
+func (l *lexer) next() (*token, error) {
+ if l.buf != nil {
+ tok := l.buf
+ l.buf = nil
+ return tok, nil
+ }
+
+ var newline *token
+ for {
+ tok, err := l.lexAndSkipWSs()
+ if err != nil {
+ return nil, err
+ }
+ if tok.kind == tokenKindNewline {
+ newline = tok
+ continue
+ }
+
+ if newline != nil {
+ l.buf = tok
+ return newline, nil
+ }
+ return tok, nil
+ }
+}
+
+func (l *lexer) lexAndSkipWSs() (*token, error) {
+ var tok *Token
+ for {
+ var err error
+ tok, err = l.d.Next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.Invalid {
+ return newInvalidToken(string(tok.Lexeme), newPosition(tok.Row+1, tok.Col+1)), nil
+ }
+ if tok.EOF {
+ return newEOFToken(), nil
+ }
+ switch tok.KindID {
+ case KindIDWhiteSpace:
+ continue
+ case KindIDLineComment:
+ continue
+ }
+
+ break
+ }
+
+ switch tok.KindID {
+ case KindIDNewline:
+ return newSymbolToken(tokenKindNewline, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDKwFragment:
+ return newSymbolToken(tokenKindKWFragment, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDIdentifier:
+ if !reIDChar.Match(tok.Lexeme) {
+ return nil, &verr.SpecError{
+ Cause: synErrIDInvalidChar,
+ Detail: string(tok.Lexeme),
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ if strings.HasPrefix(string(tok.Lexeme), "_") || strings.HasSuffix(string(tok.Lexeme), "_") {
+ return nil, &verr.SpecError{
+ Cause: synErrIDInvalidUnderscorePos,
+ Detail: string(tok.Lexeme),
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ if strings.Contains(string(tok.Lexeme), "__") {
+ return nil, &verr.SpecError{
+ Cause: synErrIDConsecutiveUnderscores,
+ Detail: string(tok.Lexeme),
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ if reIDInvalidDigitsPos.Match(tok.Lexeme) {
+ return nil, &verr.SpecError{
+ Cause: synErrIDInvalidDigitsPos,
+ Detail: string(tok.Lexeme),
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ return newIDToken(string(tok.Lexeme), newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDTerminalOpen:
+ var b strings.Builder
+ for {
+ tok, err := l.d.Next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.EOF {
+ return nil, &verr.SpecError{
+ Cause: synErrUnclosedTerminal,
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ switch tok.KindID {
+ case KindIDPattern:
+ // The escape sequences in a pattern string are interpreted by the lexer, except for the \".
+ // We must interpret the \" before passing them to the lexer because they are delimiters for
+ // the pattern strings.
+ fmt.Fprint(&b, strings.ReplaceAll(string(tok.Lexeme), `\"`, `"`))
+ case KindIDEscapeSymbol:
+ return nil, &verr.SpecError{
+ Cause: synErrIncompletedEscSeq,
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ case KindIDTerminalClose:
+ pat := b.String()
+ if pat == "" {
+ return nil, &verr.SpecError{
+ Cause: synErrEmptyPattern,
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ return newTerminalPatternToken(pat, newPosition(tok.Row+1, tok.Col+1)), nil
+ }
+ }
+ case KindIDStringLiteralOpen:
+ var b strings.Builder
+ for {
+ tok, err := l.d.Next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.EOF {
+ return nil, &verr.SpecError{
+ Cause: synErrUnclosedString,
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ switch tok.KindID {
+ case KindIDCharSeq:
+ fmt.Fprint(&b, string(tok.Lexeme))
+ case KindIDStringLiteralClose:
+ str := b.String()
+ if str == "" {
+ return nil, &verr.SpecError{
+ Cause: synErrEmptyString,
+ Row: tok.Row + 1,
+ Col: tok.Col + 1,
+ }
+ }
+ return newStringLiteralToken(str, newPosition(tok.Row+1, tok.Col+1)), nil
+ }
+ }
+ case KindIDColon:
+ return newSymbolToken(tokenKindColon, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDOr:
+ return newSymbolToken(tokenKindOr, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDSemicolon:
+ return newSymbolToken(tokenKindSemicolon, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDLabelMarker:
+ return newSymbolToken(tokenKindLabelMarker, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDDirectiveMarker:
+ return newSymbolToken(tokenKindDirectiveMarker, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDExpansion:
+ return newSymbolToken(tokenKindExpantion, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDOrderedSymbolMarker:
+ return newSymbolToken(tokenKindOrderedSymbolMarker, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDLParen:
+ return newSymbolToken(tokenKindLParen, newPosition(tok.Row+1, tok.Col+1)), nil
+ case KindIDRParen:
+ return newSymbolToken(tokenKindRParen, newPosition(tok.Row+1, tok.Col+1)), nil
+ default:
+ return newInvalidToken(string(tok.Lexeme), newPosition(tok.Row+1, tok.Col+1)), nil
+ }
+}
diff --git a/src/urubu/spec/grammar/parser/lexspec.json b/src/urubu/spec/grammar/parser/lexspec.json
new file mode 100644
index 0000000..caf1f0e
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/lexspec.json
@@ -0,0 +1,123 @@
+{
+ "name": "vartan",
+ "entries": [
+ {
+ "fragment": true,
+ "kind": "lf",
+ "pattern": "\\u{000A}"
+ },
+ {
+ "fragment": true,
+ "kind": "cr",
+ "pattern": "\\u{000D}"
+ },
+ {
+ "fragment": true,
+ "kind": "ht",
+ "pattern": "\\u{0009}"
+ },
+ {
+ "fragment": true,
+ "kind": "sp",
+ "pattern": "\\u{0020}"
+ },
+ {
+ "fragment": true,
+ "kind": "newline",
+ "pattern": "\\f{lf}|\\f{cr}|\\f{cr}\\f{lf}"
+ },
+ {
+ "kind": "white_space",
+ "pattern": "(\\f{ht}|\\f{sp})+"
+ },
+ {
+ "kind": "newline",
+ "pattern": "\\f{newline}"
+ },
+ {
+ "kind": "line_comment",
+ "pattern": "//[^\\u{000A}\\u{000D}]*"
+ },
+ {
+ "kind": "kw_fragment",
+ "pattern": "fragment"
+ },
+ {
+ "kind": "identifier",
+ "pattern": "[0-9A-Za-z_]+"
+ },
+ {
+ "kind": "terminal_open",
+ "pattern": "\"",
+ "push": "terminal"
+ },
+ {
+ "modes": ["terminal"],
+ "kind": "pattern",
+ "pattern": "([^\"\\\\]|\\\\.)+"
+ },
+ {
+ "modes": ["terminal"],
+ "kind": "escape_symbol",
+ "pattern": "\\\\"
+ },
+ {
+ "modes": ["terminal"],
+ "kind": "terminal_close",
+ "pattern": "\"",
+ "pop": true
+ },
+ {
+ "kind": "string_literal_open",
+ "pattern": "'",
+ "push": "string_literal"
+ },
+ {
+ "modes": ["string_literal"],
+ "kind": "char_seq",
+ "pattern": "[^']+"
+ },
+ {
+ "modes": ["string_literal"],
+ "kind": "string_literal_close",
+ "pattern": "'",
+ "pop": true
+ },
+ {
+ "kind": "colon",
+ "pattern": ":"
+ },
+ {
+ "kind": "or",
+ "pattern": "\\|"
+ },
+ {
+ "kind": "semicolon",
+ "pattern": ";"
+ },
+ {
+ "kind": "label_marker",
+ "pattern": "@"
+ },
+ {
+ "kind": "expansion",
+ "pattern": "\\.\\.\\."
+ },
+ {
+ "kind": "directive_marker",
+ "pattern": "#"
+ },
+ {
+ "kind": "ordered_symbol_marker",
+ "pattern": "$"
+ },
+ {
+ "kind": "l_paren",
+ "pattern": "\\("
+ },
+ {
+ "kind": "r_paren",
+ "pattern": "\\)"
+ }
+ ]
+}
diff --git a/src/urubu/spec/grammar/parser/parser.go b/src/urubu/spec/grammar/parser/parser.go
new file mode 100644
index 0000000..b604074
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/parser.go
@@ -0,0 +1,582 @@
+package parser
+
+import (
+ "fmt"
+ "io"
+
+ verr "urubu/error"
+ spec "urubu/spec/grammar"
+)
+
+type RootNode struct {
+ Directives []*DirectiveNode
+ Productions []*ProductionNode
+ LexProductions []*ProductionNode
+ Fragments []*FragmentNode
+}
+
+type ProductionNode struct {
+ Directives []*DirectiveNode
+ LHS string
+ RHS []*AlternativeNode
+ Pos Position
+}
+
+func (n *ProductionNode) isLexical() bool {
+ if len(n.RHS) == 1 && len(n.RHS[0].Elements) == 1 && n.RHS[0].Elements[0].Pattern != "" {
+ return true
+ }
+ return false
+}
+
+type AlternativeNode struct {
+ Elements []*ElementNode
+ Directives []*DirectiveNode
+ Pos Position
+}
+
+type ElementNode struct {
+ ID string
+ Pattern string
+ Label *LabelNode
+ Literally bool
+ Pos Position
+}
+
+type LabelNode struct {
+ Name string
+ Pos Position
+}
+
+type DirectiveNode struct {
+ Name string
+ Parameters []*ParameterNode
+ Pos Position
+}
+
+type ParameterNode struct {
+ ID string
+ Pattern string
+ String string
+ OrderedSymbol string
+ Group []*DirectiveNode
+ Expansion bool
+ Pos Position
+}
+
+type FragmentNode struct {
+ LHS string
+ RHS string
+ Pos Position
+}
+
+func raiseSyntaxError(row int, synErr *SyntaxError) {
+ panic(&verr.SpecError{
+ Cause: synErr,
+ Row: row,
+ })
+}
+
+func raiseSyntaxErrorWithDetail(row int, synErr *SyntaxError, detail string) {
+ panic(&verr.SpecError{
+ Cause: synErr,
+ Detail: detail,
+ Row: row,
+ })
+}
+
+func Parse(src io.Reader) (*RootNode, error) {
+ p, err := newParser(src)
+ if err != nil {
+ return nil, err
+ }
+
+ return p.parse()
+}
+
+type parser struct {
+ lex *lexer
+ peekedTok *token
+ lastTok *token
+ errs verr.SpecErrors
+
+ // A token position that the parser read at last.
+ // It is used as additional information in error messages.
+ pos Position
+}
+
+func newParser(src io.Reader) (*parser, error) {
+ lex, err := newLexer(src)
+ if err != nil {
+ return nil, err
+ }
+ return &parser{
+ lex: lex,
+ }, nil
+}
+
+func (p *parser) parse() (root *RootNode, retErr error) {
+ root = p.parseRoot()
+ if len(p.errs) > 0 {
+ return nil, p.errs
+ }
+
+ return root, nil
+}
+
+func (p *parser) parseRoot() *RootNode {
+ defer func() {
+ err := recover()
+ if err != nil {
+ specErr, ok := err.(*verr.SpecError)
+ if !ok {
+ panic(fmt.Errorf("an unexpected error occurred: %v", err))
+ }
+ p.errs = append(p.errs, specErr)
+ }
+ }()
+
+ var dirs []*DirectiveNode
+ var prods []*ProductionNode
+ var lexProds []*ProductionNode
+ var fragments []*FragmentNode
+ for {
+ dir := p.parseTopLevelDirective()
+ if dir != nil {
+ dirs = append(dirs, dir)
+ continue
+ }
+
+ fragment := p.parseFragment()
+ if fragment != nil {
+ fragments = append(fragments, fragment)
+ continue
+ }
+
+ prod := p.parseProduction()
+ if prod != nil {
+ if prod.isLexical() {
+ lexProds = append(lexProds, prod)
+ } else {
+ prods = append(prods, prod)
+ }
+ continue
+ }
+
+ if p.consume(tokenKindEOF) {
+ break
+ }
+ }
+
+ return &RootNode{
+ Directives: dirs,
+ Productions: prods,
+ LexProductions: lexProds,
+ Fragments: fragments,
+ }
+}
+
+func (p *parser) parseTopLevelDirective() *DirectiveNode {
+ defer func() {
+ err := recover()
+ if err == nil {
+ return
+ }
+
+ specErr, ok := err.(*verr.SpecError)
+ if !ok {
+ panic(err)
+ }
+
+ p.errs = append(p.errs, specErr)
+ p.skipOverTo(tokenKindSemicolon)
+ }()
+
+ dir := p.parseDirective()
+ if dir == nil {
+ return nil
+ }
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindSemicolon) {
+ raiseSyntaxError(p.pos.Row, synErrTopLevelDirNoSemicolon)
+ }
+
+ return dir
+}
+
+func (p *parser) parseFragment() *FragmentNode {
+ defer func() {
+ err := recover()
+ if err == nil {
+ return
+ }
+
+ specErr, ok := err.(*verr.SpecError)
+ if !ok {
+ panic(err)
+ }
+
+ p.errs = append(p.errs, specErr)
+ p.skipOverTo(tokenKindSemicolon)
+ }()
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindKWFragment) {
+ return nil
+ }
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindID) {
+ raiseSyntaxError(p.pos.Row, synErrNoProductionName)
+ }
+ lhs := p.lastTok.text
+ lhsPos := p.lastTok.pos
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindColon) {
+ raiseSyntaxError(p.pos.Row, synErrNoColon)
+ }
+
+ var rhs string
+ switch {
+ case p.consume(tokenKindTerminalPattern):
+ rhs = p.lastTok.text
+ case p.consume(tokenKindStringLiteral):
+ rhs = spec.EscapePattern(p.lastTok.text)
+ default:
+ raiseSyntaxError(p.pos.Row, synErrFragmentNoPattern)
+ }
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindSemicolon) {
+ raiseSyntaxError(p.pos.Row, synErrNoSemicolon)
+ }
+
+ if !p.consume(tokenKindNewline) {
+ if !p.consume(tokenKindEOF) {
+ raiseSyntaxError(p.pos.Row, synErrSemicolonNoNewline)
+ }
+ }
+
+ return &FragmentNode{
+ LHS: lhs,
+ RHS: rhs,
+ Pos: lhsPos,
+ }
+}
+
+func (p *parser) parseProduction() *ProductionNode {
+ defer func() {
+ err := recover()
+ if err == nil {
+ return
+ }
+
+ specErr, ok := err.(*verr.SpecError)
+ if !ok {
+ panic(err)
+ }
+
+ p.errs = append(p.errs, specErr)
+ p.skipOverTo(tokenKindSemicolon)
+ }()
+
+ p.consume(tokenKindNewline)
+
+ if p.consume(tokenKindEOF) {
+ return nil
+ }
+
+ if !p.consume(tokenKindID) {
+ raiseSyntaxError(p.pos.Row, synErrNoProductionName)
+ }
+ lhs := p.lastTok.text
+ lhsPos := p.lastTok.pos
+
+ var dirs []*DirectiveNode
+ for {
+ dir := p.parseDirective()
+ if dir == nil {
+ break
+ }
+ dirs = append(dirs, dir)
+ }
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindColon) {
+ raiseSyntaxError(p.pos.Row, synErrNoColon)
+ }
+
+ alt := p.parseAlternative()
+ rhs := []*AlternativeNode{alt}
+ for {
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindOr) {
+ break
+ }
+ alt := p.parseAlternative()
+ rhs = append(rhs, alt)
+ }
+
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindSemicolon) {
+ raiseSyntaxError(p.pos.Row, synErrNoSemicolon)
+ }
+
+ if !p.consume(tokenKindNewline) {
+ if !p.consume(tokenKindEOF) {
+ raiseSyntaxError(p.pos.Row, synErrSemicolonNoNewline)
+ }
+ }
+
+ prod := &ProductionNode{
+ Directives: dirs,
+ LHS: lhs,
+ RHS: rhs,
+ Pos: lhsPos,
+ }
+
+ // Vartan's driver must provide a user with the names of expected tokens when a syntax error occurs.
+ // However, if a pattern appears directly in an alternative, Vartan's compiler cannot assign an appropriate
+ // name to the pattern. Therefore, this code prohibits alternatives from containing patterns.
+ if !prod.isLexical() {
+ for _, alt := range prod.RHS {
+ for _, elem := range alt.Elements {
+ if elem.Pattern != "" {
+ raiseSyntaxError(elem.Pos.Row, synErrPatternInAlt)
+ }
+ }
+ }
+ }
+
+ return prod
+}
+
+func (p *parser) parseAlternative() *AlternativeNode {
+ elems := []*ElementNode{}
+ for {
+ elem := p.parseElement()
+ if elem == nil {
+ break
+ }
+ elems = append(elems, elem)
+ }
+
+ // When a length of an alternative is zero, we cannot set a position.
+ var firstElemPos Position
+ if len(elems) > 0 {
+ firstElemPos = elems[0].Pos
+ }
+
+ var dirs []*DirectiveNode
+ for {
+ dir := p.parseDirective()
+ if dir == nil {
+ break
+ }
+ dirs = append(dirs, dir)
+ }
+
+ return &AlternativeNode{
+ Elements: elems,
+ Directives: dirs,
+ Pos: firstElemPos,
+ }
+}
+
+func (p *parser) parseElement() *ElementNode {
+ var elem *ElementNode
+ switch {
+ case p.consume(tokenKindID):
+ elem = &ElementNode{
+ ID: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindTerminalPattern):
+ elem = &ElementNode{
+ Pattern: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindStringLiteral):
+ elem = &ElementNode{
+ Pattern: p.lastTok.text,
+ Literally: true,
+ Pos: p.lastTok.pos,
+ }
+ default:
+ if p.consume(tokenKindLabelMarker) {
+ raiseSyntaxError(p.pos.Row, synErrLabelWithNoSymbol)
+ }
+ return nil
+ }
+ if p.consume(tokenKindLabelMarker) {
+ if !p.consume(tokenKindID) {
+ raiseSyntaxError(p.pos.Row, synErrNoLabel)
+ }
+ elem.Label = &LabelNode{
+ Name: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ }
+ return elem
+}
+
+func (p *parser) parseDirective() *DirectiveNode {
+ p.consume(tokenKindNewline)
+
+ if !p.consume(tokenKindDirectiveMarker) {
+ return nil
+ }
+ dirPos := p.lastTok.pos
+
+ if !p.consume(tokenKindID) {
+ raiseSyntaxError(p.pos.Row, synErrNoDirectiveName)
+ }
+ name := p.lastTok.text
+
+ var params []*ParameterNode
+ for {
+ param := p.parseParameter()
+ if param == nil {
+ break
+ }
+ params = append(params, param)
+ }
+
+ return &DirectiveNode{
+ Name: name,
+ Parameters: params,
+ Pos: dirPos,
+ }
+}
+
+func (p *parser) parseParameter() *ParameterNode {
+ var param *ParameterNode
+ switch {
+ case p.consume(tokenKindID):
+ param = &ParameterNode{
+ ID: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindTerminalPattern):
+ param = &ParameterNode{
+ Pattern: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindStringLiteral):
+ param = &ParameterNode{
+ String: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindOrderedSymbolMarker):
+ if !p.consume(tokenKindID) {
+ raiseSyntaxError(p.pos.Row, synErrNoOrderedSymbolName)
+ }
+ param = &ParameterNode{
+ OrderedSymbol: p.lastTok.text,
+ Pos: p.lastTok.pos,
+ }
+ case p.consume(tokenKindLParen):
+ pos := p.lastTok.pos
+ var g []*DirectiveNode
+ for {
+ dir := p.parseDirective()
+ if dir == nil {
+ break
+ }
+ g = append(g, dir)
+ }
+ if !p.consume(tokenKindRParen) {
+ raiseSyntaxError(p.pos.Row, synErrUnclosedDirGroup)
+ }
+ if len(g) == 0 {
+ // Set an empty slice representing an empty directive group to distinguish between the following two cases.
+ //
+ // - #prec (); // vartan allows this case.
+ // - #prec; // This case will raise an error.
+ g = []*DirectiveNode{}
+ }
+ param = &ParameterNode{
+ Group: g,
+ Pos: pos,
+ }
+ }
+ if p.consume(tokenKindExpantion) {
+ switch {
+ case param == nil:
+ raiseSyntaxError(p.pos.Row, synErrStrayExpOp)
+ case param.ID == "":
+ raiseSyntaxError(p.pos.Row, synErrInvalidExpOperand)
+ }
+ param.Expansion = true
+ }
+ return param
+}
+
+func (p *parser) consume(expected tokenKind) bool {
+ var tok *token
+ var err error
+ if p.peekedTok != nil {
+ tok = p.peekedTok
+ p.peekedTok = nil
+ } else {
+ tok, err = p.lex.next()
+ if err != nil {
+ panic(err)
+ }
+ }
+ p.pos = tok.pos
+ if tok.kind == tokenKindInvalid {
+ raiseSyntaxErrorWithDetail(p.pos.Row, synErrInvalidToken, tok.text)
+ }
+ if tok.kind == expected {
+ p.lastTok = tok
+ return true
+ }
+ p.peekedTok = tok
+
+ return false
+}
+
+func (p *parser) skip() {
+ var tok *token
+ var err error
+ for {
+ if p.peekedTok != nil {
+ tok = p.peekedTok
+ p.peekedTok = nil
+ } else {
+ tok, err = p.lex.next()
+ if err != nil {
+ p.errs = append(p.errs, &verr.SpecError{
+ Cause: err,
+ Row: p.pos.Row,
+ })
+ continue
+ }
+ }
+
+ break
+ }
+
+ p.lastTok = tok
+ p.pos = tok.pos
+}
+
+func (p *parser) skipOverTo(kind tokenKind) {
+ for {
+ if p.consume(kind) || p.consume(tokenKindEOF) {
+ return
+ }
+ p.skip()
+ }
+}
diff --git a/src/urubu/spec/grammar/parser/syntax_error.go b/src/urubu/spec/grammar/parser/syntax_error.go
new file mode 100644
index 0000000..719fb94
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/syntax_error.go
@@ -0,0 +1,45 @@
+package parser
+
+type SyntaxError struct {
+ message string
+}
+
+func newSyntaxError(message string) *SyntaxError {
+ return &SyntaxError{
+ message: message,
+ }
+}
+
+func (e *SyntaxError) Error() string {
+ return e.message
+}
+
+var (
+ // lexical errors
+ synErrIDInvalidChar = newSyntaxError("an identifier can contain only the lower-case letter, the digits, and the underscore")
+ synErrIDInvalidUnderscorePos = newSyntaxError("the underscore cannot be placed at the beginning or end of an identifier")
+ synErrIDConsecutiveUnderscores = newSyntaxError("the underscore cannot be placed consecutively")
+ synErrIDInvalidDigitsPos = newSyntaxError("the digits cannot be placed at the biginning of an identifier")
+ synErrUnclosedTerminal = newSyntaxError("unclosed terminal")
+ synErrUnclosedString = newSyntaxError("unclosed string")
+ synErrIncompletedEscSeq = newSyntaxError("incompleted escape sequence; unexpected EOF following a backslash")
+ synErrEmptyPattern = newSyntaxError("a pattern must include at least one character")
+ synErrEmptyString = newSyntaxError("a string must include at least one character")
+
+ // syntax errors
+ synErrInvalidToken = newSyntaxError("invalid token")
+ synErrTopLevelDirNoSemicolon = newSyntaxError("a top-level directive must be followed by ;")
+ synErrNoProductionName = newSyntaxError("a production name is missing")
+ synErrNoColon = newSyntaxError("the colon must precede alternatives")
+ synErrNoSemicolon = newSyntaxError("the semicolon is missing at the last of an alternative")
+ synErrLabelWithNoSymbol = newSyntaxError("a label must follow a symbol")
+ synErrNoLabel = newSyntaxError("an identifier that represents a label is missing after the label marker @")
+ synErrNoDirectiveName = newSyntaxError("a directive needs a name")
+ synErrNoOrderedSymbolName = newSyntaxError("an ordered symbol name is missing")
+ synErrUnclosedDirGroup = newSyntaxError("a directive group must be closed by )")
+ synErrPatternInAlt = newSyntaxError("a pattern literal cannot appear directly in an alternative. instead, please define a terminal symbol with the pattern literal")
+ synErrStrayExpOp = newSyntaxError("an expansion operator ... must be preceded by an identifier")
+ synErrInvalidExpOperand = newSyntaxError("an expansion operator ... can be applied to only an identifier")
+ synErrSemicolonNoNewline = newSyntaxError("a semicolon must be followed by a newline")
+ synErrFragmentNoPattern = newSyntaxError("a fragment needs one pattern element")
+)
diff --git a/src/urubu/spec/grammar/parser/vartan_lexer.go b/src/urubu/spec/grammar/parser/vartan_lexer.go
new file mode 100644
index 0000000..76ddfde
--- /dev/null
+++ b/src/urubu/spec/grammar/parser/vartan_lexer.go
@@ -0,0 +1,1339 @@
+// Code generated by maleeni-go. DO NOT EDIT.
+package parser
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+)
+
+type ModeID int
+
+func (id ModeID) Int() int {
+ return int(id)
+}
+
+type StateID int
+
+func (id StateID) Int() int {
+ return int(id)
+}
+
+type KindID int
+
+func (id KindID) Int() int {
+ return int(id)
+}
+
+type ModeKindID int
+
+func (id ModeKindID) Int() int {
+ return int(id)
+}
+
+type LexSpec interface {
+ InitialMode() ModeID
+ Pop(mode ModeID, modeKind ModeKindID) bool
+ Push(mode ModeID, modeKind ModeKindID) (ModeID, bool)
+ ModeName(mode ModeID) string
+ InitialState(mode ModeID) StateID
+ NextState(mode ModeID, state StateID, v int) (StateID, bool)
+ Accept(mode ModeID, state StateID) (ModeKindID, bool)
+ KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string)
+}
+
+// Token representes a token.
+type Token struct {
+ // ModeID is an ID of a lex mode.
+ ModeID ModeID
+
+ // KindID is an ID of a kind. This is unique among all modes.
+ KindID KindID
+
+ // ModeKindID is an ID of a lexical kind. This is unique only within a mode.
+ // Note that you need to use KindID field if you want to identify a kind across all modes.
+ ModeKindID ModeKindID
+
+ // Row is a row number where a lexeme appears.
+ Row int
+
+ // Col is a column number where a lexeme appears.
+ // Note that Col is counted in code points, not bytes.
+ Col int
+
+ // Lexeme is a byte sequence matched a pattern of a lexical specification.
+ Lexeme []byte
+
+ // When this field is true, it means the token is the EOF token.
+ EOF bool
+
+ // When this field is true, it means the token is an error token.
+ Invalid bool
+}
+
+type LexerOption func(l *Lexer) error
+
+// DisableModeTransition disables the active mode transition. Thus, even if the lexical specification has the push and pop
+// operations, the lexer doesn't perform these operations. When the lexical specification has multiple modes, and this option is
+// enabled, you need to call the Lexer.Push and Lexer.Pop methods to perform the mode transition. You can use the Lexer.Mode method
+// to know the current lex mode.
+func DisableModeTransition() LexerOption {
+ return func(l *Lexer) error {
+ l.passiveModeTran = true
+ return nil
+ }
+}
+
+type Lexer struct {
+ spec LexSpec
+ src []byte
+ srcPtr int
+ row int
+ col int
+ prevRow int
+ prevCol int
+ tokBuf []*Token
+ modeStack []ModeID
+ passiveModeTran bool
+}
+
+// NewLexer returns a new lexer.
+func NewLexer(spec LexSpec, src io.Reader, opts ...LexerOption) (*Lexer, error) {
+ b, err := ioutil.ReadAll(src)
+ if err != nil {
+ return nil, err
+ }
+ l := &Lexer{
+ spec: spec,
+ src: b,
+ srcPtr: 0,
+ row: 0,
+ col: 0,
+ modeStack: []ModeID{
+ spec.InitialMode(),
+ },
+ passiveModeTran: false,
+ }
+ for _, opt := range opts {
+ err := opt(l)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return l, nil
+}
+
+// Next returns a next token.
+func (l *Lexer) Next() (*Token, error) {
+ if len(l.tokBuf) > 0 {
+ tok := l.tokBuf[0]
+ l.tokBuf = l.tokBuf[1:]
+ return tok, nil
+ }
+
+ tok, err := l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ return tok, nil
+ }
+ errTok := tok
+ for {
+ tok, err = l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ break
+ }
+ errTok.Lexeme = append(errTok.Lexeme, tok.Lexeme...)
+ }
+ l.tokBuf = append(l.tokBuf, tok)
+
+ return errTok, nil
+}
+
+func (l *Lexer) nextAndTransition() (*Token, error) {
+ tok, err := l.next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.EOF || tok.Invalid {
+ return tok, nil
+ }
+ if l.passiveModeTran {
+ return tok, nil
+ }
+ mode := l.Mode()
+ if l.spec.Pop(mode, tok.ModeKindID) {
+ err := l.PopMode()
+ if err != nil {
+ return nil, err
+ }
+ }
+ if mode, ok := l.spec.Push(mode, tok.ModeKindID); ok {
+ l.PushMode(mode)
+ }
+ // The checking length of the mode stack must be at after pop and push operations because those operations can be performed
+ // at the same time. When the mode stack has just one element and popped it, the mode stack will be temporarily emptied.
+ // However, since a push operation may be performed immediately after it, the lexer allows the stack to be temporarily empty.
+ if len(l.modeStack) == 0 {
+ return nil, fmt.Errorf("a mode stack must have at least one element")
+ }
+ return tok, nil
+}
+
+func (l *Lexer) next() (*Token, error) {
+ mode := l.Mode()
+ state := l.spec.InitialState(mode)
+ buf := []byte{}
+ unfixedBufLen := 0
+ row := l.row
+ col := l.col
+ var tok *Token
+ for {
+ v, eof := l.read()
+ if eof {
+ if tok != nil {
+ l.unread(unfixedBufLen)
+ return tok, nil
+ }
+ // When `buf` has unaccepted data and reads the EOF, the lexer treats the buffered data as an invalid token.
+ if len(buf) > 0 {
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Row: 0,
+ Col: 0,
+ EOF: true,
+ }, nil
+ }
+ buf = append(buf, v)
+ unfixedBufLen++
+ nextState, ok := l.spec.NextState(mode, state, int(v))
+ if !ok {
+ if tok != nil {
+ l.unread(unfixedBufLen)
+ return tok, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ state = nextState
+ if modeKindID, ok := l.spec.Accept(mode, state); ok {
+ kindID, _ := l.spec.KindIDAndName(mode, modeKindID)
+ tok = &Token{
+ ModeID: mode,
+ KindID: kindID,
+ ModeKindID: modeKindID,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ }
+ unfixedBufLen = 0
+ }
+ }
+}
+
+// Mode returns the current lex mode.
+func (l *Lexer) Mode() ModeID {
+ return l.modeStack[len(l.modeStack)-1]
+}
+
+// PushMode adds a lex mode onto the mode stack.
+func (l *Lexer) PushMode(mode ModeID) {
+ l.modeStack = append(l.modeStack, mode)
+}
+
+// PopMode removes a lex mode from the top of the mode stack.
+func (l *Lexer) PopMode() error {
+ sLen := len(l.modeStack)
+ if sLen == 0 {
+ return fmt.Errorf("cannot pop a lex mode from a lex mode stack any more")
+ }
+ l.modeStack = l.modeStack[:sLen-1]
+ return nil
+}
+
+func (l *Lexer) read() (byte, bool) {
+ if l.srcPtr >= len(l.src) {
+ return 0, true
+ }
+
+ b := l.src[l.srcPtr]
+ l.srcPtr++
+
+ l.prevRow = l.row
+ l.prevCol = l.col
+
+ // Count the token positions.
+ // The driver treats LF as the end of lines and counts columns in code points, not bytes.
+ // To count in code points, we refer to the First Byte column in the Table 3-6.
+ //
+ // Reference:
+ // - [Table 3-6] https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf > Table 3-6. UTF-8 Bit Distribution
+ if b < 128 {
+ // 0x0A is LF.
+ if b == 0x0A {
+ l.row++
+ l.col = 0
+ } else {
+ l.col++
+ }
+ } else if b>>5 == 6 || b>>4 == 14 || b>>3 == 30 {
+ l.col++
+ }
+
+ return b, false
+}
+
+// We must not call this function consecutively to record the token position correctly.
+func (l *Lexer) unread(n int) {
+ l.srcPtr -= n
+
+ l.row = l.prevRow
+ l.col = l.prevCol
+}
+
+const (
+ ModeIDNil ModeID = 0
+ ModeIDDefault ModeID = 1
+ ModeIDTerminal ModeID = 2
+ ModeIDStringLiteral ModeID = 3
+)
+
+const (
+ ModeNameNil = ""
+ ModeNameDefault = "default"
+ ModeNameTerminal = "terminal"
+ ModeNameStringLiteral = "string_literal"
+)
+
+// ModeIDToName converts a mode ID to a name.
+func ModeIDToName(id ModeID) string {
+ switch id {
+ case ModeIDNil:
+ return ModeNameNil
+ case ModeIDDefault:
+ return ModeNameDefault
+ case ModeIDTerminal:
+ return ModeNameTerminal
+ case ModeIDStringLiteral:
+ return ModeNameStringLiteral
+ }
+ return ""
+}
+
+const (
+ KindIDNil KindID = 0
+ KindIDWhiteSpace KindID = 1
+ KindIDNewline KindID = 2
+ KindIDLineComment KindID = 3
+ KindIDKwFragment KindID = 4
+ KindIDIdentifier KindID = 5
+ KindIDTerminalOpen KindID = 6
+ KindIDStringLiteralOpen KindID = 7
+ KindIDColon KindID = 8
+ KindIDOr KindID = 9
+ KindIDSemicolon KindID = 10
+ KindIDLabelMarker KindID = 11
+ KindIDExpansion KindID = 12
+ KindIDDirectiveMarker KindID = 13
+ KindIDOrderedSymbolMarker KindID = 14
+ KindIDLParen KindID = 15
+ KindIDRParen KindID = 16
+ KindIDPattern KindID = 17
+ KindIDEscapeSymbol KindID = 18
+ KindIDTerminalClose KindID = 19
+ KindIDCharSeq KindID = 20
+ KindIDStringLiteralClose KindID = 21
+)
+
+const (
+ KindNameNil = ""
+ KindNameWhiteSpace = "white_space"
+ KindNameNewline = "newline"
+ KindNameLineComment = "line_comment"
+ KindNameKwFragment = "kw_fragment"
+ KindNameIdentifier = "identifier"
+ KindNameTerminalOpen = "terminal_open"
+ KindNameStringLiteralOpen = "string_literal_open"
+ KindNameColon = "colon"
+ KindNameOr = "or"
+ KindNameSemicolon = "semicolon"
+ KindNameLabelMarker = "label_marker"
+ KindNameExpansion = "expansion"
+ KindNameDirectiveMarker = "directive_marker"
+ KindNameOrderedSymbolMarker = "ordered_symbol_marker"
+ KindNameLParen = "l_paren"
+ KindNameRParen = "r_paren"
+ KindNamePattern = "pattern"
+ KindNameEscapeSymbol = "escape_symbol"
+ KindNameTerminalClose = "terminal_close"
+ KindNameCharSeq = "char_seq"
+ KindNameStringLiteralClose = "string_literal_close"
+)
+
+// KindIDToName converts a kind ID to a name.
+func KindIDToName(id KindID) string {
+ switch id {
+ case KindIDNil:
+ return KindNameNil
+ case KindIDWhiteSpace:
+ return KindNameWhiteSpace
+ case KindIDNewline:
+ return KindNameNewline
+ case KindIDLineComment:
+ return KindNameLineComment
+ case KindIDKwFragment:
+ return KindNameKwFragment
+ case KindIDIdentifier:
+ return KindNameIdentifier
+ case KindIDTerminalOpen:
+ return KindNameTerminalOpen
+ case KindIDStringLiteralOpen:
+ return KindNameStringLiteralOpen
+ case KindIDColon:
+ return KindNameColon
+ case KindIDOr:
+ return KindNameOr
+ case KindIDSemicolon:
+ return KindNameSemicolon
+ case KindIDLabelMarker:
+ return KindNameLabelMarker
+ case KindIDExpansion:
+ return KindNameExpansion
+ case KindIDDirectiveMarker:
+ return KindNameDirectiveMarker
+ case KindIDOrderedSymbolMarker:
+ return KindNameOrderedSymbolMarker
+ case KindIDLParen:
+ return KindNameLParen
+ case KindIDRParen:
+ return KindNameRParen
+ case KindIDPattern:
+ return KindNamePattern
+ case KindIDEscapeSymbol:
+ return KindNameEscapeSymbol
+ case KindIDTerminalClose:
+ return KindNameTerminalClose
+ case KindIDCharSeq:
+ return KindNameCharSeq
+ case KindIDStringLiteralClose:
+ return KindNameStringLiteralClose
+ }
+ return ""
+}
+
+type lexSpec struct {
+ pop [][]bool
+ push [][]ModeID
+ modeNames []string
+ initialStates []StateID
+ acceptances [][]ModeKindID
+ kindIDs [][]KindID
+ kindNames []string
+ initialModeID ModeID
+ modeIDNil ModeID
+ modeKindIDNil ModeKindID
+ stateIDNil StateID
+
+ rowNums [][]int
+ rowDisplacements [][]int
+ bounds [][]int
+ entries [][]StateID
+ originalColCounts []int
+}
+
+func NewLexSpec() *lexSpec {
+ return &lexSpec{
+ pop: [][]bool{
+ nil,
+ {
+ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+ },
+ {
+ false, false, false, true,
+ },
+ {
+ false, false, true,
+ },
+ },
+ push: [][]ModeID{
+ nil,
+ {
+ 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ {
+ 0, 0, 0, 0,
+ },
+ {
+ 0, 0, 0,
+ },
+ },
+ modeNames: []string{
+ ModeNameNil,
+ ModeNameDefault,
+ ModeNameTerminal,
+ ModeNameStringLiteral,
+ },
+ initialStates: []StateID{
+ 0,
+ 1,
+ 1,
+ 1,
+ },
+ acceptances: [][]ModeKindID{
+ nil,
+ {
+ 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 4, 5, 0, 0, 2, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+ },
+ },
+ kindIDs: [][]KindID{
+ nil,
+ {
+ KindIDNil,
+ KindIDWhiteSpace,
+ KindIDNewline,
+ KindIDLineComment,
+ KindIDKwFragment,
+ KindIDIdentifier,
+ KindIDTerminalOpen,
+ KindIDStringLiteralOpen,
+ KindIDColon,
+ KindIDOr,
+ KindIDSemicolon,
+ KindIDLabelMarker,
+ KindIDExpansion,
+ KindIDDirectiveMarker,
+ KindIDOrderedSymbolMarker,
+ KindIDLParen,
+ KindIDRParen,
+ },
+ {
+ KindIDNil,
+ KindIDPattern,
+ KindIDEscapeSymbol,
+ KindIDTerminalClose,
+ },
+ {
+ KindIDNil,
+ KindIDCharSeq,
+ KindIDStringLiteralClose,
+ },
+ },
+ kindNames: []string{
+ KindNameNil,
+ KindNameWhiteSpace,
+ KindNameNewline,
+ KindNameLineComment,
+ KindNameKwFragment,
+ KindNameIdentifier,
+ KindNameTerminalOpen,
+ KindNameStringLiteralOpen,
+ KindNameColon,
+ KindNameOr,
+ KindNameSemicolon,
+ KindNameLabelMarker,
+ KindNameExpansion,
+ KindNameDirectiveMarker,
+ KindNameOrderedSymbolMarker,
+ KindNameLParen,
+ KindNameRParen,
+ KindNamePattern,
+ KindNameEscapeSymbol,
+ KindNameTerminalClose,
+ KindNameCharSeq,
+ KindNameStringLiteralClose,
+ },
+ initialModeID: ModeIDDefault,
+ modeIDNil: ModeIDNil,
+ modeKindIDNil: 0,
+ stateIDNil: 0,
+
+ rowNums: [][]int{
+ nil,
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 6, 8, 6, 9, 6, 10, 6, 11, 12, 6, 13, 14,
+ 6, 15, 16, 6, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ },
+ {
+ 0, 1, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 8, 2, 9, 10, 2, 11, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 2, 17, 2, 18, 19, 2, 20, 21, 2, 22, 23, 2, 24,
+ 2, 25, 2, 26, 2, 27, 2, 28, 2, 29, 30, 2, 31, 32, 2, 33, 34, 2, 35, 2,
+ 36, 2, 37, 2, 38, 2, 39, 2, 40, 41, 2, 42, 43, 2, 44, 45, 2, 0,
+ },
+ {
+ 0, 1, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 8, 2, 9, 10, 2, 11, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 2, 17, 2, 18, 19, 2, 20, 21, 2, 22, 23, 2, 0,
+ },
+ },
+ rowDisplacements: [][]int{
+ nil,
+ {
+ 0, 236, 1554, 1555, 1556, 0, 237, 1323, 301, 1387, 365, 1291, 429, 493, 557, 1419, 621, 765, 840, 915,
+ 990, 1065, 1140, 1215, 1290, 1558, 1559,
+ },
+ {
+ 0, 0, 736, 2548, 852, 2612, 916, 2372, 980, 1044, 1108, 2839, 1172, 245, 2613, 1236, 2677, 1300, 2420, 1364,
+ 1428, 1492, 2855, 1556, 735, 2678, 1620, 2742, 1684, 2468, 1748, 1812, 1876, 2871, 1940, 490, 2743, 2004, 2807, 2068,
+ 2516, 2132, 2196, 2260, 2887, 2324,
+ },
+ {
+ 0, 0, 246, 1194, 362, 1258, 426, 1114, 490, 554, 618, 1355, 682, 245, 1259, 746, 1323, 810, 1162, 874,
+ 938, 1002, 1371, 1066,
+ },
+ },
+ bounds: [][]int{
+ nil,
+ {
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, 5, 5, -1, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1,
+ -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1,
+ 1, -1, -1, -1, -1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, -1, -1, -1, -1, -1, -1, -1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -1, -1, -1, -1,
+ 17, -1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -1, -1,
+ -1, -1, -1, -1, -1, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -1, -1, -1, -1, 18, -1, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, -1, -1, -1, -1, -1, -1, -1,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, -1, -1, -1, -1, 19, -1, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, -1, -1, -1, -1, -1, -1, -1, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, -1, -1, -1, -1, 20, -1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, -1, -1, -1, -1, -1, -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -1, -1, -1, -1,
+ 21, -1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -1, -1,
+ -1, -1, -1, -1, -1, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -1, -1, -1, -1, 22, -1, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -1, -1, -1, -1, -1, -1, -1,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, -1, -1, -1, -1, 23, -1, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, -1, -1, -1, -1, -1, -1, -1, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, -1, -1, -1, -1, 24, -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 4, 25, 26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ },
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, -1, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1,
+ },
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, -1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ },
+ },
+ entries: [][]StateID{
+ nil,
+ {
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 13, 13,
+ 15, 18, 18, 18, 21, 2, 35, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 36, 43, 44, 0, 0, 37, 45, 46, 0, 0,
+ 0, 0, 33, 4, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 38, 40, 0, 0, 0, 0,
+ 41, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 32, 0, 32, 32, 32, 32, 32, 24, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0,
+ 39, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0,
+ 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 25,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0,
+ 0, 0, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 32, 0, 26, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 27, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 0, 0, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 28,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0,
+ 32, 0, 32, 32, 32, 32, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0,
+ 0, 0, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 32, 0, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 30, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 0, 0, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 2, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 34, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ {
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 77, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 20, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 9, 9,
+ 11, 14, 14, 14, 17, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 26, 28, 28, 30, 33, 33, 33, 36, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 64, 66, 66, 68, 71, 71, 71, 74, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 58, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 47, 47, 49, 52, 52, 52, 55,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+ 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 0, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ {
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 39,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 9, 9,
+ 11, 14, 14, 14, 17, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 26, 28, 28, 30, 33, 33, 33, 36, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ originalColCounts: nil,
+ }
+}
+
+func (s *lexSpec) InitialMode() ModeID {
+ return s.initialModeID
+}
+
+func (s *lexSpec) Pop(mode ModeID, modeKind ModeKindID) bool {
+ return s.pop[mode][modeKind]
+}
+
+func (s *lexSpec) Push(mode ModeID, modeKind ModeKindID) (ModeID, bool) {
+ id := s.push[mode][modeKind]
+ return id, id != s.modeIDNil
+}
+
+func (s *lexSpec) ModeName(mode ModeID) string {
+ return s.modeNames[mode]
+}
+
+func (s *lexSpec) InitialState(mode ModeID) StateID {
+ return s.initialStates[mode]
+}
+
+func (s *lexSpec) NextState(mode ModeID, state StateID, v int) (StateID, bool) {
+ rowNum := s.rowNums[mode][state]
+ d := s.rowDisplacements[mode][rowNum]
+ if s.bounds[mode][d+v] != rowNum {
+ return s.stateIDNil, false
+ }
+ return s.entries[mode][d+v], true
+}
+
+func (s *lexSpec) Accept(mode ModeID, state StateID) (ModeKindID, bool) {
+ id := s.acceptances[mode][state]
+ return id, id != s.modeKindIDNil
+}
+
+func (s *lexSpec) KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string) {
+ id := s.kindIDs[mode][modeKind]
+ return id, s.kindNames[id]
+}
diff --git a/src/urubu/spec/grammar/util.go b/src/urubu/spec/grammar/util.go
new file mode 100644
index 0000000..bf3f233
--- /dev/null
+++ b/src/urubu/spec/grammar/util.go
@@ -0,0 +1,21 @@
+package grammar
+
+import "strings"
+
+var rep = strings.NewReplacer(
+ `.`, `\.`,
+ `*`, `\*`,
+ `+`, `\+`,
+ `?`, `\?`,
+ `|`, `\|`,
+ `(`, `\(`,
+ `)`, `\)`,
+ `[`, `\[`,
+ `\`, `\\`,
+)
+
+// EscapePattern escapes the special characters.
+// For example, EscapePattern(`+`) returns `\+`.
+func EscapePattern(s string) string {
+ return rep.Replace(s)
+}
diff --git a/src/urubu/spec/test/parser.go b/src/urubu/spec/test/parser.go
new file mode 100644
index 0000000..b7265d7
--- /dev/null
+++ b/src/urubu/spec/test/parser.go
@@ -0,0 +1,336 @@
+//go:generate vartan compile tree.vartan -o tree.json
+//go:generate vartan-go tree.json --package test
+
+package test
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "regexp"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+type TreeDiff struct {
+ ExpectedPath string
+ ActualPath string
+ Message string
+}
+
+func newTreeDiff(expected, actual *Tree, message string) *TreeDiff {
+ return &TreeDiff{
+ ExpectedPath: expected.path(),
+ ActualPath: actual.path(),
+ Message: message,
+ }
+}
+
+type Tree struct {
+ Parent *Tree
+ Offset int
+ Kind string
+ Children []*Tree
+ Lexeme string
+}
+
+func NewNonTerminalTree(kind string, children ...*Tree) *Tree {
+ return &Tree{
+ Kind: kind,
+ Children: children,
+ }
+}
+
+func NewTerminalNode(kind string, lexeme string) *Tree {
+ return &Tree{
+ Kind: kind,
+ Lexeme: lexeme,
+ }
+}
+
+func (t *Tree) Fill() *Tree {
+ for i, c := range t.Children {
+ c.Parent = t
+ c.Offset = i
+ c.Fill()
+ }
+ return t
+}
+
+func (t *Tree) path() string {
+ if t.Parent == nil {
+ return t.Kind
+ }
+ return fmt.Sprintf("%v.[%v]%v", t.Parent.path(), t.Offset, t.Kind)
+}
+
+func (t *Tree) Format() []byte {
+ var b bytes.Buffer
+ t.format(&b, 0)
+ return b.Bytes()
+}
+
+func (t *Tree) format(buf *bytes.Buffer, depth int) {
+ for i := 0; i < depth; i++ {
+ buf.WriteString(" ")
+ }
+ buf.WriteString("(")
+ buf.WriteString(t.Kind)
+ if len(t.Children) > 0 {
+ buf.WriteString("\n")
+ for i, c := range t.Children {
+ c.format(buf, depth+1)
+ if i < len(t.Children)-1 {
+ buf.WriteString("\n")
+ }
+ }
+ }
+ buf.WriteString(")")
+}
+
+func DiffTree(expected, actual *Tree) []*TreeDiff {
+ if expected == nil && actual == nil {
+ return nil
+ }
+ if actual.Kind != expected.Kind {
+ msg := fmt.Sprintf("unexpected kind: expected '%v' but got '%v'", expected.Kind, actual.Kind)
+ return []*TreeDiff{
+ newTreeDiff(expected, actual, msg),
+ }
+ }
+ if expected.Lexeme != actual.Lexeme {
+ msg := fmt.Sprintf("unexpected lexeme: expected '%v' but got '%v'", expected.Lexeme, actual.Lexeme)
+ return []*TreeDiff{
+ newTreeDiff(expected, actual, msg),
+ }
+ }
+ if len(actual.Children) != len(expected.Children) {
+ msg := fmt.Sprintf("unexpected node count: expected %v but got %v", len(expected.Children), len(actual.Children))
+ return []*TreeDiff{
+ newTreeDiff(expected, actual, msg),
+ }
+ }
+ var diffs []*TreeDiff
+ for i, exp := range expected.Children {
+ if ds := DiffTree(exp, actual.Children[i]); len(ds) > 0 {
+ diffs = append(diffs, ds...)
+ }
+ }
+ return diffs
+}
+
+type TestCase struct {
+ Description string
+ Source []byte
+ Output *Tree
+}
+
+func ParseTestCase(r io.Reader) (*TestCase, error) {
+ parts, err := splitIntoParts(r)
+ if err != nil {
+ return nil, err
+ }
+ if len(parts) != 3 {
+ return nil, fmt.Errorf("too many or too few part delimiters: a test case consists of just tree parts: %v parts found", len(parts))
+ }
+
+ tp := &treeParser{
+ lineOffset: parts[0].lineCount + parts[1].lineCount + 2,
+ }
+ tree, err := tp.parseTree(bytes.NewReader(parts[2].buf))
+ if err != nil {
+ return nil, err
+ }
+
+ return &TestCase{
+ Description: string(parts[0].buf),
+ Source: parts[1].buf,
+ Output: tree,
+ }, nil
+}
+
+type testCasePart struct {
+ buf []byte
+ lineCount int
+}
+
+func splitIntoParts(r io.Reader) ([]*testCasePart, error) {
+ var bufs []*testCasePart
+ s := bufio.NewScanner(r)
+ for {
+ buf, lineCount, err := readPart(s)
+ if err != nil {
+ return nil, err
+ }
+ if buf == nil {
+ break
+ }
+ bufs = append(bufs, &testCasePart{
+ buf: buf,
+ lineCount: lineCount,
+ })
+ }
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+ return bufs, nil
+}
+
+var reDelim = regexp.MustCompile(`^\s*---+\s*$`)
+
+func readPart(s *bufio.Scanner) ([]byte, int, error) {
+ if !s.Scan() {
+ return nil, 0, s.Err()
+ }
+ buf := &bytes.Buffer{}
+ line := s.Bytes()
+ if reDelim.Match(line) {
+ // Return an empty slice because (*bytes.Buffer).Bytes() returns nil if we have never written data.
+ return []byte{}, 0, nil
+ }
+ _, err := buf.Write(line)
+ if err != nil {
+ return nil, 0, err
+ }
+ lineCount := 1
+ for s.Scan() {
+ line := s.Bytes()
+ if reDelim.Match(line) {
+ return buf.Bytes(), lineCount, nil
+ }
+ _, err := buf.Write([]byte("\n"))
+ if err != nil {
+ return nil, 0, err
+ }
+ _, err = buf.Write(line)
+ if err != nil {
+ return nil, 0, err
+ }
+ lineCount++
+ }
+ if err := s.Err(); err != nil {
+ return nil, 0, err
+ }
+ return buf.Bytes(), lineCount, nil
+}
+
+type treeParser struct {
+ lineOffset int
+}
+
+func (tp *treeParser) parseTree(src io.Reader) (*Tree, error) {
+ toks, err := NewTokenStream(src)
+ if err != nil {
+ return nil, err
+ }
+ gram := NewGrammar()
+ tb := NewDefaultSyntaxTreeBuilder()
+ p, err := NewParser(toks, gram, SemanticAction(NewASTActionSet(gram, tb)))
+ if err != nil {
+ return nil, err
+ }
+ err = p.Parse()
+ if err != nil {
+ return nil, err
+ }
+ synErrs := p.SyntaxErrors()
+ if len(synErrs) > 0 {
+ var b strings.Builder
+ b.Write(formatSyntaxError(synErrs[0], gram, tp.lineOffset))
+ for _, synErr := range synErrs[1:] {
+ b.WriteRune('\n')
+ b.Write(formatSyntaxError(synErr, gram, tp.lineOffset))
+ }
+ return nil, errors.New(b.String())
+ }
+ t, err := tp.genTree(tb.Tree())
+ if err != nil {
+ return nil, err
+ }
+ return t.Fill(), nil
+}
+
+func formatSyntaxError(synErr *SyntaxError, gram Grammar, lineOffset int) []byte {
+ var b bytes.Buffer
+
+ b.WriteString(fmt.Sprintf("%v:%v: %v: ", lineOffset+synErr.Row+1, synErr.Col+1, synErr.Message))
+
+ tok := synErr.Token
+ switch {
+ case tok.EOF():
+ b.WriteString("<eof>")
+ case tok.Invalid():
+ b.WriteString(fmt.Sprintf("'%v' (<invalid>)", string(tok.Lexeme())))
+ default:
+ if term := gram.Terminal(tok.TerminalID()); term != "" {
+ b.WriteString(fmt.Sprintf("'%v' (%v)", string(tok.Lexeme()), term))
+ } else {
+ b.WriteString(fmt.Sprintf("'%v'", string(tok.Lexeme())))
+ }
+ }
+ b.WriteString(fmt.Sprintf(": expected: %v", synErr.ExpectedTerminals[0]))
+ for _, t := range synErr.ExpectedTerminals[1:] {
+ b.WriteString(fmt.Sprintf(", %v", t))
+ }
+
+ return b.Bytes()
+}
+
+func (tp *treeParser) genTree(node *Node) (*Tree, error) {
+ // A node labeled 'error' cannot have children. It always must be (error).
+ if sym := node.Children[0]; sym.Text == "error" {
+ if len(node.Children) > 1 {
+ return nil, fmt.Errorf("%v:%v: error node cannot take children", tp.lineOffset+sym.Row+1, sym.Col+1)
+ }
+ return NewTerminalNode(sym.Text, ""), nil
+ }
+
+ if len(node.Children) == 2 && node.Children[1].KindName == "string" {
+ var text string
+ str := node.Children[1].Children[0]
+ switch str.KindName {
+ case "raw_string":
+ text = str.Children[0].Text
+ case "interpreted_string":
+ var b strings.Builder
+ for _, c := range str.Children {
+ switch c.KindName {
+ case "escaped_seq":
+ b.WriteString(strings.TrimPrefix(`\`, c.Text))
+ case "escape_char":
+ return nil, fmt.Errorf("%v:%v: incomplete escape sequence", tp.lineOffset+c.Row+1, c.Col+1)
+ case "codepoint_expr":
+ cp := c.Children[0]
+ n, err := strconv.ParseInt(cp.Text, 16, 64)
+ if err != nil {
+ return nil, fmt.Errorf("%v:%v: %v", tp.lineOffset+cp.Row+1, cp.Col+1, err)
+ }
+ if !utf8.ValidRune(rune(n)) {
+ return nil, fmt.Errorf("%v:%v: invalid code point: %v", tp.lineOffset+cp.Row+1, cp.Col+1, cp.Text)
+ }
+ b.WriteRune(rune(n))
+ default:
+ b.WriteString(c.Text)
+ }
+ }
+ text = b.String()
+ }
+ return NewTerminalNode(node.Children[0].Text, text), nil
+ }
+
+ var children []*Tree
+ if len(node.Children) > 1 {
+ children = make([]*Tree, len(node.Children)-1)
+ for i, c := range node.Children[1:] {
+ var err error
+ children[i], err = tp.genTree(c)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ return NewNonTerminalTree(node.Children[0].Text, children...), nil
+}
diff --git a/src/urubu/spec/test/tree-report.json b/src/urubu/spec/test/tree-report.json
new file mode 100644
index 0000000..c2018e5
--- /dev/null
+++ b/src/urubu/spec/test/tree-report.json
@@ -0,0 +1 @@
+{"terminals":[null,{"number":1,"name":"\u003ceof\u003e","pattern":"","prec":0,"assoc":""},{"number":2,"name":"error","pattern":"","prec":0,"assoc":""},{"number":3,"name":"ws","pattern":"","prec":0,"assoc":""},{"number":4,"name":"l_paren","pattern":"","prec":1,"assoc":""},{"number":5,"name":"r_paren","pattern":"","prec":0,"assoc":""},{"number":6,"name":"identifier","pattern":"","prec":0,"assoc":""},{"number":7,"name":"raw_string_open","pattern":"","prec":0,"assoc":""},{"number":8,"name":"raw_string_body","pattern":"","prec":0,"assoc":""},{"number":9,"name":"raw_string_close","pattern":"","prec":0,"assoc":""},{"number":10,"name":"interpreted_string_open","pattern":"","prec":0,"assoc":""},{"number":11,"name":"interpreted_seq","pattern":"","prec":0,"assoc":""},{"number":12,"name":"codepoint_prefix","pattern":"","prec":0,"assoc":""},{"number":13,"name":"l_brace","pattern":"","prec":0,"assoc":""},{"number":14,"name":"r_brace","pattern":"","prec":0,"assoc":""},{"number":15,"name":"hex_digits","pattern":"","prec":0,"assoc":""},{"number":16,"name":"escaped_seq","pattern":"","prec":0,"assoc":""},{"number":17,"name":"escape_char","pattern":"","prec":0,"assoc":""},{"number":18,"name":"interpreted_string_close","pattern":"","prec":0,"assoc":""}],"non_terminals":[null,{"number":1,"name":"tree'"},{"number":2,"name":"tree"},{"number":3,"name":"tree_list"},{"number":4,"name":"string"},{"number":5,"name":"raw_string"},{"number":6,"name":"opt_raw_string_body"},{"number":7,"name":"interpreted_string"},{"number":8,"name":"opt_interpreted_string_body"},{"number":9,"name":"interpreted_string_body"},{"number":10,"name":"interpreted_string_elem"},{"number":11,"name":"codepoint_expr"}],"productions":[null,{"number":1,"lhs":1,"rhs":[-2],"prec":0,"assoc":""},{"number":2,"lhs":2,"rhs":[4,6,-3,5],"prec":0,"assoc":""},{"number":3,"lhs":2,"rhs":[4,6,-4,5],"prec":0,"assoc":""},{"number":4,"lhs":2,"rhs":[4,2,5],"prec":0,"assoc":""},{"number":5,"lhs":3,"rhs":[-3,-2],"prec":0,"assoc":""},{"number":6,"lhs":3,"rhs":[-2],"prec":0,"assoc":""},{"number":7,"lhs":3,"rhs":[],"prec":2,"assoc":""},{"number":8,"lhs":4,"rhs":[-5],"prec":0,"assoc":""},{"number":9,"lhs":4,"rhs":[-7],"prec":0,"assoc":""},{"number":10,"lhs":5,"rhs":[7,-6,9],"prec":0,"assoc":""},{"number":11,"lhs":6,"rhs":[8],"prec":0,"assoc":""},{"number":12,"lhs":6,"rhs":[],"prec":0,"assoc":""},{"number":13,"lhs":7,"rhs":[10,-8,18],"prec":0,"assoc":""},{"number":14,"lhs":7,"rhs":[10,2,18],"prec":0,"assoc":""},{"number":15,"lhs":8,"rhs":[-9],"prec":0,"assoc":""},{"number":16,"lhs":8,"rhs":[],"prec":0,"assoc":""},{"number":17,"lhs":9,"rhs":[-9,-10],"prec":0,"assoc":""},{"number":18,"lhs":9,"rhs":[-10],"prec":0,"assoc":""},{"number":19,"lhs":10,"rhs":[11],"prec":0,"assoc":""},{"number":20,"lhs":10,"rhs":[13],"prec":0,"assoc":""},{"number":21,"lhs":10,"rhs":[14],"prec":0,"assoc":""},{"number":22,"lhs":10,"rhs":[15],"prec":0,"assoc":""},{"number":23,"lhs":10,"rhs":[16],"prec":0,"assoc":""},{"number":24,"lhs":10,"rhs":[17],"prec":0,"assoc":""},{"number":25,"lhs":10,"rhs":[-11],"prec":0,"assoc":""},{"number":26,"lhs":11,"rhs":[12,13,15,14],"prec":0,"assoc":""}],"states":[{"number":0,"kernel":[{"production":1,"dot":0}],"shift":[{"symbol":4,"state":2}],"reduce":null,"goto":[{"symbol":2,"state":1}],"sr_conflict":[],"rr_conflict":[]},{"number":1,"kernel":[{"production":1,"dot":1}],"shift":null,"reduce":[{"look_ahead":[1],"production":1}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":2,"kernel":[{"production":2,"dot":1},{"production":3,"dot":1},{"production":4,"dot":1}],"shift":[{"symbol":2,"state":3},{"symbol":6,"state":4}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":3,"kernel":[{"production":4,"dot":2}],"shift":[{"symbol":5,"state":5}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":4,"kernel":[{"production":2,"dot":2},{"production":3,"dot":2}],"shift":[{"symbol":4,"state":2},{"symbol":7,"state":11},{"symbol":10,"state":12}],"reduce":[{"look_ahead":[5,1],"production":7}],"goto":[{"symbol":2,"state":6},{"symbol":3,"state":7},{"symbol":4,"state":8},{"symbol":5,"state":9},{"symbol":7,"state":10}],"sr_conflict":[{"symbol":4,"state":2,"production":7,"adopted_state":2,"adopted_production":null,"resolved_by":1}],"rr_conflict":[]},{"number":5,"kernel":[{"production":4,"dot":3}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":4}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":6,"kernel":[{"production":6,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5],"production":6}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":7,"kernel":[{"production":2,"dot":3},{"production":5,"dot":1}],"shift":[{"symbol":4,"state":2},{"symbol":5,"state":14}],"reduce":null,"goto":[{"symbol":2,"state":13}],"sr_conflict":[],"rr_conflict":[]},{"number":8,"kernel":[{"production":3,"dot":3}],"shift":[{"symbol":5,"state":15}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":9,"kernel":[{"production":8,"dot":1}],"shift":null,"reduce":[{"look_ahead":[5],"production":8}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":10,"kernel":[{"production":9,"dot":1}],"shift":null,"reduce":[{"look_ahead":[5],"production":9}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":11,"kernel":[{"production":10,"dot":1}],"shift":[{"symbol":8,"state":17}],"reduce":[{"look_ahead":[4,5,9,1],"production":12}],"goto":[{"symbol":6,"state":16}],"sr_conflict":[],"rr_conflict":[]},{"number":12,"kernel":[{"production":13,"dot":1},{"production":14,"dot":1}],"shift":[{"symbol":2,"state":22},{"symbol":11,"state":23},{"symbol":12,"state":24},{"symbol":13,"state":25},{"symbol":14,"state":26},{"symbol":15,"state":27},{"symbol":16,"state":28},{"symbol":17,"state":29}],"reduce":[{"look_ahead":[4,5,18,1],"production":16}],"goto":[{"symbol":8,"state":18},{"symbol":9,"state":19},{"symbol":10,"state":20},{"symbol":11,"state":21}],"sr_conflict":[],"rr_conflict":[]},{"number":13,"kernel":[{"production":5,"dot":2}],"shift":null,"reduce":[{"look_ahead":[4,5],"production":5}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":14,"kernel":[{"production":2,"dot":4}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":2}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":15,"kernel":[{"production":3,"dot":4}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":3}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":16,"kernel":[{"production":10,"dot":2}],"shift":[{"symbol":9,"state":30}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":17,"kernel":[{"production":11,"dot":1}],"shift":null,"reduce":[{"look_ahead":[9],"production":11}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":18,"kernel":[{"production":13,"dot":2}],"shift":[{"symbol":18,"state":31}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":19,"kernel":[{"production":15,"dot":1},{"production":17,"dot":1}],"shift":[{"symbol":11,"state":23},{"symbol":12,"state":24},{"symbol":13,"state":25},{"symbol":14,"state":26},{"symbol":15,"state":27},{"symbol":16,"state":28},{"symbol":17,"state":29}],"reduce":[{"look_ahead":[18],"production":15}],"goto":[{"symbol":11,"state":21},{"symbol":10,"state":32}],"sr_conflict":[],"rr_conflict":[]},{"number":20,"kernel":[{"production":18,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":18}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":21,"kernel":[{"production":25,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":25}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":22,"kernel":[{"production":14,"dot":2}],"shift":[{"symbol":18,"state":33}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":23,"kernel":[{"production":19,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":19}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":24,"kernel":[{"production":26,"dot":1}],"shift":[{"symbol":13,"state":34}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":25,"kernel":[{"production":20,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":20}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":26,"kernel":[{"production":21,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":21}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":27,"kernel":[{"production":22,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":22}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":28,"kernel":[{"production":23,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":23}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":29,"kernel":[{"production":24,"dot":1}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":24}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":30,"kernel":[{"production":10,"dot":3}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":10}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":31,"kernel":[{"production":13,"dot":3}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":13}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":32,"kernel":[{"production":17,"dot":2}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":17}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":33,"kernel":[{"production":14,"dot":3}],"shift":null,"reduce":[{"look_ahead":[4,5,1],"production":14}],"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":34,"kernel":[{"production":26,"dot":2}],"shift":[{"symbol":15,"state":35}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":35,"kernel":[{"production":26,"dot":3}],"shift":[{"symbol":14,"state":36}],"reduce":null,"goto":null,"sr_conflict":[],"rr_conflict":[]},{"number":36,"kernel":[{"production":26,"dot":4}],"shift":null,"reduce":[{"look_ahead":[4,5,11,12,13,14,15,16,17,18,1],"production":26}],"goto":null,"sr_conflict":[],"rr_conflict":[]}]}
diff --git a/src/urubu/spec/test/tree.json b/src/urubu/spec/test/tree.json
new file mode 100644
index 0000000..f05c2f2
--- /dev/null
+++ b/src/urubu/spec/test/tree.json
@@ -0,0 +1 @@
+{"name":"tree","lexical":{"initial_mode_id":1,"mode_names":["","default","raw_string","interpreted_string"],"kind_names":["","ws","l_paren","r_paren","identifier","raw_string_open","interpreted_string_open","raw_string_body","raw_string_close","interpreted_seq","codepoint_prefix","l_brace","r_brace","hex_digits","escaped_seq","escape_char","interpreted_string_close"],"kind_ids":[null,[0,1,2,3,4,5,6],[0,7,8],[0,9,10,11,12,13,14,15,16]],"compression_level":2,"specs":[null,{"kind_names":["","ws","l_paren","r_paren","identifier","raw_string_open","interpreted_string_open"],"push":[0,0,0,0,0,2,3],"pop":[0,0,0,0,0,0,0],"dfa":{"initial_state_id":1,"accepting_states":[0,0,1,4,2,3,5,6],"row_count":8,"col_count":256,"transition":{"unique_entries":{"original_row_count":4,"original_col_count":256,"empty_value":0,"entries":[0,0,0,0,0,0,0,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,7,0,0,0,0,6,4,5,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,-1,-1,-1,-1,-1,-1,-1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,-1,-1,-1,-1,3,-1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,0,189,75]},"row_nums":[0,1,2,3,0,0,0,0],"original_row_count":8,"original_col_count":256,"empty_value":0}}},{"kind_names":["","raw_string_body","raw_string_close"],"push":[0,0,0],"pop":[0,0,1],"dfa":{"initial_state_id":1,"accepting_states":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],"row_count":40,"col_count":256,"transition":{"unique_entries":{"original_row_count":24,"original_col_count":256,"empty_value":0,"entries":[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,39,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,5,5,5,5,5,5,5,5,5,5,5,7,9,9,11,14,14,14,17,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,24,24,24,24,24,24,24,24,24,24,24,24,26,28,28,30,33,33,33,36,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,-1,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,0,246,1194,362,1258,426,1114,490,554,618,1355,682,245,1259,746,1323,810,1162,874,938,1002,1371,1066]},"row_nums":[0,1,2,3,2,4,2,5,2,6,2,7,8,2,9,10,2,11,12,2,13,2,14,2,15,2,16,2,17,2,18,19,2,20,21,2,22,23,2,0],"original_row_count":40,"original_col_count":256,"empty_value":0}}},{"kind_names":["","interpreted_seq","codepoint_prefix","l_brace","r_brace","hex_digits","escaped_seq","escape_char","interpreted_string_close"],"push":[0,0,0,0,0,0,0,0,0],"pop":[0,0,0,0,0,0,0,0,1],"dfa":{"initial_state_id":1,"accepting_states":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,5,2,3,4,6,8],"row_count":46,"col_count":256,"transition":{"unique_entries":{"original_row_count":26,"original_col_count":256,"empty_value":0,"entries":[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,45,20,20,20,20,20,20,20,20,20,20,20,20,20,40,40,40,40,40,40,40,40,40,40,20,20,20,20,20,20,20,40,40,40,40,40,40,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,39,20,20,20,20,40,40,40,40,40,40,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,42,20,43,20,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,5,5,5,5,5,5,5,5,5,5,5,7,9,9,11,14,14,14,17,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,0,0,20,20,20,20,20,20,20,0,0,0,0,0,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,20,20,20,0,0,0,0,0,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,20,0,20,20,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,24,24,24,24,24,24,24,24,24,24,24,24,26,28,28,30,33,33,33,36,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,0,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,40,40,40,40,40,40,40,40,40,40,0,0,0,0,0,0,0,40,40,40,40,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,40,40,40,40,40,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"bounds":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,13,13,13,13,13,13,13,-1,-1,-1,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,13,13,13,13,-1,-1,-1,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,-1,13,-1,13,13,-1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,-1,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,25,25,25,25,25,25,25,25,25,25,-1,-1,-1,-1,-1,-1,-1,25,25,25,25,25,25,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,25,25,25,25,25,25,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"row_displacement":[0,0,246,1194,362,1258,426,1114,490,554,618,1436,682,245,1259,746,1323,810,1162,874,938,1002,1452,1066,1504,1435]},"row_nums":[0,1,2,3,2,4,2,5,2,6,2,7,8,2,9,10,2,11,12,2,13,2,14,2,15,2,16,2,17,2,18,19,2,20,21,2,22,23,2,24,25,0,0,0,0,0],"original_row_count":46,"original_col_count":256,"empty_value":0}}}]},"syntactic":{"action":[0,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,-2,7,0,-11,0,0,-12,0,0,0,0,0,0,0,0,0,4,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,12,12,0,0,-17,12,0,0,0,0,0,0,0,0,0,0,16,-22,0,16,16,0,0,0,0,0,-23,-24,-25,-26,-27,-28,-29,16,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,-23,-24,-25,-26,-27,-28,-29,15,0,18,0,0,18,18,0,0,0,0,0,18,18,18,18,18,18,18,18,0,25,0,0,25,25,0,0,0,0,0,25,25,25,25,25,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-33,0,19,0,0,19,19,0,0,0,0,0,19,19,19,19,19,19,19,19,0,0,0,0,0,0,0,0,0,0,0,0,0,-34,0,0,0,0,0,0,20,0,0,20,20,0,0,0,0,0,20,20,20,20,20,20,20,20,0,21,0,0,21,21,0,0,0,0,0,21,21,21,21,21,21,21,21,0,22,0,0,22,22,0,0,0,0,0,22,22,22,22,22,22,22,22,0,23,0,0,23,23,0,0,0,0,0,23,23,23,23,23,23,23,23,0,24,0,0,24,24,0,0,0,0,0,24,24,24,24,24,24,24,24,0,10,0,0,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,13,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,17,17,0,0,0,0,0,17,17,17,17,17,17,17,17,0,14,0,0,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-36,0,0,0,0,0,26,0,0,26,26,0,0,0,0,0,26,26,26,26,26,26,26,26],"goto":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,7,8,9,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"state_count":37,"initial_state":0,"start_production":1,"lhs_symbols":[0,1,2,2,2,3,3,3,4,4,5,6,6,7,7,8,8,9,9,10,10,10,10,10,10,10,11],"alternative_symbol_counts":[0,1,4,4,3,2,1,0,1,1,3,1,0,3,3,1,0,2,1,1,1,1,1,1,1,1,4],"terminals":["","\u003ceof\u003e","error","ws","l_paren","r_paren","identifier","raw_string_open","raw_string_body","raw_string_close","interpreted_string_open","interpreted_seq","codepoint_prefix","l_brace","r_brace","hex_digits","escaped_seq","escape_char","interpreted_string_close"],"terminal_count":19,"terminal_skip":[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"kind_to_terminal":[0,3,4,5,6,7,10,8,9,11,12,13,14,15,16,17,18],"non_terminals":["","tree'","tree","tree_list","string","raw_string","opt_raw_string_body","interpreted_string","opt_interpreted_string_body","interpreted_string_body","interpreted_string_elem","codepoint_expr"],"non_terminal_count":12,"eof_symbol":1,"error_symbol":2,"error_trapper_states":[0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"recover_productions":[0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]},"ast_action":{"entries":[null,null,[2,-3],[2,3],[2],[-1,2],null,null,null,null,[-2],null,null,[-2],[2],[-1],null,[-1,-2],[-1],null,null,null,null,null,null,null,[3]]}}
diff --git a/src/urubu/spec/test/tree.vartan b/src/urubu/spec/test/tree.vartan
new file mode 100644
index 0000000..aa8f733
--- /dev/null
+++ b/src/urubu/spec/test/tree.vartan
@@ -0,0 +1,87 @@
+#name tree;
+
+#prec (
+ #assign l_paren
+ #assign $empty_tree
+);
+
+tree
+ : l_paren identifier tree_list r_paren #ast identifier tree_list...
+ | l_paren identifier string r_paren #ast identifier string
+ | l_paren error r_paren #recover #ast error
+ ;
+tree_list
+ : tree_list tree #ast tree_list... tree
+ | tree
+ | #prec $empty_tree
+ ;
+string
+ : raw_string
+ | interpreted_string
+ ;
+raw_string
+ : raw_string_open opt_raw_string_body raw_string_close #ast opt_raw_string_body...
+ ;
+opt_raw_string_body
+ : raw_string_body
+ |
+ ;
+interpreted_string
+ : interpreted_string_open opt_interpreted_string_body interpreted_string_close #ast opt_interpreted_string_body...
+ | interpreted_string_open error interpreted_string_close #recover #ast error
+ ;
+opt_interpreted_string_body
+ : interpreted_string_body #ast interpreted_string_body...
+ |
+ ;
+interpreted_string_body
+ : interpreted_string_body interpreted_string_elem #ast interpreted_string_body... interpreted_string_elem...
+ | interpreted_string_elem #ast interpreted_string_elem...
+ ;
+interpreted_string_elem
+ : interpreted_seq
+ | l_brace
+ | r_brace
+ | hex_digits
+ | escaped_seq
+ | escape_char
+ | codepoint_expr
+ ;
+codepoint_expr
+ : codepoint_prefix l_brace hex_digits r_brace #ast hex_digits
+ ;
+
+ws #skip
+ : "[\u{0009}\u{000A}\u{000D}\u{0020}]+";
+l_paren
+ : '(';
+r_paren
+ : ')';
+identifier
+ : "[0-9A-Za-z_]+";
+
+raw_string_open #push raw_string
+ : "'";
+raw_string_body #mode raw_string
+ : "[^']+";
+raw_string_close #mode raw_string #pop
+ : "'";
+
+interpreted_string_open #push interpreted_string
+ : '"';
+interpreted_seq #mode interpreted_string
+ : "[^\"\\{}0-9A-Fa-f]+";
+codepoint_prefix #mode interpreted_string
+ : '\u';
+l_brace #mode interpreted_string
+ : '{';
+r_brace #mode interpreted_string
+ : '}';
+hex_digits #mode interpreted_string
+ : "[0-9A-Fa-f]+";
+escaped_seq #mode interpreted_string
+ : "\\[\"\\]";
+escape_char #mode interpreted_string
+ : '\';
+interpreted_string_close #mode interpreted_string #pop
+ : '"';
diff --git a/src/urubu/spec/test/tree_lexer.go b/src/urubu/spec/test/tree_lexer.go
new file mode 100644
index 0000000..8bb1c87
--- /dev/null
+++ b/src/urubu/spec/test/tree_lexer.go
@@ -0,0 +1,1024 @@
+// Code generated by vartan-go. DO NOT EDIT.
+package test
+
+import (
+ "fmt"
+ "io"
+)
+
+type ModeID int
+
+func (id ModeID) Int() int {
+ return int(id)
+}
+
+type StateID int
+
+func (id StateID) Int() int {
+ return int(id)
+}
+
+type KindID int
+
+func (id KindID) Int() int {
+ return int(id)
+}
+
+type ModeKindID int
+
+func (id ModeKindID) Int() int {
+ return int(id)
+}
+
+type LexSpec interface {
+ InitialMode() ModeID
+ Pop(mode ModeID, modeKind ModeKindID) bool
+ Push(mode ModeID, modeKind ModeKindID) (ModeID, bool)
+ ModeName(mode ModeID) string
+ InitialState(mode ModeID) StateID
+ NextState(mode ModeID, state StateID, v int) (StateID, bool)
+ Accept(mode ModeID, state StateID) (ModeKindID, bool)
+ KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string)
+}
+
+// Token representes a token.
+type Token struct {
+ // ModeID is an ID of a lex mode.
+ ModeID ModeID
+
+ // KindID is an ID of a kind. This is unique among all modes.
+ KindID KindID
+
+ // ModeKindID is an ID of a lexical kind. This is unique only within a mode.
+ // Note that you need to use KindID field if you want to identify a kind across all modes.
+ ModeKindID ModeKindID
+
+ // Row is a row number where a lexeme appears.
+ Row int
+
+ // Col is a column number where a lexeme appears.
+ // Note that Col is counted in code points, not bytes.
+ Col int
+
+ // Lexeme is a byte sequence matched a pattern of a lexical specification.
+ Lexeme []byte
+
+ // When this field is true, it means the token is the EOF token.
+ EOF bool
+
+ // When this field is true, it means the token is an error token.
+ Invalid bool
+}
+
+type LexerOption func(l *Lexer) error
+
+// DisableModeTransition disables the active mode transition. Thus, even if the lexical specification has the push and pop
+// operations, the lexer doesn't perform these operations. When the lexical specification has multiple modes, and this option is
+// enabled, you need to call the Lexer.Push and Lexer.Pop methods to perform the mode transition. You can use the Lexer.Mode method
+// to know the current lex mode.
+func DisableModeTransition() LexerOption {
+ return func(l *Lexer) error {
+ l.passiveModeTran = true
+ return nil
+ }
+}
+
+type Lexer struct {
+ spec LexSpec
+ src []byte
+ srcPtr int
+ row int
+ col int
+ prevRow int
+ prevCol int
+ tokBuf []*Token
+ modeStack []ModeID
+ passiveModeTran bool
+}
+
+// NewLexer returns a new lexer.
+func NewLexer(spec LexSpec, src io.Reader, opts ...LexerOption) (*Lexer, error) {
+ b, err := io.ReadAll(src)
+ if err != nil {
+ return nil, err
+ }
+ l := &Lexer{
+ spec: spec,
+ src: b,
+ srcPtr: 0,
+ row: 0,
+ col: 0,
+ modeStack: []ModeID{
+ spec.InitialMode(),
+ },
+ passiveModeTran: false,
+ }
+ for _, opt := range opts {
+ err := opt(l)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return l, nil
+}
+
+// Next returns a next token.
+func (l *Lexer) Next() (*Token, error) {
+ if len(l.tokBuf) > 0 {
+ tok := l.tokBuf[0]
+ l.tokBuf = l.tokBuf[1:]
+ return tok, nil
+ }
+
+ tok, err := l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ return tok, nil
+ }
+ errTok := tok
+ for {
+ tok, err = l.nextAndTransition()
+ if err != nil {
+ return nil, err
+ }
+ if !tok.Invalid {
+ break
+ }
+ errTok.Lexeme = append(errTok.Lexeme, tok.Lexeme...)
+ }
+ l.tokBuf = append(l.tokBuf, tok)
+
+ return errTok, nil
+}
+
+func (l *Lexer) nextAndTransition() (*Token, error) {
+ tok, err := l.next()
+ if err != nil {
+ return nil, err
+ }
+ if tok.EOF || tok.Invalid {
+ return tok, nil
+ }
+ if l.passiveModeTran {
+ return tok, nil
+ }
+ mode := l.Mode()
+ if l.spec.Pop(mode, tok.ModeKindID) {
+ err := l.PopMode()
+ if err != nil {
+ return nil, err
+ }
+ }
+ if mode, ok := l.spec.Push(mode, tok.ModeKindID); ok {
+ l.PushMode(mode)
+ }
+ // The checking length of the mode stack must be at after pop and push operations because those operations can be performed
+ // at the same time. When the mode stack has just one element and popped it, the mode stack will be temporarily emptied.
+ // However, since a push operation may be performed immediately after it, the lexer allows the stack to be temporarily empty.
+ if len(l.modeStack) == 0 {
+ return nil, fmt.Errorf("a mode stack must have at least one element")
+ }
+ return tok, nil
+}
+
+func (l *Lexer) next() (*Token, error) {
+ mode := l.Mode()
+ state := l.spec.InitialState(mode)
+ buf := []byte{}
+ unfixedBufLen := 0
+ row := l.row
+ col := l.col
+ var tok *Token
+ for {
+ v, eof := l.read()
+ if eof {
+ if tok != nil {
+ l.unread(unfixedBufLen)
+ return tok, nil
+ }
+ // When `buf` has unaccepted data and reads the EOF, the lexer treats the buffered data as an invalid token.
+ if len(buf) > 0 {
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Row: 0,
+ Col: 0,
+ EOF: true,
+ }, nil
+ }
+ buf = append(buf, v)
+ unfixedBufLen++
+ nextState, ok := l.spec.NextState(mode, state, int(v))
+ if !ok {
+ if tok != nil {
+ l.unread(unfixedBufLen)
+ return tok, nil
+ }
+ return &Token{
+ ModeID: mode,
+ ModeKindID: 0,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ Invalid: true,
+ }, nil
+ }
+ state = nextState
+ if modeKindID, ok := l.spec.Accept(mode, state); ok {
+ kindID, _ := l.spec.KindIDAndName(mode, modeKindID)
+ tok = &Token{
+ ModeID: mode,
+ KindID: kindID,
+ ModeKindID: modeKindID,
+ Lexeme: buf,
+ Row: row,
+ Col: col,
+ }
+ unfixedBufLen = 0
+ }
+ }
+}
+
+// Mode returns the current lex mode.
+func (l *Lexer) Mode() ModeID {
+ return l.modeStack[len(l.modeStack)-1]
+}
+
+// PushMode adds a lex mode onto the mode stack.
+func (l *Lexer) PushMode(mode ModeID) {
+ l.modeStack = append(l.modeStack, mode)
+}
+
+// PopMode removes a lex mode from the top of the mode stack.
+func (l *Lexer) PopMode() error {
+ sLen := len(l.modeStack)
+ if sLen == 0 {
+ return fmt.Errorf("cannot pop a lex mode from a lex mode stack any more")
+ }
+ l.modeStack = l.modeStack[:sLen-1]
+ return nil
+}
+
+func (l *Lexer) read() (byte, bool) {
+ if l.srcPtr >= len(l.src) {
+ return 0, true
+ }
+
+ b := l.src[l.srcPtr]
+ l.srcPtr++
+
+ l.prevRow = l.row
+ l.prevCol = l.col
+
+ // Count the token positions.
+ // The driver treats LF as the end of lines and counts columns in code points, not bytes.
+ // To count in code points, we refer to the First Byte column in the Table 3-6.
+ //
+ // Reference:
+ // - [Table 3-6] https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf > Table 3-6. UTF-8 Bit Distribution
+ if b < 128 {
+ // 0x0A is LF.
+ if b == 0x0A {
+ l.row++
+ l.col = 0
+ } else {
+ l.col++
+ }
+ } else if b>>5 == 6 || b>>4 == 14 || b>>3 == 30 {
+ l.col++
+ }
+
+ return b, false
+}
+
+// We must not call this function consecutively to record the token position correctly.
+func (l *Lexer) unread(n int) {
+ l.srcPtr -= n
+
+ l.row = l.prevRow
+ l.col = l.prevCol
+}
+
+const (
+ ModeIDNil ModeID = 0
+ ModeIDDefault ModeID = 1
+ ModeIDRawString ModeID = 2
+ ModeIDInterpretedString ModeID = 3
+)
+
+const (
+ ModeNameNil = ""
+ ModeNameDefault = "default"
+ ModeNameRawString = "raw_string"
+ ModeNameInterpretedString = "interpreted_string"
+)
+
+// ModeIDToName converts a mode ID to a name.
+func ModeIDToName(id ModeID) string {
+ switch id {
+ case ModeIDNil:
+ return ModeNameNil
+ case ModeIDDefault:
+ return ModeNameDefault
+ case ModeIDRawString:
+ return ModeNameRawString
+ case ModeIDInterpretedString:
+ return ModeNameInterpretedString
+ }
+ return ""
+}
+
+const (
+ KindIDNil KindID = 0
+ KindIDWs KindID = 1
+ KindIDLParen KindID = 2
+ KindIDRParen KindID = 3
+ KindIDIdentifier KindID = 4
+ KindIDRawStringOpen KindID = 5
+ KindIDInterpretedStringOpen KindID = 6
+ KindIDRawStringBody KindID = 7
+ KindIDRawStringClose KindID = 8
+ KindIDInterpretedSeq KindID = 9
+ KindIDCodepointPrefix KindID = 10
+ KindIDLBrace KindID = 11
+ KindIDRBrace KindID = 12
+ KindIDHexDigits KindID = 13
+ KindIDEscapedSeq KindID = 14
+ KindIDEscapeChar KindID = 15
+ KindIDInterpretedStringClose KindID = 16
+)
+
+const (
+ KindNameNil = ""
+ KindNameWs = "ws"
+ KindNameLParen = "l_paren"
+ KindNameRParen = "r_paren"
+ KindNameIdentifier = "identifier"
+ KindNameRawStringOpen = "raw_string_open"
+ KindNameInterpretedStringOpen = "interpreted_string_open"
+ KindNameRawStringBody = "raw_string_body"
+ KindNameRawStringClose = "raw_string_close"
+ KindNameInterpretedSeq = "interpreted_seq"
+ KindNameCodepointPrefix = "codepoint_prefix"
+ KindNameLBrace = "l_brace"
+ KindNameRBrace = "r_brace"
+ KindNameHexDigits = "hex_digits"
+ KindNameEscapedSeq = "escaped_seq"
+ KindNameEscapeChar = "escape_char"
+ KindNameInterpretedStringClose = "interpreted_string_close"
+)
+
+// KindIDToName converts a kind ID to a name.
+func KindIDToName(id KindID) string {
+ switch id {
+ case KindIDNil:
+ return KindNameNil
+ case KindIDWs:
+ return KindNameWs
+ case KindIDLParen:
+ return KindNameLParen
+ case KindIDRParen:
+ return KindNameRParen
+ case KindIDIdentifier:
+ return KindNameIdentifier
+ case KindIDRawStringOpen:
+ return KindNameRawStringOpen
+ case KindIDInterpretedStringOpen:
+ return KindNameInterpretedStringOpen
+ case KindIDRawStringBody:
+ return KindNameRawStringBody
+ case KindIDRawStringClose:
+ return KindNameRawStringClose
+ case KindIDInterpretedSeq:
+ return KindNameInterpretedSeq
+ case KindIDCodepointPrefix:
+ return KindNameCodepointPrefix
+ case KindIDLBrace:
+ return KindNameLBrace
+ case KindIDRBrace:
+ return KindNameRBrace
+ case KindIDHexDigits:
+ return KindNameHexDigits
+ case KindIDEscapedSeq:
+ return KindNameEscapedSeq
+ case KindIDEscapeChar:
+ return KindNameEscapeChar
+ case KindIDInterpretedStringClose:
+ return KindNameInterpretedStringClose
+ }
+ return ""
+}
+
+type lexSpec struct {
+ pop [][]bool
+ push [][]ModeID
+ modeNames []string
+ initialStates []StateID
+ acceptances [][]ModeKindID
+ kindIDs [][]KindID
+ kindNames []string
+ initialModeID ModeID
+ modeIDNil ModeID
+ modeKindIDNil ModeKindID
+ stateIDNil StateID
+
+ rowNums [][]int
+ rowDisplacements [][]int
+ bounds [][]int
+ entries [][]StateID
+ originalColCounts []int
+}
+
+func NewLexSpec() *lexSpec {
+ return &lexSpec{
+ pop: [][]bool{
+ nil,
+ {
+ false, false, false, false, false, false, false,
+ },
+ {
+ false, false, true,
+ },
+ {
+ false, false, false, false, false, false, false, false, true,
+ },
+ },
+ push: [][]ModeID{
+ nil,
+ {
+ 0, 0, 0, 0, 0, 2, 3,
+ },
+ {
+ 0, 0, 0,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ modeNames: []string{
+ ModeNameNil,
+ ModeNameDefault,
+ ModeNameRawString,
+ ModeNameInterpretedString,
+ },
+ initialStates: []StateID{
+ 0,
+ 1,
+ 1,
+ 1,
+ },
+ acceptances: [][]ModeKindID{
+ nil,
+ {
+ 0, 0, 1, 4, 2, 3, 5, 6,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 5, 2, 3, 4, 6, 8,
+ },
+ },
+ kindIDs: [][]KindID{
+ nil,
+ {
+ KindIDNil,
+ KindIDWs,
+ KindIDLParen,
+ KindIDRParen,
+ KindIDIdentifier,
+ KindIDRawStringOpen,
+ KindIDInterpretedStringOpen,
+ },
+ {
+ KindIDNil,
+ KindIDRawStringBody,
+ KindIDRawStringClose,
+ },
+ {
+ KindIDNil,
+ KindIDInterpretedSeq,
+ KindIDCodepointPrefix,
+ KindIDLBrace,
+ KindIDRBrace,
+ KindIDHexDigits,
+ KindIDEscapedSeq,
+ KindIDEscapeChar,
+ KindIDInterpretedStringClose,
+ },
+ },
+ kindNames: []string{
+ KindNameNil,
+ KindNameWs,
+ KindNameLParen,
+ KindNameRParen,
+ KindNameIdentifier,
+ KindNameRawStringOpen,
+ KindNameInterpretedStringOpen,
+ KindNameRawStringBody,
+ KindNameRawStringClose,
+ KindNameInterpretedSeq,
+ KindNameCodepointPrefix,
+ KindNameLBrace,
+ KindNameRBrace,
+ KindNameHexDigits,
+ KindNameEscapedSeq,
+ KindNameEscapeChar,
+ KindNameInterpretedStringClose,
+ },
+ initialModeID: ModeIDDefault,
+ modeIDNil: ModeIDNil,
+ modeKindIDNil: 0,
+ stateIDNil: 0,
+
+ rowNums: [][]int{
+ nil,
+ {
+ 0, 1, 2, 3, 0, 0, 0, 0,
+ },
+ {
+ 0, 1, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 8, 2, 9, 10, 2, 11, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 2, 17, 2, 18, 19, 2, 20, 21, 2, 22, 23, 2, 0,
+ },
+ {
+ 0, 1, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 8, 2, 9, 10, 2, 11, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 2, 17, 2, 18, 19, 2, 20, 21, 2, 22, 23, 2, 24,
+ 25, 0, 0, 0, 0, 0,
+ },
+ },
+ rowDisplacements: [][]int{
+ nil,
+ {
+ 0, 0, 189, 75,
+ },
+ {
+ 0, 0, 246, 1194, 362, 1258, 426, 1114, 490, 554, 618, 1355, 682, 245, 1259, 746, 1323, 810, 1162, 874,
+ 938, 1002, 1371, 1066,
+ },
+ {
+ 0, 0, 246, 1194, 362, 1258, 426, 1114, 490, 554, 618, 1436, 682, 245, 1259, 746, 1323, 810, 1162, 874,
+ 938, 1002, 1452, 1066, 1504, 1435,
+ },
+ },
+ bounds: [][]int{
+ nil,
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1,
+ 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,
+ -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, 3, -1, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2,
+ -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1,
+ },
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, -1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ },
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 13, 13, 13, 13, 13, 13, 13, -1, -1, -1, -1, -1, -1, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -1, 13, 13,
+ 13, 13, -1, -1, -1, -1, -1, -1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, -1, 13, -1, 13, 13, -1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -1, -1, -1, -1, -1, -1, -1,
+ 25, 25, 25, 25, 25, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 25, 25, 25, 25, 25, 24, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 24, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ },
+ },
+ entries: [][]StateID{
+ nil,
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0, 0, 6,
+ 4, 5, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2,
+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ },
+ {
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 39,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 9, 9,
+ 11, 14, 14, 14, 17, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 26, 28, 28, 30, 33, 33, 33, 36, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ },
+ {
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 45, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 20,
+ 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 39, 20, 20, 20, 20, 40, 40, 40,
+ 40, 40, 40, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 42, 20, 43, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 9, 9,
+ 11, 14, 14, 14, 17, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20,
+ 20, 20, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 0, 20, 0, 20, 20, 0, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 26, 28, 28, 30, 33, 33, 33, 36, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0,
+ 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 44, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 44, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ originalColCounts: nil,
+ }
+}
+
+func (s *lexSpec) InitialMode() ModeID {
+ return s.initialModeID
+}
+
+func (s *lexSpec) Pop(mode ModeID, modeKind ModeKindID) bool {
+ return s.pop[mode][modeKind]
+}
+
+func (s *lexSpec) Push(mode ModeID, modeKind ModeKindID) (ModeID, bool) {
+ id := s.push[mode][modeKind]
+ return id, id != s.modeIDNil
+}
+
+func (s *lexSpec) ModeName(mode ModeID) string {
+ return s.modeNames[mode]
+}
+
+func (s *lexSpec) InitialState(mode ModeID) StateID {
+ return s.initialStates[mode]
+}
+
+func (s *lexSpec) NextState(mode ModeID, state StateID, v int) (StateID, bool) {
+ rowNum := s.rowNums[mode][state]
+ d := s.rowDisplacements[mode][rowNum]
+ if s.bounds[mode][d+v] != rowNum {
+ return s.stateIDNil, false
+ }
+ return s.entries[mode][d+v], true
+}
+
+func (s *lexSpec) Accept(mode ModeID, state StateID) (ModeKindID, bool) {
+ id := s.acceptances[mode][state]
+ return id, id != s.modeKindIDNil
+}
+
+func (s *lexSpec) KindIDAndName(mode ModeID, modeKind ModeKindID) (KindID, string) {
+ id := s.kindIDs[mode][modeKind]
+ return id, s.kindNames[id]
+}
diff --git a/src/urubu/spec/test/tree_parser.go b/src/urubu/spec/test/tree_parser.go
new file mode 100644
index 0000000..528d259
--- /dev/null
+++ b/src/urubu/spec/test/tree_parser.go
@@ -0,0 +1,716 @@
+// Code generated by vartan-go. DO NOT EDIT.
+package test
+
+import (
+ "fmt"
+ "io"
+)
+
+type Grammar interface {
+ // InitialState returns the initial state of a parser.
+ InitialState() int
+
+ // StartProduction returns the start production of grammar.
+ StartProduction() int
+
+ // Action returns an ACTION entry corresponding to a (state, terminal symbol) pair.
+ Action(state int, terminal int) int
+
+ // GoTo returns a GOTO entry corresponding to a (state, non-terminal symbol) pair.
+ GoTo(state int, lhs int) int
+
+ // ErrorTrapperState returns true when a state can shift the error symbol.
+ ErrorTrapperState(state int) bool
+
+ // LHS returns a LHS symbol of a production.
+ LHS(prod int) int
+
+ // AlternativeSymbolCount returns a symbol count of p production.
+ AlternativeSymbolCount(prod int) int
+
+ // RecoverProduction returns true when a production has the recover directive.
+ RecoverProduction(prod int) bool
+
+ // NonTerminal retuns a string representaion of a non-terminal symbol.
+ NonTerminal(nonTerminal int) string
+
+ // TerminalCount returns a terminal symbol count of grammar.
+ TerminalCount() int
+
+ // SkipTerminal returns true when a terminal symbol must be skipped on syntax analysis.
+ SkipTerminal(terminal int) bool
+
+ // EOF returns the EOF symbol.
+ EOF() int
+
+ // Error returns the error symbol.
+ Error() int
+
+ // Terminal retuns a string representaion of a terminal symbol.
+ Terminal(terminal int) string
+
+ // ASTAction returns an AST action entries.
+ ASTAction(prod int) []int
+}
+
+type VToken interface {
+ // TerminalID returns a terminal ID.
+ TerminalID() int
+
+ // Lexeme returns a lexeme.
+ Lexeme() []byte
+
+ // EOF returns true when a token represents EOF.
+ EOF() bool
+
+ // Invalid returns true when a token is invalid.
+ Invalid() bool
+
+ // Position returns (row, column) pair.
+ Position() (int, int)
+}
+
+type TokenStream interface {
+ Next() (VToken, error)
+}
+
+type SyntaxError struct {
+ Row int
+ Col int
+ Message string
+ Token VToken
+ ExpectedTerminals []string
+}
+
+type ParserOption func(p *Parser) error
+
+// DisableLAC disables LAC (lookahead correction). LAC is enabled by default.
+func DisableLAC() ParserOption {
+ return func(p *Parser) error {
+ p.disableLAC = true
+ return nil
+ }
+}
+
+func SemanticAction(semAct SemanticActionSet) ParserOption {
+ return func(p *Parser) error {
+ p.semAct = semAct
+ return nil
+ }
+}
+
+type Parser struct {
+ toks TokenStream
+ gram Grammar
+ stateStack *stateStack
+ semAct SemanticActionSet
+ disableLAC bool
+ onError bool
+ shiftCount int
+ synErrs []*SyntaxError
+}
+
+func NewParser(toks TokenStream, gram Grammar, opts ...ParserOption) (*Parser, error) {
+ p := &Parser{
+ toks: toks,
+ gram: gram,
+ stateStack: &stateStack{},
+ }
+
+ for _, opt := range opts {
+ err := opt(p)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return p, nil
+}
+
+func (p *Parser) Parse() error {
+ p.stateStack.push(p.gram.InitialState())
+ tok, err := p.nextToken()
+ if err != nil {
+ return err
+ }
+
+ACTION_LOOP:
+ for {
+ act := p.lookupAction(tok)
+
+ switch {
+ case act < 0: // Shift
+ nextState := act * -1
+
+ recovered := false
+ if p.onError {
+ p.shiftCount++
+
+ // When the parser performs shift three times, the parser recovers from the error state.
+ if p.shiftCount >= 3 {
+ p.onError = false
+ p.shiftCount = 0
+ recovered = true
+ }
+ }
+
+ p.shift(nextState)
+
+ if p.semAct != nil {
+ p.semAct.Shift(tok, recovered)
+ }
+
+ tok, err = p.nextToken()
+ if err != nil {
+ return err
+ }
+ case act > 0: // Reduce
+ prodNum := act
+
+ recovered := false
+ if p.onError && p.gram.RecoverProduction(prodNum) {
+ p.onError = false
+ p.shiftCount = 0
+ recovered = true
+ }
+
+ accepted := p.reduce(prodNum)
+ if accepted {
+ if p.semAct != nil {
+ p.semAct.Accept()
+ }
+
+ return nil
+ }
+
+ if p.semAct != nil {
+ p.semAct.Reduce(prodNum, recovered)
+ }
+ default: // Error
+ if p.onError {
+ tok, err = p.nextToken()
+ if err != nil {
+ return err
+ }
+ if tok.EOF() {
+ if p.semAct != nil {
+ p.semAct.MissError(tok)
+ }
+
+ return nil
+ }
+
+ continue ACTION_LOOP
+ }
+
+ row, col := tok.Position()
+ p.synErrs = append(p.synErrs, &SyntaxError{
+ Row: row,
+ Col: col,
+ Message: "unexpected token",
+ Token: tok,
+ ExpectedTerminals: p.searchLookahead(p.stateStack.top()),
+ })
+
+ count, ok := p.trapError()
+ if !ok {
+ if p.semAct != nil {
+ p.semAct.MissError(tok)
+ }
+
+ return nil
+ }
+
+ p.onError = true
+ p.shiftCount = 0
+
+ act, err := p.lookupActionOnError()
+ if err != nil {
+ return err
+ }
+
+ p.shift(act * -1)
+
+ if p.semAct != nil {
+ p.semAct.TrapAndShiftError(tok, count)
+ }
+ }
+ }
+}
+
+// validateLookahead validates whether `term` is a valid lookahead in the current context. When `term` is valid,
+// this method returns `true`.
+func (p *Parser) validateLookahead(term int) bool {
+ p.stateStack.enableExploratoryMode()
+ defer p.stateStack.disableExploratoryMode()
+
+ for {
+ act := p.gram.Action(p.stateStack.topExploratorily(), term)
+
+ switch {
+ case act < 0: // Shift
+ return true
+ case act > 0: // Reduce
+ prodNum := act
+
+ lhs := p.gram.LHS(prodNum)
+ if lhs == p.gram.LHS(p.gram.StartProduction()) {
+ return true
+ }
+ n := p.gram.AlternativeSymbolCount(prodNum)
+ p.stateStack.popExploratorily(n)
+ state := p.gram.GoTo(p.stateStack.topExploratorily(), lhs)
+ p.stateStack.pushExploratorily(state)
+ default: // Error
+ return false
+ }
+ }
+}
+
+func (p *Parser) nextToken() (VToken, error) {
+ for {
+ // We don't have to check whether the token is invalid because the kind ID of the invalid token is 0,
+ // and the parsing table doesn't have an entry corresponding to the kind ID 0. Thus we can detect
+ // a syntax error because the parser cannot find an entry corresponding to the invalid token.
+ tok, err := p.toks.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.gram.SkipTerminal(tok.TerminalID()) {
+ continue
+ }
+
+ return tok, nil
+ }
+}
+
+func (p *Parser) tokenToTerminal(tok VToken) int {
+ if tok.EOF() {
+ return p.gram.EOF()
+ }
+
+ return tok.TerminalID()
+}
+
+func (p *Parser) lookupAction(tok VToken) int {
+ if !p.disableLAC {
+ term := p.tokenToTerminal(tok)
+ if !p.validateLookahead(term) {
+ return 0
+ }
+ }
+
+ return p.gram.Action(p.stateStack.top(), p.tokenToTerminal(tok))
+}
+
+func (p *Parser) lookupActionOnError() (int, error) {
+ act := p.gram.Action(p.stateStack.top(), p.gram.Error())
+ if act >= 0 {
+ return 0, fmt.Errorf("an entry must be a shift action by the error symbol; entry: %v, state: %v, symbol: %v", act, p.stateStack.top(), p.gram.Terminal(p.gram.Error()))
+ }
+
+ return act, nil
+}
+
+func (p *Parser) shift(nextState int) {
+ p.stateStack.push(nextState)
+}
+
+func (p *Parser) reduce(prodNum int) bool {
+ lhs := p.gram.LHS(prodNum)
+ if lhs == p.gram.LHS(p.gram.StartProduction()) {
+ return true
+ }
+ n := p.gram.AlternativeSymbolCount(prodNum)
+ p.stateStack.pop(n)
+ nextState := p.gram.GoTo(p.stateStack.top(), lhs)
+ p.stateStack.push(nextState)
+ return false
+}
+
+func (p *Parser) trapError() (int, bool) {
+ count := 0
+ for {
+ if p.gram.ErrorTrapperState(p.stateStack.top()) {
+ return count, true
+ }
+
+ if p.stateStack.top() != p.gram.InitialState() {
+ p.stateStack.pop(1)
+ count++
+ } else {
+ return 0, false
+ }
+ }
+}
+
+func (p *Parser) SyntaxErrors() []*SyntaxError {
+ return p.synErrs
+}
+
+func (p *Parser) searchLookahead(state int) []string {
+ kinds := []string{}
+ termCount := p.gram.TerminalCount()
+ for term := 0; term < termCount; term++ {
+ if p.disableLAC {
+ if p.gram.Action(p.stateStack.top(), term) == 0 {
+ continue
+ }
+ } else {
+ if !p.validateLookahead(term) {
+ continue
+ }
+ }
+
+ // We don't add the error symbol to the look-ahead symbols because users cannot input the error symbol
+ // intentionally.
+ if term == p.gram.Error() {
+ continue
+ }
+
+ kinds = append(kinds, p.gram.Terminal(term))
+ }
+
+ return kinds
+}
+
+type stateStack struct {
+ items []int
+ itemsExp []int
+}
+
+func (s *stateStack) enableExploratoryMode() {
+ s.itemsExp = make([]int, len(s.items))
+ copy(s.itemsExp, s.items)
+}
+
+func (s *stateStack) disableExploratoryMode() {
+ s.itemsExp = nil
+}
+
+func (s *stateStack) top() int {
+ return s.items[len(s.items)-1]
+}
+
+func (s *stateStack) topExploratorily() int {
+ return s.itemsExp[len(s.itemsExp)-1]
+}
+
+func (s *stateStack) push(state int) {
+ s.items = append(s.items, state)
+}
+
+func (s *stateStack) pushExploratorily(state int) {
+ s.itemsExp = append(s.itemsExp, state)
+}
+
+func (s *stateStack) pop(n int) {
+ s.items = s.items[:len(s.items)-n]
+}
+
+func (s *stateStack) popExploratorily(n int) {
+ s.itemsExp = s.itemsExp[:len(s.itemsExp)-n]
+}
+
+type grammarImpl struct {
+ recoverProductions []int
+ action []int
+ goTo []int
+ alternativeSymbolCounts []int
+ errorTrapperStates []int
+ nonTerminals []string
+ lhsSymbols []int
+ terminals []string
+ terminalSkip []int
+ astActions [][]int
+}
+
+func NewGrammar() *grammarImpl {
+ return &grammarImpl{
+ recoverProductions: []int{
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ },
+ action: []int{
+ 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -3, 0, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+ -2, 7, 0, -11, 0, 0, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 12, 12, 0, 0, -17, 12, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -22, 0, 16, 16, 0, 0, 0, 0, 0, -23,
+ -24, -25, -26, -27, -28, -29, 16, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, -24, -25, -26, -27, -28, -29, 15,
+ 0, 18, 0, 0, 18, 18, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0,
+ 25, 0, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -33, 0, 19, 0,
+ 0, 19, 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 20, 0, 0, 20,
+ 20, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 0, 21, 0, 0, 21, 21,
+ 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 0, 22, 0, 0, 22, 22, 0,
+ 0, 0, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, 0, 23, 0, 0, 23, 23, 0, 0,
+ 0, 0, 0, 23, 23, 23, 23, 23, 23, 23, 23, 0, 24, 0, 0, 24, 24, 0, 0, 0,
+ 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 0, 10, 0, 0, 10, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 13, 13, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 17, 17, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0, 14, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -36,
+ 0, 0, 0, 0, 0, 26, 0, 0, 26, 26, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26,
+ 26, 26, 26,
+ },
+ goTo: []int{
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 21, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ },
+ alternativeSymbolCounts: []int{
+ 0, 1, 4, 4, 3, 2, 1, 0, 1, 1, 3, 1, 0, 3, 3, 1, 0, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 4,
+ },
+ errorTrapperStates: []int{
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ nonTerminals: []string{
+ "",
+ "tree'",
+ "tree",
+ "tree_list",
+ "string",
+ "raw_string",
+ "opt_raw_string_body",
+ "interpreted_string",
+ "opt_interpreted_string_body",
+ "interpreted_string_body",
+ "interpreted_string_elem",
+ "codepoint_expr",
+ },
+ lhsSymbols: []int{
+ 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
+ 10, 10, 10, 10, 10, 10, 11,
+ },
+ terminals: []string{
+ "",
+ "<eof>",
+ "error",
+ "ws",
+ "l_paren",
+ "r_paren",
+ "identifier",
+ "raw_string_open",
+ "raw_string_body",
+ "raw_string_close",
+ "interpreted_string_open",
+ "interpreted_seq",
+ "codepoint_prefix",
+ "l_brace",
+ "r_brace",
+ "hex_digits",
+ "escaped_seq",
+ "escape_char",
+ "interpreted_string_close",
+ },
+ terminalSkip: []int{
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ astActions: [][]int{
+ nil,
+ nil,
+ {
+ 2, -3,
+ },
+ {
+ 2, 3,
+ },
+ {
+ 2,
+ },
+ {
+ -1, 2,
+ },
+ nil,
+ nil,
+ nil,
+ nil,
+ {
+ -2,
+ },
+ nil,
+ nil,
+ {
+ -2,
+ },
+ {
+ 2,
+ },
+ {
+ -1,
+ },
+ nil,
+ {
+ -1, -2,
+ },
+ {
+ -1,
+ },
+ nil,
+ nil,
+ nil,
+ nil,
+ nil,
+ nil,
+ nil,
+ {
+ 3,
+ },
+ },
+ }
+}
+
+func (g *grammarImpl) InitialState() int {
+ return 0
+}
+
+func (g *grammarImpl) StartProduction() int {
+ return 1
+}
+
+func (g *grammarImpl) RecoverProduction(prod int) bool {
+ return g.recoverProductions[prod] != 0
+}
+
+func (g *grammarImpl) Action(state int, terminal int) int {
+ return g.action[state*19+terminal]
+}
+
+func (g *grammarImpl) GoTo(state int, lhs int) int {
+ return g.goTo[state*12+lhs]
+}
+
+func (g *grammarImpl) AlternativeSymbolCount(prod int) int {
+ return g.alternativeSymbolCounts[prod]
+}
+
+func (g *grammarImpl) TerminalCount() int {
+ return 19
+}
+
+func (g *grammarImpl) SkipTerminal(terminal int) bool {
+ return g.terminalSkip[terminal] == 1
+}
+
+func (g *grammarImpl) ErrorTrapperState(state int) bool {
+ return g.errorTrapperStates[state] != 0
+}
+
+func (g *grammarImpl) NonTerminal(nonTerminal int) string {
+ return g.nonTerminals[nonTerminal]
+}
+
+func (g *grammarImpl) LHS(prod int) int {
+ return g.lhsSymbols[prod]
+}
+
+func (g *grammarImpl) EOF() int {
+ return 1
+}
+
+func (g *grammarImpl) Error() int {
+ return 2
+}
+
+func (g *grammarImpl) Terminal(terminal int) string {
+ return g.terminals[terminal]
+}
+
+func (g *grammarImpl) ASTAction(prod int) []int {
+ return g.astActions[prod]
+}
+
+type vToken struct {
+ terminalID int
+ tok *Token
+}
+
+func (t *vToken) TerminalID() int {
+ return t.terminalID
+}
+
+func (t *vToken) Lexeme() []byte {
+ return t.tok.Lexeme
+}
+
+func (t *vToken) EOF() bool {
+ return t.tok.EOF
+}
+
+func (t *vToken) Invalid() bool {
+ return t.tok.Invalid
+}
+
+func (t *vToken) Position() (int, int) {
+ return t.tok.Row, t.tok.Col
+}
+
+var kindToTerminal = []int{
+ 0, 3, 4, 5, 6, 7, 10, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18,
+}
+
+type tokenStream struct {
+ lex *Lexer
+ kindToTerminal []int
+}
+
+func NewTokenStream(src io.Reader) (*tokenStream, error) {
+ lex, err := NewLexer(NewLexSpec(), src)
+ if err != nil {
+ return nil, err
+ }
+
+ return &tokenStream{
+ lex: lex,
+ }, nil
+}
+
+func (t *tokenStream) Next() (VToken, error) {
+ tok, err := t.lex.Next()
+ if err != nil {
+ return nil, err
+ }
+ return &vToken{
+ terminalID: kindToTerminal[tok.KindID],
+ tok: tok,
+ }, nil
+}
diff --git a/src/urubu/spec/test/tree_semantic_action.go b/src/urubu/spec/test/tree_semantic_action.go
new file mode 100644
index 0000000..c1d5a25
--- /dev/null
+++ b/src/urubu/spec/test/tree_semantic_action.go
@@ -0,0 +1,367 @@
+// Code generated by vartan-go. DO NOT EDIT.
+package test
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+// SemanticActionSet is a set of semantic actions a parser calls.
+type SemanticActionSet interface {
+ // Shift runs when the parser shifts a symbol onto a state stack. `tok` is a token corresponding to the symbol.
+ // When the parser recovered from an error state by shifting the token, `recovered` is true.
+ Shift(tok VToken, recovered bool)
+
+ // Reduce runs when the parser reduces an RHS of a production to its LHS. `prodNum` is a number of the production.
+ // When the parser recovered from an error state by reducing the production, `recovered` is true.
+ Reduce(prodNum int, recovered bool)
+
+ // Accept runs when the parser accepts an input.
+ Accept()
+
+ // TrapAndShiftError runs when the parser traps a syntax error and shifts a error symbol onto the state stack.
+ // `cause` is a token that caused a syntax error. `popped` is the number of frames that the parser discards
+ // from the state stack.
+ // Unlike `Shift` function, this function doesn't take a token to be shifted as an argument because a token
+ // corresponding to the error symbol doesn't exist.
+ TrapAndShiftError(cause VToken, popped int)
+
+ // MissError runs when the parser fails to trap a syntax error. `cause` is a token that caused a syntax error.
+ MissError(cause VToken)
+}
+
+var _ SemanticActionSet = &SyntaxTreeActionSet{}
+
+// SyntaxTreeNode is a node of a syntax tree. A node type used in SyntaxTreeActionSet must implement SyntaxTreeNode interface.
+type SyntaxTreeNode interface {
+ // ChildCount returns a child count of a node. A parser calls this method to know the child count to be expanded by an `#ast`
+ // directive with `...` operator.
+ ChildCount() int
+
+ // ExpandChildren returns children of a node. A parser calls this method to fetch the children to be expanded by an `#ast`
+ // directive with `...` operator.
+ ExpandChildren() []SyntaxTreeNode
+}
+
+var _ SyntaxTreeNode = &Node{}
+
+// SyntaxTreeBuilder allows you to construct a syntax tree containing arbitrary user-defined node types.
+// The parser uses SyntaxTreeBuilder interface as a part of semantic actions via SyntaxTreeActionSet interface.
+type SyntaxTreeBuilder interface {
+ Shift(kindName string, text string, row, col int) SyntaxTreeNode
+ ShiftError(kindName string) SyntaxTreeNode
+ Reduce(kindName string, children []SyntaxTreeNode) SyntaxTreeNode
+ Accept(f SyntaxTreeNode)
+}
+
+var _ SyntaxTreeBuilder = &DefaulSyntaxTreeBuilder{}
+
+// DefaulSyntaxTreeBuilder is a implementation of SyntaxTreeBuilder.
+type DefaulSyntaxTreeBuilder struct {
+ tree *Node
+}
+
+// NewDefaultSyntaxTreeBuilder returns a new DefaultSyntaxTreeBuilder.
+func NewDefaultSyntaxTreeBuilder() *DefaulSyntaxTreeBuilder {
+ return &DefaulSyntaxTreeBuilder{}
+}
+
+// Shift is a implementation of SyntaxTreeBuilder.Shift.
+func (b *DefaulSyntaxTreeBuilder) Shift(kindName string, text string, row, col int) SyntaxTreeNode {
+ return &Node{
+ Type: NodeTypeTerminal,
+ KindName: kindName,
+ Text: text,
+ Row: row,
+ Col: col,
+ }
+}
+
+// ShiftError is a implementation of SyntaxTreeBuilder.ShiftError.
+func (b *DefaulSyntaxTreeBuilder) ShiftError(kindName string) SyntaxTreeNode {
+ return &Node{
+ Type: NodeTypeError,
+ KindName: kindName,
+ }
+}
+
+// Reduce is a implementation of SyntaxTreeBuilder.Reduce.
+func (b *DefaulSyntaxTreeBuilder) Reduce(kindName string, children []SyntaxTreeNode) SyntaxTreeNode {
+ cNodes := make([]*Node, len(children))
+ for i, c := range children {
+ cNodes[i] = c.(*Node)
+ }
+ return &Node{
+ Type: NodeTypeNonTerminal,
+ KindName: kindName,
+ Children: cNodes,
+ }
+}
+
+// Accept is a implementation of SyntaxTreeBuilder.Accept.
+func (b *DefaulSyntaxTreeBuilder) Accept(f SyntaxTreeNode) {
+ b.tree = f.(*Node)
+}
+
+// Tree returns a syntax tree when the parser has accepted an input. If a syntax error occurs, the return value is nil.
+func (b *DefaulSyntaxTreeBuilder) Tree() *Node {
+ return b.tree
+}
+
+// SyntaxTreeActionSet is a implementation of SemanticActionSet interface and constructs a syntax tree.
+type SyntaxTreeActionSet struct {
+ gram Grammar
+ builder SyntaxTreeBuilder
+ semStack *semanticStack
+ disableASTAction bool
+}
+
+// NewASTActionSet returns a new SyntaxTreeActionSet that constructs an AST (Abstract Syntax Tree).
+// When grammar `gram` contains `#ast` directives, the new SyntaxTreeActionSet this function returns interprets them.
+func NewASTActionSet(gram Grammar, builder SyntaxTreeBuilder) *SyntaxTreeActionSet {
+ return &SyntaxTreeActionSet{
+ gram: gram,
+ builder: builder,
+ semStack: newSemanticStack(),
+ }
+}
+
+// NewCSTTActionSet returns a new SyntaxTreeActionSet that constructs a CST (Concrete Syntax Tree).
+// Even if grammar `gram` contains `#ast` directives, the new SyntaxTreeActionSet this function returns ignores them.
+func NewCSTActionSet(gram Grammar, builder SyntaxTreeBuilder) *SyntaxTreeActionSet {
+ return &SyntaxTreeActionSet{
+ gram: gram,
+ builder: builder,
+ semStack: newSemanticStack(),
+ disableASTAction: true,
+ }
+}
+
+// Shift is a implementation of SemanticActionSet.Shift method.
+func (a *SyntaxTreeActionSet) Shift(tok VToken, recovered bool) {
+ term := a.tokenToTerminal(tok)
+ row, col := tok.Position()
+ a.semStack.push(a.builder.Shift(a.gram.Terminal(term), string(tok.Lexeme()), row, col))
+}
+
+// Reduce is a implementation of SemanticActionSet.Reduce method.
+func (a *SyntaxTreeActionSet) Reduce(prodNum int, recovered bool) {
+ lhs := a.gram.LHS(prodNum)
+
+ // When an alternative is empty, `n` will be 0, and `handle` will be empty slice.
+ n := a.gram.AlternativeSymbolCount(prodNum)
+ handle := a.semStack.pop(n)
+
+ var astAct []int
+ if !a.disableASTAction {
+ astAct = a.gram.ASTAction(prodNum)
+ }
+ var children []SyntaxTreeNode
+ if astAct != nil {
+ // Count the number of children in advance to avoid frequent growth in a slice for children.
+ {
+ l := 0
+ for _, e := range astAct {
+ if e > 0 {
+ l++
+ } else {
+ offset := e*-1 - 1
+ l += handle[offset].ChildCount()
+ }
+ }
+
+ children = make([]SyntaxTreeNode, l)
+ }
+
+ p := 0
+ for _, e := range astAct {
+ if e > 0 {
+ offset := e - 1
+ children[p] = handle[offset]
+ p++
+ } else {
+ offset := e*-1 - 1
+ for _, c := range handle[offset].ExpandChildren() {
+ children[p] = c
+ p++
+ }
+ }
+ }
+ } else {
+ // If an alternative has no AST action, a driver generates
+ // a node with the same structure as a CST.
+ children = handle
+ }
+
+ a.semStack.push(a.builder.Reduce(a.gram.NonTerminal(lhs), children))
+}
+
+// Accept is a implementation of SemanticActionSet.Accept method.
+func (a *SyntaxTreeActionSet) Accept() {
+ top := a.semStack.pop(1)
+ a.builder.Accept(top[0])
+}
+
+// TrapAndShiftError is a implementation of SemanticActionSet.TrapAndShiftError method.
+func (a *SyntaxTreeActionSet) TrapAndShiftError(cause VToken, popped int) {
+ a.semStack.pop(popped)
+ a.semStack.push(a.builder.ShiftError(a.gram.Terminal(a.gram.Error())))
+}
+
+// MissError is a implementation of SemanticActionSet.MissError method.
+func (a *SyntaxTreeActionSet) MissError(cause VToken) {
+}
+
+func (a *SyntaxTreeActionSet) tokenToTerminal(tok VToken) int {
+ if tok.EOF() {
+ return a.gram.EOF()
+ }
+
+ return tok.TerminalID()
+}
+
+type semanticStack struct {
+ frames []SyntaxTreeNode
+}
+
+func newSemanticStack() *semanticStack {
+ return &semanticStack{
+ frames: make([]SyntaxTreeNode, 0, 100),
+ }
+}
+
+func (s *semanticStack) push(f SyntaxTreeNode) {
+ s.frames = append(s.frames, f)
+}
+
+func (s *semanticStack) pop(n int) []SyntaxTreeNode {
+ fs := s.frames[len(s.frames)-n:]
+ s.frames = s.frames[:len(s.frames)-n]
+
+ return fs
+}
+
+type NodeType int
+
+const (
+ NodeTypeError = 0
+ NodeTypeTerminal = 1
+ NodeTypeNonTerminal = 2
+)
+
+// Node is a implementation of SyntaxTreeNode interface.
+type Node struct {
+ Type NodeType
+ KindName string
+ Text string
+ Row int
+ Col int
+ Children []*Node
+}
+
+func (n *Node) MarshalJSON() ([]byte, error) {
+ switch n.Type {
+ case NodeTypeError:
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ })
+ case NodeTypeTerminal:
+ if n.KindName == "" {
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ Text string `json:"text"`
+ Row int `json:"row"`
+ Col int `json:"col"`
+ }{
+ Type: n.Type,
+ Text: n.Text,
+ Row: n.Row,
+ Col: n.Col,
+ })
+ }
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ Text string `json:"text"`
+ Row int `json:"row"`
+ Col int `json:"col"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ Text: n.Text,
+ Row: n.Row,
+ Col: n.Col,
+ })
+ case NodeTypeNonTerminal:
+ return json.Marshal(struct {
+ Type NodeType `json:"type"`
+ KindName string `json:"kind_name"`
+ Children []*Node `json:"children"`
+ }{
+ Type: n.Type,
+ KindName: n.KindName,
+ Children: n.Children,
+ })
+ default:
+ return nil, fmt.Errorf("invalid node type: %v", n.Type)
+ }
+}
+
+// ChildCount is a implementation of SyntaxTreeNode.ChildCount.
+func (n *Node) ChildCount() int {
+ return len(n.Children)
+}
+
+// ExpandChildren is a implementation of SyntaxTreeNode.ExpandChildren.
+func (n *Node) ExpandChildren() []SyntaxTreeNode {
+ fs := make([]SyntaxTreeNode, len(n.Children))
+ for i, n := range n.Children {
+ fs[i] = n
+ }
+ return fs
+}
+
+// PrintTree prints a syntax tree whose root is `node`.
+func PrintTree(w io.Writer, node *Node) {
+ printTree(w, node, "", "")
+}
+
+func printTree(w io.Writer, node *Node, ruledLine string, childRuledLinePrefix string) {
+ if node == nil {
+ return
+ }
+
+ switch node.Type {
+ case NodeTypeError:
+ fmt.Fprintf(w, "%v%v\n", ruledLine, node.KindName)
+ case NodeTypeTerminal:
+ fmt.Fprintf(w, "%v%v %v\n", ruledLine, node.KindName, strconv.Quote(node.Text))
+ case NodeTypeNonTerminal:
+ fmt.Fprintf(w, "%v%v\n", ruledLine, node.KindName)
+
+ num := len(node.Children)
+ for i, child := range node.Children {
+ var line string
+ if num > 1 && i < num-1 {
+ line = "├─ "
+ } else {
+ line = "└─ "
+ }
+
+ var prefix string
+ if i >= num-1 {
+ prefix = " "
+ } else {
+ prefix = "│ "
+ }
+
+ printTree(w, child, childRuledLinePrefix+line, childRuledLinePrefix+prefix)
+ }
+ }
+}
diff --git a/src/urubu/tester/tester.go b/src/urubu/tester/tester.go
new file mode 100644
index 0000000..cae52b2
--- /dev/null
+++ b/src/urubu/tester/tester.go
@@ -0,0 +1,181 @@
+package tester
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime/debug"
+ "strings"
+
+ driver "urubu/driver/parser"
+ gspec "urubu/spec/grammar"
+ tspec "urubu/spec/test"
+)
+
+type TestResult struct {
+ TestCasePath string
+ Error error
+ Diffs []*tspec.TreeDiff
+}
+
+func (r *TestResult) String() string {
+ if r.Error != nil {
+ const indent1 = " "
+ const indent2 = indent1 + indent1
+
+ msgLines := strings.Split(r.Error.Error(), "\n")
+ msg := fmt.Sprintf("Failed %v:\n%v%v", r.TestCasePath, indent1, strings.Join(msgLines, "\n"+indent1))
+ if len(r.Diffs) == 0 {
+ return msg
+ }
+ var diffLines []string
+ for _, diff := range r.Diffs {
+ diffLines = append(diffLines, diff.Message)
+ diffLines = append(diffLines, fmt.Sprintf("%vexpected path: %v", indent1, diff.ExpectedPath))
+ diffLines = append(diffLines, fmt.Sprintf("%vactual path: %v", indent1, diff.ActualPath))
+ }
+ return fmt.Sprintf("%v\n%v%v", msg, indent2, strings.Join(diffLines, "\n"+indent2))
+ }
+ return fmt.Sprintf("Passed %v", r.TestCasePath)
+}
+
+type TestCaseWithMetadata struct {
+ TestCase *tspec.TestCase
+ FilePath string
+ Error error
+}
+
+func ListTestCases(testPath string) []*TestCaseWithMetadata {
+ fi, err := os.Stat(testPath)
+ if err != nil {
+ return []*TestCaseWithMetadata{
+ {
+ FilePath: testPath,
+ Error: err,
+ },
+ }
+ }
+ if !fi.IsDir() {
+ c, err := parseTestCase(testPath)
+ return []*TestCaseWithMetadata{
+ {
+ TestCase: c,
+ FilePath: testPath,
+ Error: err,
+ },
+ }
+ }
+
+ es, err := os.ReadDir(testPath)
+ if err != nil {
+ return []*TestCaseWithMetadata{
+ {
+ FilePath: testPath,
+ Error: err,
+ },
+ }
+ }
+ var cases []*TestCaseWithMetadata
+ for _, e := range es {
+ cs := ListTestCases(filepath.Join(testPath, e.Name()))
+ cases = append(cases, cs...)
+ }
+ return cases
+}
+
+func parseTestCase(testCasePath string) (*tspec.TestCase, error) {
+ f, err := os.Open(testCasePath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return tspec.ParseTestCase(f)
+}
+
+type Tester struct {
+ Grammar *gspec.CompiledGrammar
+ Cases []*TestCaseWithMetadata
+}
+
+func (t *Tester) Run() []*TestResult {
+ var rs []*TestResult
+ for _, c := range t.Cases {
+ rs = append(rs, runTest(t.Grammar, c))
+ }
+ return rs
+}
+
+func runTest(g *gspec.CompiledGrammar, c *TestCaseWithMetadata) *TestResult {
+ var p *driver.Parser
+ var tb *driver.DefaultSyntaxTreeBuilder
+ {
+ gram := driver.NewGrammar(g)
+ toks, err := driver.NewTokenStream(g, bytes.NewReader(c.TestCase.Source))
+ if err != nil {
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ Error: err,
+ }
+ }
+ tb = driver.NewDefaultSyntaxTreeBuilder()
+ p, err = driver.NewParser(toks, gram, driver.SemanticAction(driver.NewASTActionSet(gram, tb)))
+ if err != nil {
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ Error: err,
+ }
+ }
+ }
+
+ err := p.Parse()
+ if err != nil {
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ Error: err,
+ }
+ }
+
+ if tb.Tree() == nil {
+ var err error
+ if len(p.SyntaxErrors()) > 0 {
+ err = fmt.Errorf("parse tree was not generated: syntax error occurred")
+ } else {
+ // The parser should always generate a parse tree in the vartan-test command, so if there is no parse
+ // tree, it is a bug. We also include a stack trace in the error message to be sure.
+ err = fmt.Errorf("parse tree was not generated: no syntax error:\n%v", string(debug.Stack()))
+ }
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ Error: err,
+ }
+ }
+
+ // When a parse tree exists, the test continues regardless of whether or not syntax errors occurred.
+ diffs := tspec.DiffTree(c.TestCase.Output, ConvertSyntaxTreeToTestableTree(tb.Tree()).Fill())
+ if len(diffs) > 0 {
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ Error: fmt.Errorf("output mismatch"),
+ Diffs: diffs,
+ }
+ }
+ return &TestResult{
+ TestCasePath: c.FilePath,
+ }
+}
+
+func ConvertSyntaxTreeToTestableTree(dTree *driver.Node) *tspec.Tree {
+ if dTree.Text != "" {
+ return tspec.NewTerminalNode(dTree.KindName, dTree.Text)
+ }
+
+ var children []*tspec.Tree
+ if len(dTree.Children) > 0 {
+ children = make([]*tspec.Tree, len(dTree.Children))
+ for i, c := range dTree.Children {
+ children[i] = ConvertSyntaxTreeToTestableTree(c)
+ }
+ }
+ return tspec.NewNonTerminalTree(dTree.KindName, children...)
+}
diff --git a/src/urubu/ucd/api.go b/src/urubu/ucd/api.go
new file mode 100644
index 0000000..8265d54
--- /dev/null
+++ b/src/urubu/ucd/api.go
@@ -0,0 +1,180 @@
+//go:generate go run ../cmd/ucdgen/main.go
+//go:generate go fmt codepoint.go
+
+package ucd
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ // https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf
+ // 3.4 Characters and Encoding
+ // > D9 Unicode codespace: A range of integers from 0 to 10FFFF16.
+ codePointMin = 0x0
+ codePointMax = 0x10FFFF
+)
+
+func NormalizeCharacterProperty(propName, propVal string) (string, error) {
+ if propName == "" {
+ propName = "gc"
+ }
+
+ name, ok := propertyNameAbbs[normalizeSymbolicValue(propName)]
+ if !ok {
+ return "", fmt.Errorf("unsupported character property name: %v", propName)
+ }
+ props, ok := derivedCoreProperties[name]
+ if !ok {
+ return "", nil
+ }
+ var b strings.Builder
+ yes, ok := binaryValues[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return "", fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if yes {
+ fmt.Fprint(&b, "[")
+ } else {
+ fmt.Fprint(&b, "[^")
+ }
+ for _, prop := range props {
+ fmt.Fprint(&b, prop)
+ }
+ fmt.Fprint(&b, "]")
+
+ return b.String(), nil
+}
+
+func IsContributoryProperty(propName string) bool {
+ if propName == "" {
+ return false
+ }
+
+ for _, p := range contributoryProperties {
+ if propName == p {
+ return true
+ }
+ }
+ return false
+}
+
+func FindCodePointRanges(propName, propVal string) ([]*CodePointRange, bool, error) {
+ if propName == "" {
+ propName = "gc"
+ }
+
+ name, ok := propertyNameAbbs[normalizeSymbolicValue(propName)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property name: %v", propName)
+ }
+ switch name {
+ case "gc":
+ val, ok := generalCategoryValueAbbs[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if val == generalCategoryValueAbbs[normalizeSymbolicValue(generalCategoryDefaultValue)] {
+ var allCPs []*CodePointRange
+ if generalCategoryDefaultRange.From > codePointMin {
+ allCPs = append(allCPs, &CodePointRange{
+ From: codePointMin,
+ To: generalCategoryDefaultRange.From - 1,
+ })
+ }
+ if generalCategoryDefaultRange.To < codePointMax {
+ allCPs = append(allCPs, &CodePointRange{
+ From: generalCategoryDefaultRange.To + 1,
+ To: codePointMax,
+ })
+ }
+ for _, cp := range generalCategoryCodePoints {
+ allCPs = append(allCPs, cp...)
+ }
+ return allCPs, true, nil
+ }
+ vals, ok := compositGeneralCategories[val]
+ if !ok {
+ vals = []string{val}
+ }
+ var ranges []*CodePointRange
+ for _, v := range vals {
+ rs, ok := generalCategoryCodePoints[v]
+ if !ok {
+ return nil, false, fmt.Errorf("invalid value of the General_Category property: %v", v)
+ }
+ ranges = append(ranges, rs...)
+ }
+ return ranges, false, nil
+ case "sc":
+ val, ok := scriptValueAbbs[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if val == scriptValueAbbs[normalizeSymbolicValue(scriptDefaultValue)] {
+ var allCPs []*CodePointRange
+ if scriptDefaultRange.From > codePointMin {
+ allCPs = append(allCPs, &CodePointRange{
+ From: codePointMin,
+ To: scriptDefaultRange.From - 1,
+ })
+ }
+ if scriptDefaultRange.To < codePointMax {
+ allCPs = append(allCPs, &CodePointRange{
+ From: scriptDefaultRange.To + 1,
+ To: codePointMax,
+ })
+ }
+ for _, cp := range scriptCodepoints {
+ allCPs = append(allCPs, cp...)
+ }
+ return allCPs, true, nil
+ }
+ return scriptCodepoints[val], false, nil
+ case "oalpha":
+ yes, ok := binaryValues[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if yes {
+ return otherAlphabeticCodePoints, false, nil
+ } else {
+ return otherAlphabeticCodePoints, true, nil
+ }
+ case "olower":
+ yes, ok := binaryValues[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if yes {
+ return otherLowercaseCodePoints, false, nil
+ } else {
+ return otherLowercaseCodePoints, true, nil
+ }
+ case "oupper":
+ yes, ok := binaryValues[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if yes {
+ return otherUppercaseCodePoints, false, nil
+ } else {
+ return otherUppercaseCodePoints, true, nil
+ }
+ case "wspace":
+ yes, ok := binaryValues[normalizeSymbolicValue(propVal)]
+ if !ok {
+ return nil, false, fmt.Errorf("unsupported character property value: %v", propVal)
+ }
+ if yes {
+ return whiteSpaceCodePoints, false, nil
+ } else {
+ return whiteSpaceCodePoints, true, nil
+ }
+ }
+
+ // If the process reaches this code, it's a bug. We must handle all of the properties registered with
+ // the `propertyNameAbbs`.
+ return nil, false, fmt.Errorf("character property '%v' is unavailable", propName)
+}
diff --git a/src/urubu/ucd/codepoint.go b/src/urubu/ucd/codepoint.go
new file mode 100644
index 0000000..e9b411e
--- /dev/null
+++ b/src/urubu/ucd/codepoint.go
@@ -0,0 +1,6552 @@
+// Code generated by generator/main.go; DO NOT EDIT.
+
+package ucd
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var generalCategoryValueAbbs = map[string]string{
+ "c": "c",
+ "casedletter": "lc",
+ "cc": "cc",
+ "cf": "cf",
+ "closepunctuation": "pe",
+ "cn": "cn",
+ "cntrl": "cc",
+ "co": "co",
+ "combiningmark": "m",
+ "connectorpunctuation": "pc",
+ "control": "cc",
+ "cs": "cs",
+ "currencysymbol": "sc",
+ "dashpunctuation": "pd",
+ "decimalnumber": "nd",
+ "digit": "nd",
+ "enclosingmark": "me",
+ "finalpunctuation": "pf",
+ "format": "cf",
+ "initialpunctuation": "pi",
+ "l": "l",
+ "lc": "lc",
+ "letter": "l",
+ "letternumber": "nl",
+ "lineseparator": "zl",
+ "ll": "ll",
+ "lm": "lm",
+ "lo": "lo",
+ "lowercaseletter": "ll",
+ "lt": "lt",
+ "lu": "lu",
+ "m": "m",
+ "mark": "m",
+ "mathsymbol": "sm",
+ "mc": "mc",
+ "me": "me",
+ "mn": "mn",
+ "modifierletter": "lm",
+ "modifiersymbol": "sk",
+ "n": "n",
+ "nd": "nd",
+ "nl": "nl",
+ "no": "no",
+ "nonspacingmark": "mn",
+ "number": "n",
+ "openpunctuation": "ps",
+ "other": "c",
+ "otherletter": "lo",
+ "othernumber": "no",
+ "otherpunctuation": "po",
+ "othersymbol": "so",
+ "p": "p",
+ "paragraphseparator": "zp",
+ "pc": "pc",
+ "pd": "pd",
+ "pe": "pe",
+ "pf": "pf",
+ "pi": "pi",
+ "po": "po",
+ "privateuse": "co",
+ "ps": "ps",
+ "punct": "p",
+ "punctuation": "p",
+ "s": "s",
+ "sc": "sc",
+ "separator": "z",
+ "sk": "sk",
+ "sm": "sm",
+ "so": "so",
+ "spaceseparator": "zs",
+ "spacingmark": "mc",
+ "surrogate": "cs",
+ "symbol": "s",
+ "titlecaseletter": "lt",
+ "unassigned": "cn",
+ "uppercaseletter": "lu",
+ "z": "z",
+ "zl": "zl",
+ "zp": "zp",
+ "zs": "zs",
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var scriptValueAbbs = map[string]string{
+ "adlam": "adlm",
+ "adlm": "adlm",
+ "aghb": "aghb",
+ "ahom": "ahom",
+ "anatolianhieroglyphs": "hluw",
+ "arab": "arab",
+ "arabic": "arab",
+ "armenian": "armn",
+ "armi": "armi",
+ "armn": "armn",
+ "avestan": "avst",
+ "avst": "avst",
+ "bali": "bali",
+ "balinese": "bali",
+ "bamu": "bamu",
+ "bamum": "bamu",
+ "bass": "bass",
+ "bassavah": "bass",
+ "batak": "batk",
+ "batk": "batk",
+ "beng": "beng",
+ "bengali": "beng",
+ "bhaiksuki": "bhks",
+ "bhks": "bhks",
+ "bopo": "bopo",
+ "bopomofo": "bopo",
+ "brah": "brah",
+ "brahmi": "brah",
+ "brai": "brai",
+ "braille": "brai",
+ "bugi": "bugi",
+ "buginese": "bugi",
+ "buhd": "buhd",
+ "buhid": "buhd",
+ "cakm": "cakm",
+ "canadianaboriginal": "cans",
+ "cans": "cans",
+ "cari": "cari",
+ "carian": "cari",
+ "caucasianalbanian": "aghb",
+ "chakma": "cakm",
+ "cham": "cham",
+ "cher": "cher",
+ "cherokee": "cher",
+ "chorasmian": "chrs",
+ "chrs": "chrs",
+ "common": "zyyy",
+ "copt": "copt",
+ "coptic": "copt",
+ "cprt": "cprt",
+ "cuneiform": "xsux",
+ "cypriot": "cprt",
+ "cyrillic": "cyrl",
+ "cyrl": "cyrl",
+ "deseret": "dsrt",
+ "deva": "deva",
+ "devanagari": "deva",
+ "diak": "diak",
+ "divesakuru": "diak",
+ "dogr": "dogr",
+ "dogra": "dogr",
+ "dsrt": "dsrt",
+ "dupl": "dupl",
+ "duployan": "dupl",
+ "egyp": "egyp",
+ "egyptianhieroglyphs": "egyp",
+ "elba": "elba",
+ "elbasan": "elba",
+ "elym": "elym",
+ "elymaic": "elym",
+ "ethi": "ethi",
+ "ethiopic": "ethi",
+ "geor": "geor",
+ "georgian": "geor",
+ "glag": "glag",
+ "glagolitic": "glag",
+ "gong": "gong",
+ "gonm": "gonm",
+ "goth": "goth",
+ "gothic": "goth",
+ "gran": "gran",
+ "grantha": "gran",
+ "greek": "grek",
+ "grek": "grek",
+ "gujarati": "gujr",
+ "gujr": "gujr",
+ "gunjalagondi": "gong",
+ "gurmukhi": "guru",
+ "guru": "guru",
+ "han": "hani",
+ "hang": "hang",
+ "hangul": "hang",
+ "hani": "hani",
+ "hanifirohingya": "rohg",
+ "hano": "hano",
+ "hanunoo": "hano",
+ "hatr": "hatr",
+ "hatran": "hatr",
+ "hebr": "hebr",
+ "hebrew": "hebr",
+ "hira": "hira",
+ "hiragana": "hira",
+ "hluw": "hluw",
+ "hmng": "hmng",
+ "hmnp": "hmnp",
+ "hrkt": "hrkt",
+ "hung": "hung",
+ "imperialaramaic": "armi",
+ "inherited": "zinh",
+ "inscriptionalpahlavi": "phli",
+ "inscriptionalparthian": "prti",
+ "ital": "ital",
+ "java": "java",
+ "javanese": "java",
+ "kaithi": "kthi",
+ "kali": "kali",
+ "kana": "kana",
+ "kannada": "knda",
+ "katakana": "kana",
+ "katakanaorhiragana": "hrkt",
+ "kayahli": "kali",
+ "khar": "khar",
+ "kharoshthi": "khar",
+ "khitansmallscript": "kits",
+ "khmer": "khmr",
+ "khmr": "khmr",
+ "khoj": "khoj",
+ "khojki": "khoj",
+ "khudawadi": "sind",
+ "kits": "kits",
+ "knda": "knda",
+ "kthi": "kthi",
+ "lana": "lana",
+ "lao": "laoo",
+ "laoo": "laoo",
+ "latin": "latn",
+ "latn": "latn",
+ "lepc": "lepc",
+ "lepcha": "lepc",
+ "limb": "limb",
+ "limbu": "limb",
+ "lina": "lina",
+ "linb": "linb",
+ "lineara": "lina",
+ "linearb": "linb",
+ "lisu": "lisu",
+ "lyci": "lyci",
+ "lycian": "lyci",
+ "lydi": "lydi",
+ "lydian": "lydi",
+ "mahajani": "mahj",
+ "mahj": "mahj",
+ "maka": "maka",
+ "makasar": "maka",
+ "malayalam": "mlym",
+ "mand": "mand",
+ "mandaic": "mand",
+ "mani": "mani",
+ "manichaean": "mani",
+ "marc": "marc",
+ "marchen": "marc",
+ "masaramgondi": "gonm",
+ "medefaidrin": "medf",
+ "medf": "medf",
+ "meeteimayek": "mtei",
+ "mend": "mend",
+ "mendekikakui": "mend",
+ "merc": "merc",
+ "mero": "mero",
+ "meroiticcursive": "merc",
+ "meroitichieroglyphs": "mero",
+ "miao": "plrd",
+ "mlym": "mlym",
+ "modi": "modi",
+ "mong": "mong",
+ "mongolian": "mong",
+ "mro": "mroo",
+ "mroo": "mroo",
+ "mtei": "mtei",
+ "mult": "mult",
+ "multani": "mult",
+ "myanmar": "mymr",
+ "mymr": "mymr",
+ "nabataean": "nbat",
+ "nand": "nand",
+ "nandinagari": "nand",
+ "narb": "narb",
+ "nbat": "nbat",
+ "newa": "newa",
+ "newtailue": "talu",
+ "nko": "nkoo",
+ "nkoo": "nkoo",
+ "nshu": "nshu",
+ "nushu": "nshu",
+ "nyiakengpuachuehmong": "hmnp",
+ "ogam": "ogam",
+ "ogham": "ogam",
+ "olchiki": "olck",
+ "olck": "olck",
+ "oldhungarian": "hung",
+ "olditalic": "ital",
+ "oldnortharabian": "narb",
+ "oldpermic": "perm",
+ "oldpersian": "xpeo",
+ "oldsogdian": "sogo",
+ "oldsoutharabian": "sarb",
+ "oldturkic": "orkh",
+ "oriya": "orya",
+ "orkh": "orkh",
+ "orya": "orya",
+ "osage": "osge",
+ "osge": "osge",
+ "osma": "osma",
+ "osmanya": "osma",
+ "pahawhhmong": "hmng",
+ "palm": "palm",
+ "palmyrene": "palm",
+ "pauc": "pauc",
+ "paucinhau": "pauc",
+ "perm": "perm",
+ "phag": "phag",
+ "phagspa": "phag",
+ "phli": "phli",
+ "phlp": "phlp",
+ "phnx": "phnx",
+ "phoenician": "phnx",
+ "plrd": "plrd",
+ "prti": "prti",
+ "psalterpahlavi": "phlp",
+ "qaac": "copt",
+ "qaai": "zinh",
+ "rejang": "rjng",
+ "rjng": "rjng",
+ "rohg": "rohg",
+ "runic": "runr",
+ "runr": "runr",
+ "samaritan": "samr",
+ "samr": "samr",
+ "sarb": "sarb",
+ "saur": "saur",
+ "saurashtra": "saur",
+ "sgnw": "sgnw",
+ "sharada": "shrd",
+ "shavian": "shaw",
+ "shaw": "shaw",
+ "shrd": "shrd",
+ "sidd": "sidd",
+ "siddham": "sidd",
+ "signwriting": "sgnw",
+ "sind": "sind",
+ "sinh": "sinh",
+ "sinhala": "sinh",
+ "sogd": "sogd",
+ "sogdian": "sogd",
+ "sogo": "sogo",
+ "sora": "sora",
+ "sorasompeng": "sora",
+ "soyo": "soyo",
+ "soyombo": "soyo",
+ "sund": "sund",
+ "sundanese": "sund",
+ "sylo": "sylo",
+ "sylotinagri": "sylo",
+ "syrc": "syrc",
+ "syriac": "syrc",
+ "tagalog": "tglg",
+ "tagb": "tagb",
+ "tagbanwa": "tagb",
+ "taile": "tale",
+ "taitham": "lana",
+ "taiviet": "tavt",
+ "takr": "takr",
+ "takri": "takr",
+ "tale": "tale",
+ "talu": "talu",
+ "tamil": "taml",
+ "taml": "taml",
+ "tang": "tang",
+ "tangut": "tang",
+ "tavt": "tavt",
+ "telu": "telu",
+ "telugu": "telu",
+ "tfng": "tfng",
+ "tglg": "tglg",
+ "thaa": "thaa",
+ "thaana": "thaa",
+ "thai": "thai",
+ "tibetan": "tibt",
+ "tibt": "tibt",
+ "tifinagh": "tfng",
+ "tirh": "tirh",
+ "tirhuta": "tirh",
+ "ugar": "ugar",
+ "ugaritic": "ugar",
+ "unknown": "zzzz",
+ "vai": "vaii",
+ "vaii": "vaii",
+ "wancho": "wcho",
+ "wara": "wara",
+ "warangciti": "wara",
+ "wcho": "wcho",
+ "xpeo": "xpeo",
+ "xsux": "xsux",
+ "yezi": "yezi",
+ "yezidi": "yezi",
+ "yi": "yiii",
+ "yiii": "yiii",
+ "zanabazarsquare": "zanb",
+ "zanb": "zanb",
+ "zinh": "zinh",
+ "zyyy": "zyyy",
+ "zzzz": "zzzz",
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var (
+ generalCategoryDefaultRange = &CodePointRange{
+ From: rune(0),
+ To: rune(1114111),
+ }
+ generalCategoryDefaultValue = "unassigned"
+)
+
+// https://www.unicode.org/Public/13.0.0/ucd/UnicodeData.txt
+var generalCategoryCodePoints = map[string][]*CodePointRange{
+ "cc": {
+ &CodePointRange{From: rune(0), To: rune(31)},
+ &CodePointRange{From: rune(127), To: rune(159)},
+ },
+ "cf": {
+ &CodePointRange{From: rune(173), To: rune(173)},
+ &CodePointRange{From: rune(1536), To: rune(1541)},
+ &CodePointRange{From: rune(1564), To: rune(1564)},
+ &CodePointRange{From: rune(1757), To: rune(1757)},
+ &CodePointRange{From: rune(1807), To: rune(1807)},
+ &CodePointRange{From: rune(2274), To: rune(2274)},
+ &CodePointRange{From: rune(6158), To: rune(6158)},
+ &CodePointRange{From: rune(8203), To: rune(8207)},
+ &CodePointRange{From: rune(8234), To: rune(8238)},
+ &CodePointRange{From: rune(8288), To: rune(8292)},
+ &CodePointRange{From: rune(8294), To: rune(8303)},
+ &CodePointRange{From: rune(65279), To: rune(65279)},
+ &CodePointRange{From: rune(65529), To: rune(65531)},
+ &CodePointRange{From: rune(69821), To: rune(69821)},
+ &CodePointRange{From: rune(69837), To: rune(69837)},
+ &CodePointRange{From: rune(78896), To: rune(78904)},
+ &CodePointRange{From: rune(113824), To: rune(113827)},
+ &CodePointRange{From: rune(119155), To: rune(119162)},
+ &CodePointRange{From: rune(917505), To: rune(917505)},
+ &CodePointRange{From: rune(917536), To: rune(917631)},
+ },
+ "co": {
+ &CodePointRange{From: rune(57344), To: rune(57344)},
+ &CodePointRange{From: rune(63743), To: rune(63743)},
+ &CodePointRange{From: rune(983040), To: rune(983040)},
+ &CodePointRange{From: rune(1048573), To: rune(1048573)},
+ &CodePointRange{From: rune(1048576), To: rune(1048576)},
+ &CodePointRange{From: rune(1114109), To: rune(1114109)},
+ },
+ "cs": {
+ &CodePointRange{From: rune(55296), To: rune(55296)},
+ &CodePointRange{From: rune(56191), To: rune(56192)},
+ &CodePointRange{From: rune(56319), To: rune(56320)},
+ &CodePointRange{From: rune(57343), To: rune(57343)},
+ },
+ "ll": {
+ &CodePointRange{From: rune(97), To: rune(122)},
+ &CodePointRange{From: rune(181), To: rune(181)},
+ &CodePointRange{From: rune(223), To: rune(246)},
+ &CodePointRange{From: rune(248), To: rune(255)},
+ &CodePointRange{From: rune(257), To: rune(257)},
+ &CodePointRange{From: rune(259), To: rune(259)},
+ &CodePointRange{From: rune(261), To: rune(261)},
+ &CodePointRange{From: rune(263), To: rune(263)},
+ &CodePointRange{From: rune(265), To: rune(265)},
+ &CodePointRange{From: rune(267), To: rune(267)},
+ &CodePointRange{From: rune(269), To: rune(269)},
+ &CodePointRange{From: rune(271), To: rune(271)},
+ &CodePointRange{From: rune(273), To: rune(273)},
+ &CodePointRange{From: rune(275), To: rune(275)},
+ &CodePointRange{From: rune(277), To: rune(277)},
+ &CodePointRange{From: rune(279), To: rune(279)},
+ &CodePointRange{From: rune(281), To: rune(281)},
+ &CodePointRange{From: rune(283), To: rune(283)},
+ &CodePointRange{From: rune(285), To: rune(285)},
+ &CodePointRange{From: rune(287), To: rune(287)},
+ &CodePointRange{From: rune(289), To: rune(289)},
+ &CodePointRange{From: rune(291), To: rune(291)},
+ &CodePointRange{From: rune(293), To: rune(293)},
+ &CodePointRange{From: rune(295), To: rune(295)},
+ &CodePointRange{From: rune(297), To: rune(297)},
+ &CodePointRange{From: rune(299), To: rune(299)},
+ &CodePointRange{From: rune(301), To: rune(301)},
+ &CodePointRange{From: rune(303), To: rune(303)},
+ &CodePointRange{From: rune(305), To: rune(305)},
+ &CodePointRange{From: rune(307), To: rune(307)},
+ &CodePointRange{From: rune(309), To: rune(309)},
+ &CodePointRange{From: rune(311), To: rune(312)},
+ &CodePointRange{From: rune(314), To: rune(314)},
+ &CodePointRange{From: rune(316), To: rune(316)},
+ &CodePointRange{From: rune(318), To: rune(318)},
+ &CodePointRange{From: rune(320), To: rune(320)},
+ &CodePointRange{From: rune(322), To: rune(322)},
+ &CodePointRange{From: rune(324), To: rune(324)},
+ &CodePointRange{From: rune(326), To: rune(326)},
+ &CodePointRange{From: rune(328), To: rune(329)},
+ &CodePointRange{From: rune(331), To: rune(331)},
+ &CodePointRange{From: rune(333), To: rune(333)},
+ &CodePointRange{From: rune(335), To: rune(335)},
+ &CodePointRange{From: rune(337), To: rune(337)},
+ &CodePointRange{From: rune(339), To: rune(339)},
+ &CodePointRange{From: rune(341), To: rune(341)},
+ &CodePointRange{From: rune(343), To: rune(343)},
+ &CodePointRange{From: rune(345), To: rune(345)},
+ &CodePointRange{From: rune(347), To: rune(347)},
+ &CodePointRange{From: rune(349), To: rune(349)},
+ &CodePointRange{From: rune(351), To: rune(351)},
+ &CodePointRange{From: rune(353), To: rune(353)},
+ &CodePointRange{From: rune(355), To: rune(355)},
+ &CodePointRange{From: rune(357), To: rune(357)},
+ &CodePointRange{From: rune(359), To: rune(359)},
+ &CodePointRange{From: rune(361), To: rune(361)},
+ &CodePointRange{From: rune(363), To: rune(363)},
+ &CodePointRange{From: rune(365), To: rune(365)},
+ &CodePointRange{From: rune(367), To: rune(367)},
+ &CodePointRange{From: rune(369), To: rune(369)},
+ &CodePointRange{From: rune(371), To: rune(371)},
+ &CodePointRange{From: rune(373), To: rune(373)},
+ &CodePointRange{From: rune(375), To: rune(375)},
+ &CodePointRange{From: rune(378), To: rune(378)},
+ &CodePointRange{From: rune(380), To: rune(380)},
+ &CodePointRange{From: rune(382), To: rune(384)},
+ &CodePointRange{From: rune(387), To: rune(387)},
+ &CodePointRange{From: rune(389), To: rune(389)},
+ &CodePointRange{From: rune(392), To: rune(392)},
+ &CodePointRange{From: rune(396), To: rune(397)},
+ &CodePointRange{From: rune(402), To: rune(402)},
+ &CodePointRange{From: rune(405), To: rune(405)},
+ &CodePointRange{From: rune(409), To: rune(411)},
+ &CodePointRange{From: rune(414), To: rune(414)},
+ &CodePointRange{From: rune(417), To: rune(417)},
+ &CodePointRange{From: rune(419), To: rune(419)},
+ &CodePointRange{From: rune(421), To: rune(421)},
+ &CodePointRange{From: rune(424), To: rune(424)},
+ &CodePointRange{From: rune(426), To: rune(427)},
+ &CodePointRange{From: rune(429), To: rune(429)},
+ &CodePointRange{From: rune(432), To: rune(432)},
+ &CodePointRange{From: rune(436), To: rune(436)},
+ &CodePointRange{From: rune(438), To: rune(438)},
+ &CodePointRange{From: rune(441), To: rune(442)},
+ &CodePointRange{From: rune(445), To: rune(447)},
+ &CodePointRange{From: rune(454), To: rune(454)},
+ &CodePointRange{From: rune(457), To: rune(457)},
+ &CodePointRange{From: rune(460), To: rune(460)},
+ &CodePointRange{From: rune(462), To: rune(462)},
+ &CodePointRange{From: rune(464), To: rune(464)},
+ &CodePointRange{From: rune(466), To: rune(466)},
+ &CodePointRange{From: rune(468), To: rune(468)},
+ &CodePointRange{From: rune(470), To: rune(470)},
+ &CodePointRange{From: rune(472), To: rune(472)},
+ &CodePointRange{From: rune(474), To: rune(474)},
+ &CodePointRange{From: rune(476), To: rune(477)},
+ &CodePointRange{From: rune(479), To: rune(479)},
+ &CodePointRange{From: rune(481), To: rune(481)},
+ &CodePointRange{From: rune(483), To: rune(483)},
+ &CodePointRange{From: rune(485), To: rune(485)},
+ &CodePointRange{From: rune(487), To: rune(487)},
+ &CodePointRange{From: rune(489), To: rune(489)},
+ &CodePointRange{From: rune(491), To: rune(491)},
+ &CodePointRange{From: rune(493), To: rune(493)},
+ &CodePointRange{From: rune(495), To: rune(496)},
+ &CodePointRange{From: rune(499), To: rune(499)},
+ &CodePointRange{From: rune(501), To: rune(501)},
+ &CodePointRange{From: rune(505), To: rune(505)},
+ &CodePointRange{From: rune(507), To: rune(507)},
+ &CodePointRange{From: rune(509), To: rune(509)},
+ &CodePointRange{From: rune(511), To: rune(511)},
+ &CodePointRange{From: rune(513), To: rune(513)},
+ &CodePointRange{From: rune(515), To: rune(515)},
+ &CodePointRange{From: rune(517), To: rune(517)},
+ &CodePointRange{From: rune(519), To: rune(519)},
+ &CodePointRange{From: rune(521), To: rune(521)},
+ &CodePointRange{From: rune(523), To: rune(523)},
+ &CodePointRange{From: rune(525), To: rune(525)},
+ &CodePointRange{From: rune(527), To: rune(527)},
+ &CodePointRange{From: rune(529), To: rune(529)},
+ &CodePointRange{From: rune(531), To: rune(531)},
+ &CodePointRange{From: rune(533), To: rune(533)},
+ &CodePointRange{From: rune(535), To: rune(535)},
+ &CodePointRange{From: rune(537), To: rune(537)},
+ &CodePointRange{From: rune(539), To: rune(539)},
+ &CodePointRange{From: rune(541), To: rune(541)},
+ &CodePointRange{From: rune(543), To: rune(543)},
+ &CodePointRange{From: rune(545), To: rune(545)},
+ &CodePointRange{From: rune(547), To: rune(547)},
+ &CodePointRange{From: rune(549), To: rune(549)},
+ &CodePointRange{From: rune(551), To: rune(551)},
+ &CodePointRange{From: rune(553), To: rune(553)},
+ &CodePointRange{From: rune(555), To: rune(555)},
+ &CodePointRange{From: rune(557), To: rune(557)},
+ &CodePointRange{From: rune(559), To: rune(559)},
+ &CodePointRange{From: rune(561), To: rune(561)},
+ &CodePointRange{From: rune(563), To: rune(569)},
+ &CodePointRange{From: rune(572), To: rune(572)},
+ &CodePointRange{From: rune(575), To: rune(576)},
+ &CodePointRange{From: rune(578), To: rune(578)},
+ &CodePointRange{From: rune(583), To: rune(583)},
+ &CodePointRange{From: rune(585), To: rune(585)},
+ &CodePointRange{From: rune(587), To: rune(587)},
+ &CodePointRange{From: rune(589), To: rune(589)},
+ &CodePointRange{From: rune(591), To: rune(659)},
+ &CodePointRange{From: rune(661), To: rune(687)},
+ &CodePointRange{From: rune(881), To: rune(881)},
+ &CodePointRange{From: rune(883), To: rune(883)},
+ &CodePointRange{From: rune(887), To: rune(887)},
+ &CodePointRange{From: rune(891), To: rune(893)},
+ &CodePointRange{From: rune(912), To: rune(912)},
+ &CodePointRange{From: rune(940), To: rune(974)},
+ &CodePointRange{From: rune(976), To: rune(977)},
+ &CodePointRange{From: rune(981), To: rune(983)},
+ &CodePointRange{From: rune(985), To: rune(985)},
+ &CodePointRange{From: rune(987), To: rune(987)},
+ &CodePointRange{From: rune(989), To: rune(989)},
+ &CodePointRange{From: rune(991), To: rune(991)},
+ &CodePointRange{From: rune(993), To: rune(993)},
+ &CodePointRange{From: rune(995), To: rune(995)},
+ &CodePointRange{From: rune(997), To: rune(997)},
+ &CodePointRange{From: rune(999), To: rune(999)},
+ &CodePointRange{From: rune(1001), To: rune(1001)},
+ &CodePointRange{From: rune(1003), To: rune(1003)},
+ &CodePointRange{From: rune(1005), To: rune(1005)},
+ &CodePointRange{From: rune(1007), To: rune(1011)},
+ &CodePointRange{From: rune(1013), To: rune(1013)},
+ &CodePointRange{From: rune(1016), To: rune(1016)},
+ &CodePointRange{From: rune(1019), To: rune(1020)},
+ &CodePointRange{From: rune(1072), To: rune(1119)},
+ &CodePointRange{From: rune(1121), To: rune(1121)},
+ &CodePointRange{From: rune(1123), To: rune(1123)},
+ &CodePointRange{From: rune(1125), To: rune(1125)},
+ &CodePointRange{From: rune(1127), To: rune(1127)},
+ &CodePointRange{From: rune(1129), To: rune(1129)},
+ &CodePointRange{From: rune(1131), To: rune(1131)},
+ &CodePointRange{From: rune(1133), To: rune(1133)},
+ &CodePointRange{From: rune(1135), To: rune(1135)},
+ &CodePointRange{From: rune(1137), To: rune(1137)},
+ &CodePointRange{From: rune(1139), To: rune(1139)},
+ &CodePointRange{From: rune(1141), To: rune(1141)},
+ &CodePointRange{From: rune(1143), To: rune(1143)},
+ &CodePointRange{From: rune(1145), To: rune(1145)},
+ &CodePointRange{From: rune(1147), To: rune(1147)},
+ &CodePointRange{From: rune(1149), To: rune(1149)},
+ &CodePointRange{From: rune(1151), To: rune(1151)},
+ &CodePointRange{From: rune(1153), To: rune(1153)},
+ &CodePointRange{From: rune(1163), To: rune(1163)},
+ &CodePointRange{From: rune(1165), To: rune(1165)},
+ &CodePointRange{From: rune(1167), To: rune(1167)},
+ &CodePointRange{From: rune(1169), To: rune(1169)},
+ &CodePointRange{From: rune(1171), To: rune(1171)},
+ &CodePointRange{From: rune(1173), To: rune(1173)},
+ &CodePointRange{From: rune(1175), To: rune(1175)},
+ &CodePointRange{From: rune(1177), To: rune(1177)},
+ &CodePointRange{From: rune(1179), To: rune(1179)},
+ &CodePointRange{From: rune(1181), To: rune(1181)},
+ &CodePointRange{From: rune(1183), To: rune(1183)},
+ &CodePointRange{From: rune(1185), To: rune(1185)},
+ &CodePointRange{From: rune(1187), To: rune(1187)},
+ &CodePointRange{From: rune(1189), To: rune(1189)},
+ &CodePointRange{From: rune(1191), To: rune(1191)},
+ &CodePointRange{From: rune(1193), To: rune(1193)},
+ &CodePointRange{From: rune(1195), To: rune(1195)},
+ &CodePointRange{From: rune(1197), To: rune(1197)},
+ &CodePointRange{From: rune(1199), To: rune(1199)},
+ &CodePointRange{From: rune(1201), To: rune(1201)},
+ &CodePointRange{From: rune(1203), To: rune(1203)},
+ &CodePointRange{From: rune(1205), To: rune(1205)},
+ &CodePointRange{From: rune(1207), To: rune(1207)},
+ &CodePointRange{From: rune(1209), To: rune(1209)},
+ &CodePointRange{From: rune(1211), To: rune(1211)},
+ &CodePointRange{From: rune(1213), To: rune(1213)},
+ &CodePointRange{From: rune(1215), To: rune(1215)},
+ &CodePointRange{From: rune(1218), To: rune(1218)},
+ &CodePointRange{From: rune(1220), To: rune(1220)},
+ &CodePointRange{From: rune(1222), To: rune(1222)},
+ &CodePointRange{From: rune(1224), To: rune(1224)},
+ &CodePointRange{From: rune(1226), To: rune(1226)},
+ &CodePointRange{From: rune(1228), To: rune(1228)},
+ &CodePointRange{From: rune(1230), To: rune(1231)},
+ &CodePointRange{From: rune(1233), To: rune(1233)},
+ &CodePointRange{From: rune(1235), To: rune(1235)},
+ &CodePointRange{From: rune(1237), To: rune(1237)},
+ &CodePointRange{From: rune(1239), To: rune(1239)},
+ &CodePointRange{From: rune(1241), To: rune(1241)},
+ &CodePointRange{From: rune(1243), To: rune(1243)},
+ &CodePointRange{From: rune(1245), To: rune(1245)},
+ &CodePointRange{From: rune(1247), To: rune(1247)},
+ &CodePointRange{From: rune(1249), To: rune(1249)},
+ &CodePointRange{From: rune(1251), To: rune(1251)},
+ &CodePointRange{From: rune(1253), To: rune(1253)},
+ &CodePointRange{From: rune(1255), To: rune(1255)},
+ &CodePointRange{From: rune(1257), To: rune(1257)},
+ &CodePointRange{From: rune(1259), To: rune(1259)},
+ &CodePointRange{From: rune(1261), To: rune(1261)},
+ &CodePointRange{From: rune(1263), To: rune(1263)},
+ &CodePointRange{From: rune(1265), To: rune(1265)},
+ &CodePointRange{From: rune(1267), To: rune(1267)},
+ &CodePointRange{From: rune(1269), To: rune(1269)},
+ &CodePointRange{From: rune(1271), To: rune(1271)},
+ &CodePointRange{From: rune(1273), To: rune(1273)},
+ &CodePointRange{From: rune(1275), To: rune(1275)},
+ &CodePointRange{From: rune(1277), To: rune(1277)},
+ &CodePointRange{From: rune(1279), To: rune(1279)},
+ &CodePointRange{From: rune(1281), To: rune(1281)},
+ &CodePointRange{From: rune(1283), To: rune(1283)},
+ &CodePointRange{From: rune(1285), To: rune(1285)},
+ &CodePointRange{From: rune(1287), To: rune(1287)},
+ &CodePointRange{From: rune(1289), To: rune(1289)},
+ &CodePointRange{From: rune(1291), To: rune(1291)},
+ &CodePointRange{From: rune(1293), To: rune(1293)},
+ &CodePointRange{From: rune(1295), To: rune(1295)},
+ &CodePointRange{From: rune(1297), To: rune(1297)},
+ &CodePointRange{From: rune(1299), To: rune(1299)},
+ &CodePointRange{From: rune(1301), To: rune(1301)},
+ &CodePointRange{From: rune(1303), To: rune(1303)},
+ &CodePointRange{From: rune(1305), To: rune(1305)},
+ &CodePointRange{From: rune(1307), To: rune(1307)},
+ &CodePointRange{From: rune(1309), To: rune(1309)},
+ &CodePointRange{From: rune(1311), To: rune(1311)},
+ &CodePointRange{From: rune(1313), To: rune(1313)},
+ &CodePointRange{From: rune(1315), To: rune(1315)},
+ &CodePointRange{From: rune(1317), To: rune(1317)},
+ &CodePointRange{From: rune(1319), To: rune(1319)},
+ &CodePointRange{From: rune(1321), To: rune(1321)},
+ &CodePointRange{From: rune(1323), To: rune(1323)},
+ &CodePointRange{From: rune(1325), To: rune(1325)},
+ &CodePointRange{From: rune(1327), To: rune(1327)},
+ &CodePointRange{From: rune(1376), To: rune(1416)},
+ &CodePointRange{From: rune(4304), To: rune(4346)},
+ &CodePointRange{From: rune(4349), To: rune(4351)},
+ &CodePointRange{From: rune(5112), To: rune(5117)},
+ &CodePointRange{From: rune(7296), To: rune(7304)},
+ &CodePointRange{From: rune(7424), To: rune(7467)},
+ &CodePointRange{From: rune(7531), To: rune(7543)},
+ &CodePointRange{From: rune(7545), To: rune(7578)},
+ &CodePointRange{From: rune(7681), To: rune(7681)},
+ &CodePointRange{From: rune(7683), To: rune(7683)},
+ &CodePointRange{From: rune(7685), To: rune(7685)},
+ &CodePointRange{From: rune(7687), To: rune(7687)},
+ &CodePointRange{From: rune(7689), To: rune(7689)},
+ &CodePointRange{From: rune(7691), To: rune(7691)},
+ &CodePointRange{From: rune(7693), To: rune(7693)},
+ &CodePointRange{From: rune(7695), To: rune(7695)},
+ &CodePointRange{From: rune(7697), To: rune(7697)},
+ &CodePointRange{From: rune(7699), To: rune(7699)},
+ &CodePointRange{From: rune(7701), To: rune(7701)},
+ &CodePointRange{From: rune(7703), To: rune(7703)},
+ &CodePointRange{From: rune(7705), To: rune(7705)},
+ &CodePointRange{From: rune(7707), To: rune(7707)},
+ &CodePointRange{From: rune(7709), To: rune(7709)},
+ &CodePointRange{From: rune(7711), To: rune(7711)},
+ &CodePointRange{From: rune(7713), To: rune(7713)},
+ &CodePointRange{From: rune(7715), To: rune(7715)},
+ &CodePointRange{From: rune(7717), To: rune(7717)},
+ &CodePointRange{From: rune(7719), To: rune(7719)},
+ &CodePointRange{From: rune(7721), To: rune(7721)},
+ &CodePointRange{From: rune(7723), To: rune(7723)},
+ &CodePointRange{From: rune(7725), To: rune(7725)},
+ &CodePointRange{From: rune(7727), To: rune(7727)},
+ &CodePointRange{From: rune(7729), To: rune(7729)},
+ &CodePointRange{From: rune(7731), To: rune(7731)},
+ &CodePointRange{From: rune(7733), To: rune(7733)},
+ &CodePointRange{From: rune(7735), To: rune(7735)},
+ &CodePointRange{From: rune(7737), To: rune(7737)},
+ &CodePointRange{From: rune(7739), To: rune(7739)},
+ &CodePointRange{From: rune(7741), To: rune(7741)},
+ &CodePointRange{From: rune(7743), To: rune(7743)},
+ &CodePointRange{From: rune(7745), To: rune(7745)},
+ &CodePointRange{From: rune(7747), To: rune(7747)},
+ &CodePointRange{From: rune(7749), To: rune(7749)},
+ &CodePointRange{From: rune(7751), To: rune(7751)},
+ &CodePointRange{From: rune(7753), To: rune(7753)},
+ &CodePointRange{From: rune(7755), To: rune(7755)},
+ &CodePointRange{From: rune(7757), To: rune(7757)},
+ &CodePointRange{From: rune(7759), To: rune(7759)},
+ &CodePointRange{From: rune(7761), To: rune(7761)},
+ &CodePointRange{From: rune(7763), To: rune(7763)},
+ &CodePointRange{From: rune(7765), To: rune(7765)},
+ &CodePointRange{From: rune(7767), To: rune(7767)},
+ &CodePointRange{From: rune(7769), To: rune(7769)},
+ &CodePointRange{From: rune(7771), To: rune(7771)},
+ &CodePointRange{From: rune(7773), To: rune(7773)},
+ &CodePointRange{From: rune(7775), To: rune(7775)},
+ &CodePointRange{From: rune(7777), To: rune(7777)},
+ &CodePointRange{From: rune(7779), To: rune(7779)},
+ &CodePointRange{From: rune(7781), To: rune(7781)},
+ &CodePointRange{From: rune(7783), To: rune(7783)},
+ &CodePointRange{From: rune(7785), To: rune(7785)},
+ &CodePointRange{From: rune(7787), To: rune(7787)},
+ &CodePointRange{From: rune(7789), To: rune(7789)},
+ &CodePointRange{From: rune(7791), To: rune(7791)},
+ &CodePointRange{From: rune(7793), To: rune(7793)},
+ &CodePointRange{From: rune(7795), To: rune(7795)},
+ &CodePointRange{From: rune(7797), To: rune(7797)},
+ &CodePointRange{From: rune(7799), To: rune(7799)},
+ &CodePointRange{From: rune(7801), To: rune(7801)},
+ &CodePointRange{From: rune(7803), To: rune(7803)},
+ &CodePointRange{From: rune(7805), To: rune(7805)},
+ &CodePointRange{From: rune(7807), To: rune(7807)},
+ &CodePointRange{From: rune(7809), To: rune(7809)},
+ &CodePointRange{From: rune(7811), To: rune(7811)},
+ &CodePointRange{From: rune(7813), To: rune(7813)},
+ &CodePointRange{From: rune(7815), To: rune(7815)},
+ &CodePointRange{From: rune(7817), To: rune(7817)},
+ &CodePointRange{From: rune(7819), To: rune(7819)},
+ &CodePointRange{From: rune(7821), To: rune(7821)},
+ &CodePointRange{From: rune(7823), To: rune(7823)},
+ &CodePointRange{From: rune(7825), To: rune(7825)},
+ &CodePointRange{From: rune(7827), To: rune(7827)},
+ &CodePointRange{From: rune(7829), To: rune(7837)},
+ &CodePointRange{From: rune(7839), To: rune(7839)},
+ &CodePointRange{From: rune(7841), To: rune(7841)},
+ &CodePointRange{From: rune(7843), To: rune(7843)},
+ &CodePointRange{From: rune(7845), To: rune(7845)},
+ &CodePointRange{From: rune(7847), To: rune(7847)},
+ &CodePointRange{From: rune(7849), To: rune(7849)},
+ &CodePointRange{From: rune(7851), To: rune(7851)},
+ &CodePointRange{From: rune(7853), To: rune(7853)},
+ &CodePointRange{From: rune(7855), To: rune(7855)},
+ &CodePointRange{From: rune(7857), To: rune(7857)},
+ &CodePointRange{From: rune(7859), To: rune(7859)},
+ &CodePointRange{From: rune(7861), To: rune(7861)},
+ &CodePointRange{From: rune(7863), To: rune(7863)},
+ &CodePointRange{From: rune(7865), To: rune(7865)},
+ &CodePointRange{From: rune(7867), To: rune(7867)},
+ &CodePointRange{From: rune(7869), To: rune(7869)},
+ &CodePointRange{From: rune(7871), To: rune(7871)},
+ &CodePointRange{From: rune(7873), To: rune(7873)},
+ &CodePointRange{From: rune(7875), To: rune(7875)},
+ &CodePointRange{From: rune(7877), To: rune(7877)},
+ &CodePointRange{From: rune(7879), To: rune(7879)},
+ &CodePointRange{From: rune(7881), To: rune(7881)},
+ &CodePointRange{From: rune(7883), To: rune(7883)},
+ &CodePointRange{From: rune(7885), To: rune(7885)},
+ &CodePointRange{From: rune(7887), To: rune(7887)},
+ &CodePointRange{From: rune(7889), To: rune(7889)},
+ &CodePointRange{From: rune(7891), To: rune(7891)},
+ &CodePointRange{From: rune(7893), To: rune(7893)},
+ &CodePointRange{From: rune(7895), To: rune(7895)},
+ &CodePointRange{From: rune(7897), To: rune(7897)},
+ &CodePointRange{From: rune(7899), To: rune(7899)},
+ &CodePointRange{From: rune(7901), To: rune(7901)},
+ &CodePointRange{From: rune(7903), To: rune(7903)},
+ &CodePointRange{From: rune(7905), To: rune(7905)},
+ &CodePointRange{From: rune(7907), To: rune(7907)},
+ &CodePointRange{From: rune(7909), To: rune(7909)},
+ &CodePointRange{From: rune(7911), To: rune(7911)},
+ &CodePointRange{From: rune(7913), To: rune(7913)},
+ &CodePointRange{From: rune(7915), To: rune(7915)},
+ &CodePointRange{From: rune(7917), To: rune(7917)},
+ &CodePointRange{From: rune(7919), To: rune(7919)},
+ &CodePointRange{From: rune(7921), To: rune(7921)},
+ &CodePointRange{From: rune(7923), To: rune(7923)},
+ &CodePointRange{From: rune(7925), To: rune(7925)},
+ &CodePointRange{From: rune(7927), To: rune(7927)},
+ &CodePointRange{From: rune(7929), To: rune(7929)},
+ &CodePointRange{From: rune(7931), To: rune(7931)},
+ &CodePointRange{From: rune(7933), To: rune(7933)},
+ &CodePointRange{From: rune(7935), To: rune(7943)},
+ &CodePointRange{From: rune(7952), To: rune(7957)},
+ &CodePointRange{From: rune(7968), To: rune(7975)},
+ &CodePointRange{From: rune(7984), To: rune(7991)},
+ &CodePointRange{From: rune(8000), To: rune(8005)},
+ &CodePointRange{From: rune(8016), To: rune(8023)},
+ &CodePointRange{From: rune(8032), To: rune(8039)},
+ &CodePointRange{From: rune(8048), To: rune(8061)},
+ &CodePointRange{From: rune(8064), To: rune(8071)},
+ &CodePointRange{From: rune(8080), To: rune(8087)},
+ &CodePointRange{From: rune(8096), To: rune(8103)},
+ &CodePointRange{From: rune(8112), To: rune(8116)},
+ &CodePointRange{From: rune(8118), To: rune(8119)},
+ &CodePointRange{From: rune(8126), To: rune(8126)},
+ &CodePointRange{From: rune(8130), To: rune(8132)},
+ &CodePointRange{From: rune(8134), To: rune(8135)},
+ &CodePointRange{From: rune(8144), To: rune(8147)},
+ &CodePointRange{From: rune(8150), To: rune(8151)},
+ &CodePointRange{From: rune(8160), To: rune(8167)},
+ &CodePointRange{From: rune(8178), To: rune(8180)},
+ &CodePointRange{From: rune(8182), To: rune(8183)},
+ &CodePointRange{From: rune(8458), To: rune(8458)},
+ &CodePointRange{From: rune(8462), To: rune(8463)},
+ &CodePointRange{From: rune(8467), To: rune(8467)},
+ &CodePointRange{From: rune(8495), To: rune(8495)},
+ &CodePointRange{From: rune(8500), To: rune(8500)},
+ &CodePointRange{From: rune(8505), To: rune(8505)},
+ &CodePointRange{From: rune(8508), To: rune(8509)},
+ &CodePointRange{From: rune(8518), To: rune(8521)},
+ &CodePointRange{From: rune(8526), To: rune(8526)},
+ &CodePointRange{From: rune(8580), To: rune(8580)},
+ &CodePointRange{From: rune(11312), To: rune(11358)},
+ &CodePointRange{From: rune(11361), To: rune(11361)},
+ &CodePointRange{From: rune(11365), To: rune(11366)},
+ &CodePointRange{From: rune(11368), To: rune(11368)},
+ &CodePointRange{From: rune(11370), To: rune(11370)},
+ &CodePointRange{From: rune(11372), To: rune(11372)},
+ &CodePointRange{From: rune(11377), To: rune(11377)},
+ &CodePointRange{From: rune(11379), To: rune(11380)},
+ &CodePointRange{From: rune(11382), To: rune(11387)},
+ &CodePointRange{From: rune(11393), To: rune(11393)},
+ &CodePointRange{From: rune(11395), To: rune(11395)},
+ &CodePointRange{From: rune(11397), To: rune(11397)},
+ &CodePointRange{From: rune(11399), To: rune(11399)},
+ &CodePointRange{From: rune(11401), To: rune(11401)},
+ &CodePointRange{From: rune(11403), To: rune(11403)},
+ &CodePointRange{From: rune(11405), To: rune(11405)},
+ &CodePointRange{From: rune(11407), To: rune(11407)},
+ &CodePointRange{From: rune(11409), To: rune(11409)},
+ &CodePointRange{From: rune(11411), To: rune(11411)},
+ &CodePointRange{From: rune(11413), To: rune(11413)},
+ &CodePointRange{From: rune(11415), To: rune(11415)},
+ &CodePointRange{From: rune(11417), To: rune(11417)},
+ &CodePointRange{From: rune(11419), To: rune(11419)},
+ &CodePointRange{From: rune(11421), To: rune(11421)},
+ &CodePointRange{From: rune(11423), To: rune(11423)},
+ &CodePointRange{From: rune(11425), To: rune(11425)},
+ &CodePointRange{From: rune(11427), To: rune(11427)},
+ &CodePointRange{From: rune(11429), To: rune(11429)},
+ &CodePointRange{From: rune(11431), To: rune(11431)},
+ &CodePointRange{From: rune(11433), To: rune(11433)},
+ &CodePointRange{From: rune(11435), To: rune(11435)},
+ &CodePointRange{From: rune(11437), To: rune(11437)},
+ &CodePointRange{From: rune(11439), To: rune(11439)},
+ &CodePointRange{From: rune(11441), To: rune(11441)},
+ &CodePointRange{From: rune(11443), To: rune(11443)},
+ &CodePointRange{From: rune(11445), To: rune(11445)},
+ &CodePointRange{From: rune(11447), To: rune(11447)},
+ &CodePointRange{From: rune(11449), To: rune(11449)},
+ &CodePointRange{From: rune(11451), To: rune(11451)},
+ &CodePointRange{From: rune(11453), To: rune(11453)},
+ &CodePointRange{From: rune(11455), To: rune(11455)},
+ &CodePointRange{From: rune(11457), To: rune(11457)},
+ &CodePointRange{From: rune(11459), To: rune(11459)},
+ &CodePointRange{From: rune(11461), To: rune(11461)},
+ &CodePointRange{From: rune(11463), To: rune(11463)},
+ &CodePointRange{From: rune(11465), To: rune(11465)},
+ &CodePointRange{From: rune(11467), To: rune(11467)},
+ &CodePointRange{From: rune(11469), To: rune(11469)},
+ &CodePointRange{From: rune(11471), To: rune(11471)},
+ &CodePointRange{From: rune(11473), To: rune(11473)},
+ &CodePointRange{From: rune(11475), To: rune(11475)},
+ &CodePointRange{From: rune(11477), To: rune(11477)},
+ &CodePointRange{From: rune(11479), To: rune(11479)},
+ &CodePointRange{From: rune(11481), To: rune(11481)},
+ &CodePointRange{From: rune(11483), To: rune(11483)},
+ &CodePointRange{From: rune(11485), To: rune(11485)},
+ &CodePointRange{From: rune(11487), To: rune(11487)},
+ &CodePointRange{From: rune(11489), To: rune(11489)},
+ &CodePointRange{From: rune(11491), To: rune(11492)},
+ &CodePointRange{From: rune(11500), To: rune(11500)},
+ &CodePointRange{From: rune(11502), To: rune(11502)},
+ &CodePointRange{From: rune(11507), To: rune(11507)},
+ &CodePointRange{From: rune(11520), To: rune(11557)},
+ &CodePointRange{From: rune(11559), To: rune(11559)},
+ &CodePointRange{From: rune(11565), To: rune(11565)},
+ &CodePointRange{From: rune(42561), To: rune(42561)},
+ &CodePointRange{From: rune(42563), To: rune(42563)},
+ &CodePointRange{From: rune(42565), To: rune(42565)},
+ &CodePointRange{From: rune(42567), To: rune(42567)},
+ &CodePointRange{From: rune(42569), To: rune(42569)},
+ &CodePointRange{From: rune(42571), To: rune(42571)},
+ &CodePointRange{From: rune(42573), To: rune(42573)},
+ &CodePointRange{From: rune(42575), To: rune(42575)},
+ &CodePointRange{From: rune(42577), To: rune(42577)},
+ &CodePointRange{From: rune(42579), To: rune(42579)},
+ &CodePointRange{From: rune(42581), To: rune(42581)},
+ &CodePointRange{From: rune(42583), To: rune(42583)},
+ &CodePointRange{From: rune(42585), To: rune(42585)},
+ &CodePointRange{From: rune(42587), To: rune(42587)},
+ &CodePointRange{From: rune(42589), To: rune(42589)},
+ &CodePointRange{From: rune(42591), To: rune(42591)},
+ &CodePointRange{From: rune(42593), To: rune(42593)},
+ &CodePointRange{From: rune(42595), To: rune(42595)},
+ &CodePointRange{From: rune(42597), To: rune(42597)},
+ &CodePointRange{From: rune(42599), To: rune(42599)},
+ &CodePointRange{From: rune(42601), To: rune(42601)},
+ &CodePointRange{From: rune(42603), To: rune(42603)},
+ &CodePointRange{From: rune(42605), To: rune(42605)},
+ &CodePointRange{From: rune(42625), To: rune(42625)},
+ &CodePointRange{From: rune(42627), To: rune(42627)},
+ &CodePointRange{From: rune(42629), To: rune(42629)},
+ &CodePointRange{From: rune(42631), To: rune(42631)},
+ &CodePointRange{From: rune(42633), To: rune(42633)},
+ &CodePointRange{From: rune(42635), To: rune(42635)},
+ &CodePointRange{From: rune(42637), To: rune(42637)},
+ &CodePointRange{From: rune(42639), To: rune(42639)},
+ &CodePointRange{From: rune(42641), To: rune(42641)},
+ &CodePointRange{From: rune(42643), To: rune(42643)},
+ &CodePointRange{From: rune(42645), To: rune(42645)},
+ &CodePointRange{From: rune(42647), To: rune(42647)},
+ &CodePointRange{From: rune(42649), To: rune(42649)},
+ &CodePointRange{From: rune(42651), To: rune(42651)},
+ &CodePointRange{From: rune(42787), To: rune(42787)},
+ &CodePointRange{From: rune(42789), To: rune(42789)},
+ &CodePointRange{From: rune(42791), To: rune(42791)},
+ &CodePointRange{From: rune(42793), To: rune(42793)},
+ &CodePointRange{From: rune(42795), To: rune(42795)},
+ &CodePointRange{From: rune(42797), To: rune(42797)},
+ &CodePointRange{From: rune(42799), To: rune(42801)},
+ &CodePointRange{From: rune(42803), To: rune(42803)},
+ &CodePointRange{From: rune(42805), To: rune(42805)},
+ &CodePointRange{From: rune(42807), To: rune(42807)},
+ &CodePointRange{From: rune(42809), To: rune(42809)},
+ &CodePointRange{From: rune(42811), To: rune(42811)},
+ &CodePointRange{From: rune(42813), To: rune(42813)},
+ &CodePointRange{From: rune(42815), To: rune(42815)},
+ &CodePointRange{From: rune(42817), To: rune(42817)},
+ &CodePointRange{From: rune(42819), To: rune(42819)},
+ &CodePointRange{From: rune(42821), To: rune(42821)},
+ &CodePointRange{From: rune(42823), To: rune(42823)},
+ &CodePointRange{From: rune(42825), To: rune(42825)},
+ &CodePointRange{From: rune(42827), To: rune(42827)},
+ &CodePointRange{From: rune(42829), To: rune(42829)},
+ &CodePointRange{From: rune(42831), To: rune(42831)},
+ &CodePointRange{From: rune(42833), To: rune(42833)},
+ &CodePointRange{From: rune(42835), To: rune(42835)},
+ &CodePointRange{From: rune(42837), To: rune(42837)},
+ &CodePointRange{From: rune(42839), To: rune(42839)},
+ &CodePointRange{From: rune(42841), To: rune(42841)},
+ &CodePointRange{From: rune(42843), To: rune(42843)},
+ &CodePointRange{From: rune(42845), To: rune(42845)},
+ &CodePointRange{From: rune(42847), To: rune(42847)},
+ &CodePointRange{From: rune(42849), To: rune(42849)},
+ &CodePointRange{From: rune(42851), To: rune(42851)},
+ &CodePointRange{From: rune(42853), To: rune(42853)},
+ &CodePointRange{From: rune(42855), To: rune(42855)},
+ &CodePointRange{From: rune(42857), To: rune(42857)},
+ &CodePointRange{From: rune(42859), To: rune(42859)},
+ &CodePointRange{From: rune(42861), To: rune(42861)},
+ &CodePointRange{From: rune(42863), To: rune(42863)},
+ &CodePointRange{From: rune(42865), To: rune(42872)},
+ &CodePointRange{From: rune(42874), To: rune(42874)},
+ &CodePointRange{From: rune(42876), To: rune(42876)},
+ &CodePointRange{From: rune(42879), To: rune(42879)},
+ &CodePointRange{From: rune(42881), To: rune(42881)},
+ &CodePointRange{From: rune(42883), To: rune(42883)},
+ &CodePointRange{From: rune(42885), To: rune(42885)},
+ &CodePointRange{From: rune(42887), To: rune(42887)},
+ &CodePointRange{From: rune(42892), To: rune(42892)},
+ &CodePointRange{From: rune(42894), To: rune(42894)},
+ &CodePointRange{From: rune(42897), To: rune(42897)},
+ &CodePointRange{From: rune(42899), To: rune(42901)},
+ &CodePointRange{From: rune(42903), To: rune(42903)},
+ &CodePointRange{From: rune(42905), To: rune(42905)},
+ &CodePointRange{From: rune(42907), To: rune(42907)},
+ &CodePointRange{From: rune(42909), To: rune(42909)},
+ &CodePointRange{From: rune(42911), To: rune(42911)},
+ &CodePointRange{From: rune(42913), To: rune(42913)},
+ &CodePointRange{From: rune(42915), To: rune(42915)},
+ &CodePointRange{From: rune(42917), To: rune(42917)},
+ &CodePointRange{From: rune(42919), To: rune(42919)},
+ &CodePointRange{From: rune(42921), To: rune(42921)},
+ &CodePointRange{From: rune(42927), To: rune(42927)},
+ &CodePointRange{From: rune(42933), To: rune(42933)},
+ &CodePointRange{From: rune(42935), To: rune(42935)},
+ &CodePointRange{From: rune(42937), To: rune(42937)},
+ &CodePointRange{From: rune(42939), To: rune(42939)},
+ &CodePointRange{From: rune(42941), To: rune(42941)},
+ &CodePointRange{From: rune(42943), To: rune(42943)},
+ &CodePointRange{From: rune(42947), To: rune(42947)},
+ &CodePointRange{From: rune(42952), To: rune(42952)},
+ &CodePointRange{From: rune(42954), To: rune(42954)},
+ &CodePointRange{From: rune(42998), To: rune(42998)},
+ &CodePointRange{From: rune(43002), To: rune(43002)},
+ &CodePointRange{From: rune(43824), To: rune(43866)},
+ &CodePointRange{From: rune(43872), To: rune(43880)},
+ &CodePointRange{From: rune(43888), To: rune(43967)},
+ &CodePointRange{From: rune(64256), To: rune(64262)},
+ &CodePointRange{From: rune(64275), To: rune(64279)},
+ &CodePointRange{From: rune(65345), To: rune(65370)},
+ &CodePointRange{From: rune(66600), To: rune(66639)},
+ &CodePointRange{From: rune(66776), To: rune(66811)},
+ &CodePointRange{From: rune(68800), To: rune(68850)},
+ &CodePointRange{From: rune(71872), To: rune(71903)},
+ &CodePointRange{From: rune(93792), To: rune(93823)},
+ &CodePointRange{From: rune(119834), To: rune(119859)},
+ &CodePointRange{From: rune(119886), To: rune(119892)},
+ &CodePointRange{From: rune(119894), To: rune(119911)},
+ &CodePointRange{From: rune(119938), To: rune(119963)},
+ &CodePointRange{From: rune(119990), To: rune(119993)},
+ &CodePointRange{From: rune(119995), To: rune(119995)},
+ &CodePointRange{From: rune(119997), To: rune(120003)},
+ &CodePointRange{From: rune(120005), To: rune(120015)},
+ &CodePointRange{From: rune(120042), To: rune(120067)},
+ &CodePointRange{From: rune(120094), To: rune(120119)},
+ &CodePointRange{From: rune(120146), To: rune(120171)},
+ &CodePointRange{From: rune(120198), To: rune(120223)},
+ &CodePointRange{From: rune(120250), To: rune(120275)},
+ &CodePointRange{From: rune(120302), To: rune(120327)},
+ &CodePointRange{From: rune(120354), To: rune(120379)},
+ &CodePointRange{From: rune(120406), To: rune(120431)},
+ &CodePointRange{From: rune(120458), To: rune(120485)},
+ &CodePointRange{From: rune(120514), To: rune(120538)},
+ &CodePointRange{From: rune(120540), To: rune(120545)},
+ &CodePointRange{From: rune(120572), To: rune(120596)},
+ &CodePointRange{From: rune(120598), To: rune(120603)},
+ &CodePointRange{From: rune(120630), To: rune(120654)},
+ &CodePointRange{From: rune(120656), To: rune(120661)},
+ &CodePointRange{From: rune(120688), To: rune(120712)},
+ &CodePointRange{From: rune(120714), To: rune(120719)},
+ &CodePointRange{From: rune(120746), To: rune(120770)},
+ &CodePointRange{From: rune(120772), To: rune(120777)},
+ &CodePointRange{From: rune(120779), To: rune(120779)},
+ &CodePointRange{From: rune(125218), To: rune(125251)},
+ },
+ "lm": {
+ &CodePointRange{From: rune(688), To: rune(705)},
+ &CodePointRange{From: rune(710), To: rune(721)},
+ &CodePointRange{From: rune(736), To: rune(740)},
+ &CodePointRange{From: rune(748), To: rune(748)},
+ &CodePointRange{From: rune(750), To: rune(750)},
+ &CodePointRange{From: rune(884), To: rune(884)},
+ &CodePointRange{From: rune(890), To: rune(890)},
+ &CodePointRange{From: rune(1369), To: rune(1369)},
+ &CodePointRange{From: rune(1600), To: rune(1600)},
+ &CodePointRange{From: rune(1765), To: rune(1766)},
+ &CodePointRange{From: rune(2036), To: rune(2037)},
+ &CodePointRange{From: rune(2042), To: rune(2042)},
+ &CodePointRange{From: rune(2074), To: rune(2074)},
+ &CodePointRange{From: rune(2084), To: rune(2084)},
+ &CodePointRange{From: rune(2088), To: rune(2088)},
+ &CodePointRange{From: rune(2417), To: rune(2417)},
+ &CodePointRange{From: rune(3654), To: rune(3654)},
+ &CodePointRange{From: rune(3782), To: rune(3782)},
+ &CodePointRange{From: rune(4348), To: rune(4348)},
+ &CodePointRange{From: rune(6103), To: rune(6103)},
+ &CodePointRange{From: rune(6211), To: rune(6211)},
+ &CodePointRange{From: rune(6823), To: rune(6823)},
+ &CodePointRange{From: rune(7288), To: rune(7293)},
+ &CodePointRange{From: rune(7468), To: rune(7530)},
+ &CodePointRange{From: rune(7544), To: rune(7544)},
+ &CodePointRange{From: rune(7579), To: rune(7615)},
+ &CodePointRange{From: rune(8305), To: rune(8305)},
+ &CodePointRange{From: rune(8319), To: rune(8319)},
+ &CodePointRange{From: rune(8336), To: rune(8348)},
+ &CodePointRange{From: rune(11388), To: rune(11389)},
+ &CodePointRange{From: rune(11631), To: rune(11631)},
+ &CodePointRange{From: rune(11823), To: rune(11823)},
+ &CodePointRange{From: rune(12293), To: rune(12293)},
+ &CodePointRange{From: rune(12337), To: rune(12341)},
+ &CodePointRange{From: rune(12347), To: rune(12347)},
+ &CodePointRange{From: rune(12445), To: rune(12446)},
+ &CodePointRange{From: rune(12540), To: rune(12542)},
+ &CodePointRange{From: rune(40981), To: rune(40981)},
+ &CodePointRange{From: rune(42232), To: rune(42237)},
+ &CodePointRange{From: rune(42508), To: rune(42508)},
+ &CodePointRange{From: rune(42623), To: rune(42623)},
+ &CodePointRange{From: rune(42652), To: rune(42653)},
+ &CodePointRange{From: rune(42775), To: rune(42783)},
+ &CodePointRange{From: rune(42864), To: rune(42864)},
+ &CodePointRange{From: rune(42888), To: rune(42888)},
+ &CodePointRange{From: rune(43000), To: rune(43001)},
+ &CodePointRange{From: rune(43471), To: rune(43471)},
+ &CodePointRange{From: rune(43494), To: rune(43494)},
+ &CodePointRange{From: rune(43632), To: rune(43632)},
+ &CodePointRange{From: rune(43741), To: rune(43741)},
+ &CodePointRange{From: rune(43763), To: rune(43764)},
+ &CodePointRange{From: rune(43868), To: rune(43871)},
+ &CodePointRange{From: rune(43881), To: rune(43881)},
+ &CodePointRange{From: rune(65392), To: rune(65392)},
+ &CodePointRange{From: rune(65438), To: rune(65439)},
+ &CodePointRange{From: rune(92992), To: rune(92995)},
+ &CodePointRange{From: rune(94099), To: rune(94111)},
+ &CodePointRange{From: rune(94176), To: rune(94177)},
+ &CodePointRange{From: rune(94179), To: rune(94179)},
+ &CodePointRange{From: rune(123191), To: rune(123197)},
+ &CodePointRange{From: rune(125259), To: rune(125259)},
+ },
+ "lo": {
+ &CodePointRange{From: rune(170), To: rune(170)},
+ &CodePointRange{From: rune(186), To: rune(186)},
+ &CodePointRange{From: rune(443), To: rune(443)},
+ &CodePointRange{From: rune(448), To: rune(451)},
+ &CodePointRange{From: rune(660), To: rune(660)},
+ &CodePointRange{From: rune(1488), To: rune(1514)},
+ &CodePointRange{From: rune(1519), To: rune(1522)},
+ &CodePointRange{From: rune(1568), To: rune(1599)},
+ &CodePointRange{From: rune(1601), To: rune(1610)},
+ &CodePointRange{From: rune(1646), To: rune(1647)},
+ &CodePointRange{From: rune(1649), To: rune(1747)},
+ &CodePointRange{From: rune(1749), To: rune(1749)},
+ &CodePointRange{From: rune(1774), To: rune(1775)},
+ &CodePointRange{From: rune(1786), To: rune(1788)},
+ &CodePointRange{From: rune(1791), To: rune(1791)},
+ &CodePointRange{From: rune(1808), To: rune(1808)},
+ &CodePointRange{From: rune(1810), To: rune(1839)},
+ &CodePointRange{From: rune(1869), To: rune(1957)},
+ &CodePointRange{From: rune(1969), To: rune(1969)},
+ &CodePointRange{From: rune(1994), To: rune(2026)},
+ &CodePointRange{From: rune(2048), To: rune(2069)},
+ &CodePointRange{From: rune(2112), To: rune(2136)},
+ &CodePointRange{From: rune(2144), To: rune(2154)},
+ &CodePointRange{From: rune(2208), To: rune(2228)},
+ &CodePointRange{From: rune(2230), To: rune(2247)},
+ &CodePointRange{From: rune(2308), To: rune(2361)},
+ &CodePointRange{From: rune(2365), To: rune(2365)},
+ &CodePointRange{From: rune(2384), To: rune(2384)},
+ &CodePointRange{From: rune(2392), To: rune(2401)},
+ &CodePointRange{From: rune(2418), To: rune(2432)},
+ &CodePointRange{From: rune(2437), To: rune(2444)},
+ &CodePointRange{From: rune(2447), To: rune(2448)},
+ &CodePointRange{From: rune(2451), To: rune(2472)},
+ &CodePointRange{From: rune(2474), To: rune(2480)},
+ &CodePointRange{From: rune(2482), To: rune(2482)},
+ &CodePointRange{From: rune(2486), To: rune(2489)},
+ &CodePointRange{From: rune(2493), To: rune(2493)},
+ &CodePointRange{From: rune(2510), To: rune(2510)},
+ &CodePointRange{From: rune(2524), To: rune(2525)},
+ &CodePointRange{From: rune(2527), To: rune(2529)},
+ &CodePointRange{From: rune(2544), To: rune(2545)},
+ &CodePointRange{From: rune(2556), To: rune(2556)},
+ &CodePointRange{From: rune(2565), To: rune(2570)},
+ &CodePointRange{From: rune(2575), To: rune(2576)},
+ &CodePointRange{From: rune(2579), To: rune(2600)},
+ &CodePointRange{From: rune(2602), To: rune(2608)},
+ &CodePointRange{From: rune(2610), To: rune(2611)},
+ &CodePointRange{From: rune(2613), To: rune(2614)},
+ &CodePointRange{From: rune(2616), To: rune(2617)},
+ &CodePointRange{From: rune(2649), To: rune(2652)},
+ &CodePointRange{From: rune(2654), To: rune(2654)},
+ &CodePointRange{From: rune(2674), To: rune(2676)},
+ &CodePointRange{From: rune(2693), To: rune(2701)},
+ &CodePointRange{From: rune(2703), To: rune(2705)},
+ &CodePointRange{From: rune(2707), To: rune(2728)},
+ &CodePointRange{From: rune(2730), To: rune(2736)},
+ &CodePointRange{From: rune(2738), To: rune(2739)},
+ &CodePointRange{From: rune(2741), To: rune(2745)},
+ &CodePointRange{From: rune(2749), To: rune(2749)},
+ &CodePointRange{From: rune(2768), To: rune(2768)},
+ &CodePointRange{From: rune(2784), To: rune(2785)},
+ &CodePointRange{From: rune(2809), To: rune(2809)},
+ &CodePointRange{From: rune(2821), To: rune(2828)},
+ &CodePointRange{From: rune(2831), To: rune(2832)},
+ &CodePointRange{From: rune(2835), To: rune(2856)},
+ &CodePointRange{From: rune(2858), To: rune(2864)},
+ &CodePointRange{From: rune(2866), To: rune(2867)},
+ &CodePointRange{From: rune(2869), To: rune(2873)},
+ &CodePointRange{From: rune(2877), To: rune(2877)},
+ &CodePointRange{From: rune(2908), To: rune(2909)},
+ &CodePointRange{From: rune(2911), To: rune(2913)},
+ &CodePointRange{From: rune(2929), To: rune(2929)},
+ &CodePointRange{From: rune(2947), To: rune(2947)},
+ &CodePointRange{From: rune(2949), To: rune(2954)},
+ &CodePointRange{From: rune(2958), To: rune(2960)},
+ &CodePointRange{From: rune(2962), To: rune(2965)},
+ &CodePointRange{From: rune(2969), To: rune(2970)},
+ &CodePointRange{From: rune(2972), To: rune(2972)},
+ &CodePointRange{From: rune(2974), To: rune(2975)},
+ &CodePointRange{From: rune(2979), To: rune(2980)},
+ &CodePointRange{From: rune(2984), To: rune(2986)},
+ &CodePointRange{From: rune(2990), To: rune(3001)},
+ &CodePointRange{From: rune(3024), To: rune(3024)},
+ &CodePointRange{From: rune(3077), To: rune(3084)},
+ &CodePointRange{From: rune(3086), To: rune(3088)},
+ &CodePointRange{From: rune(3090), To: rune(3112)},
+ &CodePointRange{From: rune(3114), To: rune(3129)},
+ &CodePointRange{From: rune(3133), To: rune(3133)},
+ &CodePointRange{From: rune(3160), To: rune(3162)},
+ &CodePointRange{From: rune(3168), To: rune(3169)},
+ &CodePointRange{From: rune(3200), To: rune(3200)},
+ &CodePointRange{From: rune(3205), To: rune(3212)},
+ &CodePointRange{From: rune(3214), To: rune(3216)},
+ &CodePointRange{From: rune(3218), To: rune(3240)},
+ &CodePointRange{From: rune(3242), To: rune(3251)},
+ &CodePointRange{From: rune(3253), To: rune(3257)},
+ &CodePointRange{From: rune(3261), To: rune(3261)},
+ &CodePointRange{From: rune(3294), To: rune(3294)},
+ &CodePointRange{From: rune(3296), To: rune(3297)},
+ &CodePointRange{From: rune(3313), To: rune(3314)},
+ &CodePointRange{From: rune(3332), To: rune(3340)},
+ &CodePointRange{From: rune(3342), To: rune(3344)},
+ &CodePointRange{From: rune(3346), To: rune(3386)},
+ &CodePointRange{From: rune(3389), To: rune(3389)},
+ &CodePointRange{From: rune(3406), To: rune(3406)},
+ &CodePointRange{From: rune(3412), To: rune(3414)},
+ &CodePointRange{From: rune(3423), To: rune(3425)},
+ &CodePointRange{From: rune(3450), To: rune(3455)},
+ &CodePointRange{From: rune(3461), To: rune(3478)},
+ &CodePointRange{From: rune(3482), To: rune(3505)},
+ &CodePointRange{From: rune(3507), To: rune(3515)},
+ &CodePointRange{From: rune(3517), To: rune(3517)},
+ &CodePointRange{From: rune(3520), To: rune(3526)},
+ &CodePointRange{From: rune(3585), To: rune(3632)},
+ &CodePointRange{From: rune(3634), To: rune(3635)},
+ &CodePointRange{From: rune(3648), To: rune(3653)},
+ &CodePointRange{From: rune(3713), To: rune(3714)},
+ &CodePointRange{From: rune(3716), To: rune(3716)},
+ &CodePointRange{From: rune(3718), To: rune(3722)},
+ &CodePointRange{From: rune(3724), To: rune(3747)},
+ &CodePointRange{From: rune(3749), To: rune(3749)},
+ &CodePointRange{From: rune(3751), To: rune(3760)},
+ &CodePointRange{From: rune(3762), To: rune(3763)},
+ &CodePointRange{From: rune(3773), To: rune(3773)},
+ &CodePointRange{From: rune(3776), To: rune(3780)},
+ &CodePointRange{From: rune(3804), To: rune(3807)},
+ &CodePointRange{From: rune(3840), To: rune(3840)},
+ &CodePointRange{From: rune(3904), To: rune(3911)},
+ &CodePointRange{From: rune(3913), To: rune(3948)},
+ &CodePointRange{From: rune(3976), To: rune(3980)},
+ &CodePointRange{From: rune(4096), To: rune(4138)},
+ &CodePointRange{From: rune(4159), To: rune(4159)},
+ &CodePointRange{From: rune(4176), To: rune(4181)},
+ &CodePointRange{From: rune(4186), To: rune(4189)},
+ &CodePointRange{From: rune(4193), To: rune(4193)},
+ &CodePointRange{From: rune(4197), To: rune(4198)},
+ &CodePointRange{From: rune(4206), To: rune(4208)},
+ &CodePointRange{From: rune(4213), To: rune(4225)},
+ &CodePointRange{From: rune(4238), To: rune(4238)},
+ &CodePointRange{From: rune(4352), To: rune(4680)},
+ &CodePointRange{From: rune(4682), To: rune(4685)},
+ &CodePointRange{From: rune(4688), To: rune(4694)},
+ &CodePointRange{From: rune(4696), To: rune(4696)},
+ &CodePointRange{From: rune(4698), To: rune(4701)},
+ &CodePointRange{From: rune(4704), To: rune(4744)},
+ &CodePointRange{From: rune(4746), To: rune(4749)},
+ &CodePointRange{From: rune(4752), To: rune(4784)},
+ &CodePointRange{From: rune(4786), To: rune(4789)},
+ &CodePointRange{From: rune(4792), To: rune(4798)},
+ &CodePointRange{From: rune(4800), To: rune(4800)},
+ &CodePointRange{From: rune(4802), To: rune(4805)},
+ &CodePointRange{From: rune(4808), To: rune(4822)},
+ &CodePointRange{From: rune(4824), To: rune(4880)},
+ &CodePointRange{From: rune(4882), To: rune(4885)},
+ &CodePointRange{From: rune(4888), To: rune(4954)},
+ &CodePointRange{From: rune(4992), To: rune(5007)},
+ &CodePointRange{From: rune(5121), To: rune(5740)},
+ &CodePointRange{From: rune(5743), To: rune(5759)},
+ &CodePointRange{From: rune(5761), To: rune(5786)},
+ &CodePointRange{From: rune(5792), To: rune(5866)},
+ &CodePointRange{From: rune(5873), To: rune(5880)},
+ &CodePointRange{From: rune(5888), To: rune(5900)},
+ &CodePointRange{From: rune(5902), To: rune(5905)},
+ &CodePointRange{From: rune(5920), To: rune(5937)},
+ &CodePointRange{From: rune(5952), To: rune(5969)},
+ &CodePointRange{From: rune(5984), To: rune(5996)},
+ &CodePointRange{From: rune(5998), To: rune(6000)},
+ &CodePointRange{From: rune(6016), To: rune(6067)},
+ &CodePointRange{From: rune(6108), To: rune(6108)},
+ &CodePointRange{From: rune(6176), To: rune(6210)},
+ &CodePointRange{From: rune(6212), To: rune(6264)},
+ &CodePointRange{From: rune(6272), To: rune(6276)},
+ &CodePointRange{From: rune(6279), To: rune(6312)},
+ &CodePointRange{From: rune(6314), To: rune(6314)},
+ &CodePointRange{From: rune(6320), To: rune(6389)},
+ &CodePointRange{From: rune(6400), To: rune(6430)},
+ &CodePointRange{From: rune(6480), To: rune(6509)},
+ &CodePointRange{From: rune(6512), To: rune(6516)},
+ &CodePointRange{From: rune(6528), To: rune(6571)},
+ &CodePointRange{From: rune(6576), To: rune(6601)},
+ &CodePointRange{From: rune(6656), To: rune(6678)},
+ &CodePointRange{From: rune(6688), To: rune(6740)},
+ &CodePointRange{From: rune(6917), To: rune(6963)},
+ &CodePointRange{From: rune(6981), To: rune(6987)},
+ &CodePointRange{From: rune(7043), To: rune(7072)},
+ &CodePointRange{From: rune(7086), To: rune(7087)},
+ &CodePointRange{From: rune(7098), To: rune(7141)},
+ &CodePointRange{From: rune(7168), To: rune(7203)},
+ &CodePointRange{From: rune(7245), To: rune(7247)},
+ &CodePointRange{From: rune(7258), To: rune(7287)},
+ &CodePointRange{From: rune(7401), To: rune(7404)},
+ &CodePointRange{From: rune(7406), To: rune(7411)},
+ &CodePointRange{From: rune(7413), To: rune(7414)},
+ &CodePointRange{From: rune(7418), To: rune(7418)},
+ &CodePointRange{From: rune(8501), To: rune(8504)},
+ &CodePointRange{From: rune(11568), To: rune(11623)},
+ &CodePointRange{From: rune(11648), To: rune(11670)},
+ &CodePointRange{From: rune(11680), To: rune(11686)},
+ &CodePointRange{From: rune(11688), To: rune(11694)},
+ &CodePointRange{From: rune(11696), To: rune(11702)},
+ &CodePointRange{From: rune(11704), To: rune(11710)},
+ &CodePointRange{From: rune(11712), To: rune(11718)},
+ &CodePointRange{From: rune(11720), To: rune(11726)},
+ &CodePointRange{From: rune(11728), To: rune(11734)},
+ &CodePointRange{From: rune(11736), To: rune(11742)},
+ &CodePointRange{From: rune(12294), To: rune(12294)},
+ &CodePointRange{From: rune(12348), To: rune(12348)},
+ &CodePointRange{From: rune(12353), To: rune(12438)},
+ &CodePointRange{From: rune(12447), To: rune(12447)},
+ &CodePointRange{From: rune(12449), To: rune(12538)},
+ &CodePointRange{From: rune(12543), To: rune(12543)},
+ &CodePointRange{From: rune(12549), To: rune(12591)},
+ &CodePointRange{From: rune(12593), To: rune(12686)},
+ &CodePointRange{From: rune(12704), To: rune(12735)},
+ &CodePointRange{From: rune(12784), To: rune(12799)},
+ &CodePointRange{From: rune(13312), To: rune(13312)},
+ &CodePointRange{From: rune(19903), To: rune(19903)},
+ &CodePointRange{From: rune(19968), To: rune(19968)},
+ &CodePointRange{From: rune(40956), To: rune(40956)},
+ &CodePointRange{From: rune(40960), To: rune(40980)},
+ &CodePointRange{From: rune(40982), To: rune(42124)},
+ &CodePointRange{From: rune(42192), To: rune(42231)},
+ &CodePointRange{From: rune(42240), To: rune(42507)},
+ &CodePointRange{From: rune(42512), To: rune(42527)},
+ &CodePointRange{From: rune(42538), To: rune(42539)},
+ &CodePointRange{From: rune(42606), To: rune(42606)},
+ &CodePointRange{From: rune(42656), To: rune(42725)},
+ &CodePointRange{From: rune(42895), To: rune(42895)},
+ &CodePointRange{From: rune(42999), To: rune(42999)},
+ &CodePointRange{From: rune(43003), To: rune(43009)},
+ &CodePointRange{From: rune(43011), To: rune(43013)},
+ &CodePointRange{From: rune(43015), To: rune(43018)},
+ &CodePointRange{From: rune(43020), To: rune(43042)},
+ &CodePointRange{From: rune(43072), To: rune(43123)},
+ &CodePointRange{From: rune(43138), To: rune(43187)},
+ &CodePointRange{From: rune(43250), To: rune(43255)},
+ &CodePointRange{From: rune(43259), To: rune(43259)},
+ &CodePointRange{From: rune(43261), To: rune(43262)},
+ &CodePointRange{From: rune(43274), To: rune(43301)},
+ &CodePointRange{From: rune(43312), To: rune(43334)},
+ &CodePointRange{From: rune(43360), To: rune(43388)},
+ &CodePointRange{From: rune(43396), To: rune(43442)},
+ &CodePointRange{From: rune(43488), To: rune(43492)},
+ &CodePointRange{From: rune(43495), To: rune(43503)},
+ &CodePointRange{From: rune(43514), To: rune(43518)},
+ &CodePointRange{From: rune(43520), To: rune(43560)},
+ &CodePointRange{From: rune(43584), To: rune(43586)},
+ &CodePointRange{From: rune(43588), To: rune(43595)},
+ &CodePointRange{From: rune(43616), To: rune(43631)},
+ &CodePointRange{From: rune(43633), To: rune(43638)},
+ &CodePointRange{From: rune(43642), To: rune(43642)},
+ &CodePointRange{From: rune(43646), To: rune(43695)},
+ &CodePointRange{From: rune(43697), To: rune(43697)},
+ &CodePointRange{From: rune(43701), To: rune(43702)},
+ &CodePointRange{From: rune(43705), To: rune(43709)},
+ &CodePointRange{From: rune(43712), To: rune(43712)},
+ &CodePointRange{From: rune(43714), To: rune(43714)},
+ &CodePointRange{From: rune(43739), To: rune(43740)},
+ &CodePointRange{From: rune(43744), To: rune(43754)},
+ &CodePointRange{From: rune(43762), To: rune(43762)},
+ &CodePointRange{From: rune(43777), To: rune(43782)},
+ &CodePointRange{From: rune(43785), To: rune(43790)},
+ &CodePointRange{From: rune(43793), To: rune(43798)},
+ &CodePointRange{From: rune(43808), To: rune(43814)},
+ &CodePointRange{From: rune(43816), To: rune(43822)},
+ &CodePointRange{From: rune(43968), To: rune(44002)},
+ &CodePointRange{From: rune(44032), To: rune(44032)},
+ &CodePointRange{From: rune(55203), To: rune(55203)},
+ &CodePointRange{From: rune(55216), To: rune(55238)},
+ &CodePointRange{From: rune(55243), To: rune(55291)},
+ &CodePointRange{From: rune(63744), To: rune(64109)},
+ &CodePointRange{From: rune(64112), To: rune(64217)},
+ &CodePointRange{From: rune(64285), To: rune(64285)},
+ &CodePointRange{From: rune(64287), To: rune(64296)},
+ &CodePointRange{From: rune(64298), To: rune(64310)},
+ &CodePointRange{From: rune(64312), To: rune(64316)},
+ &CodePointRange{From: rune(64318), To: rune(64318)},
+ &CodePointRange{From: rune(64320), To: rune(64321)},
+ &CodePointRange{From: rune(64323), To: rune(64324)},
+ &CodePointRange{From: rune(64326), To: rune(64433)},
+ &CodePointRange{From: rune(64467), To: rune(64829)},
+ &CodePointRange{From: rune(64848), To: rune(64911)},
+ &CodePointRange{From: rune(64914), To: rune(64967)},
+ &CodePointRange{From: rune(65008), To: rune(65019)},
+ &CodePointRange{From: rune(65136), To: rune(65140)},
+ &CodePointRange{From: rune(65142), To: rune(65276)},
+ &CodePointRange{From: rune(65382), To: rune(65391)},
+ &CodePointRange{From: rune(65393), To: rune(65437)},
+ &CodePointRange{From: rune(65440), To: rune(65470)},
+ &CodePointRange{From: rune(65474), To: rune(65479)},
+ &CodePointRange{From: rune(65482), To: rune(65487)},
+ &CodePointRange{From: rune(65490), To: rune(65495)},
+ &CodePointRange{From: rune(65498), To: rune(65500)},
+ &CodePointRange{From: rune(65536), To: rune(65547)},
+ &CodePointRange{From: rune(65549), To: rune(65574)},
+ &CodePointRange{From: rune(65576), To: rune(65594)},
+ &CodePointRange{From: rune(65596), To: rune(65597)},
+ &CodePointRange{From: rune(65599), To: rune(65613)},
+ &CodePointRange{From: rune(65616), To: rune(65629)},
+ &CodePointRange{From: rune(65664), To: rune(65786)},
+ &CodePointRange{From: rune(66176), To: rune(66204)},
+ &CodePointRange{From: rune(66208), To: rune(66256)},
+ &CodePointRange{From: rune(66304), To: rune(66335)},
+ &CodePointRange{From: rune(66349), To: rune(66368)},
+ &CodePointRange{From: rune(66370), To: rune(66377)},
+ &CodePointRange{From: rune(66384), To: rune(66421)},
+ &CodePointRange{From: rune(66432), To: rune(66461)},
+ &CodePointRange{From: rune(66464), To: rune(66499)},
+ &CodePointRange{From: rune(66504), To: rune(66511)},
+ &CodePointRange{From: rune(66640), To: rune(66717)},
+ &CodePointRange{From: rune(66816), To: rune(66855)},
+ &CodePointRange{From: rune(66864), To: rune(66915)},
+ &CodePointRange{From: rune(67072), To: rune(67382)},
+ &CodePointRange{From: rune(67392), To: rune(67413)},
+ &CodePointRange{From: rune(67424), To: rune(67431)},
+ &CodePointRange{From: rune(67584), To: rune(67589)},
+ &CodePointRange{From: rune(67592), To: rune(67592)},
+ &CodePointRange{From: rune(67594), To: rune(67637)},
+ &CodePointRange{From: rune(67639), To: rune(67640)},
+ &CodePointRange{From: rune(67644), To: rune(67644)},
+ &CodePointRange{From: rune(67647), To: rune(67669)},
+ &CodePointRange{From: rune(67680), To: rune(67702)},
+ &CodePointRange{From: rune(67712), To: rune(67742)},
+ &CodePointRange{From: rune(67808), To: rune(67826)},
+ &CodePointRange{From: rune(67828), To: rune(67829)},
+ &CodePointRange{From: rune(67840), To: rune(67861)},
+ &CodePointRange{From: rune(67872), To: rune(67897)},
+ &CodePointRange{From: rune(67968), To: rune(68023)},
+ &CodePointRange{From: rune(68030), To: rune(68031)},
+ &CodePointRange{From: rune(68096), To: rune(68096)},
+ &CodePointRange{From: rune(68112), To: rune(68115)},
+ &CodePointRange{From: rune(68117), To: rune(68119)},
+ &CodePointRange{From: rune(68121), To: rune(68149)},
+ &CodePointRange{From: rune(68192), To: rune(68220)},
+ &CodePointRange{From: rune(68224), To: rune(68252)},
+ &CodePointRange{From: rune(68288), To: rune(68295)},
+ &CodePointRange{From: rune(68297), To: rune(68324)},
+ &CodePointRange{From: rune(68352), To: rune(68405)},
+ &CodePointRange{From: rune(68416), To: rune(68437)},
+ &CodePointRange{From: rune(68448), To: rune(68466)},
+ &CodePointRange{From: rune(68480), To: rune(68497)},
+ &CodePointRange{From: rune(68608), To: rune(68680)},
+ &CodePointRange{From: rune(68864), To: rune(68899)},
+ &CodePointRange{From: rune(69248), To: rune(69289)},
+ &CodePointRange{From: rune(69296), To: rune(69297)},
+ &CodePointRange{From: rune(69376), To: rune(69404)},
+ &CodePointRange{From: rune(69415), To: rune(69415)},
+ &CodePointRange{From: rune(69424), To: rune(69445)},
+ &CodePointRange{From: rune(69552), To: rune(69572)},
+ &CodePointRange{From: rune(69600), To: rune(69622)},
+ &CodePointRange{From: rune(69635), To: rune(69687)},
+ &CodePointRange{From: rune(69763), To: rune(69807)},
+ &CodePointRange{From: rune(69840), To: rune(69864)},
+ &CodePointRange{From: rune(69891), To: rune(69926)},
+ &CodePointRange{From: rune(69956), To: rune(69956)},
+ &CodePointRange{From: rune(69959), To: rune(69959)},
+ &CodePointRange{From: rune(69968), To: rune(70002)},
+ &CodePointRange{From: rune(70006), To: rune(70006)},
+ &CodePointRange{From: rune(70019), To: rune(70066)},
+ &CodePointRange{From: rune(70081), To: rune(70084)},
+ &CodePointRange{From: rune(70106), To: rune(70106)},
+ &CodePointRange{From: rune(70108), To: rune(70108)},
+ &CodePointRange{From: rune(70144), To: rune(70161)},
+ &CodePointRange{From: rune(70163), To: rune(70187)},
+ &CodePointRange{From: rune(70272), To: rune(70278)},
+ &CodePointRange{From: rune(70280), To: rune(70280)},
+ &CodePointRange{From: rune(70282), To: rune(70285)},
+ &CodePointRange{From: rune(70287), To: rune(70301)},
+ &CodePointRange{From: rune(70303), To: rune(70312)},
+ &CodePointRange{From: rune(70320), To: rune(70366)},
+ &CodePointRange{From: rune(70405), To: rune(70412)},
+ &CodePointRange{From: rune(70415), To: rune(70416)},
+ &CodePointRange{From: rune(70419), To: rune(70440)},
+ &CodePointRange{From: rune(70442), To: rune(70448)},
+ &CodePointRange{From: rune(70450), To: rune(70451)},
+ &CodePointRange{From: rune(70453), To: rune(70457)},
+ &CodePointRange{From: rune(70461), To: rune(70461)},
+ &CodePointRange{From: rune(70480), To: rune(70480)},
+ &CodePointRange{From: rune(70493), To: rune(70497)},
+ &CodePointRange{From: rune(70656), To: rune(70708)},
+ &CodePointRange{From: rune(70727), To: rune(70730)},
+ &CodePointRange{From: rune(70751), To: rune(70753)},
+ &CodePointRange{From: rune(70784), To: rune(70831)},
+ &CodePointRange{From: rune(70852), To: rune(70853)},
+ &CodePointRange{From: rune(70855), To: rune(70855)},
+ &CodePointRange{From: rune(71040), To: rune(71086)},
+ &CodePointRange{From: rune(71128), To: rune(71131)},
+ &CodePointRange{From: rune(71168), To: rune(71215)},
+ &CodePointRange{From: rune(71236), To: rune(71236)},
+ &CodePointRange{From: rune(71296), To: rune(71338)},
+ &CodePointRange{From: rune(71352), To: rune(71352)},
+ &CodePointRange{From: rune(71424), To: rune(71450)},
+ &CodePointRange{From: rune(71680), To: rune(71723)},
+ &CodePointRange{From: rune(71935), To: rune(71942)},
+ &CodePointRange{From: rune(71945), To: rune(71945)},
+ &CodePointRange{From: rune(71948), To: rune(71955)},
+ &CodePointRange{From: rune(71957), To: rune(71958)},
+ &CodePointRange{From: rune(71960), To: rune(71983)},
+ &CodePointRange{From: rune(71999), To: rune(71999)},
+ &CodePointRange{From: rune(72001), To: rune(72001)},
+ &CodePointRange{From: rune(72096), To: rune(72103)},
+ &CodePointRange{From: rune(72106), To: rune(72144)},
+ &CodePointRange{From: rune(72161), To: rune(72161)},
+ &CodePointRange{From: rune(72163), To: rune(72163)},
+ &CodePointRange{From: rune(72192), To: rune(72192)},
+ &CodePointRange{From: rune(72203), To: rune(72242)},
+ &CodePointRange{From: rune(72250), To: rune(72250)},
+ &CodePointRange{From: rune(72272), To: rune(72272)},
+ &CodePointRange{From: rune(72284), To: rune(72329)},
+ &CodePointRange{From: rune(72349), To: rune(72349)},
+ &CodePointRange{From: rune(72384), To: rune(72440)},
+ &CodePointRange{From: rune(72704), To: rune(72712)},
+ &CodePointRange{From: rune(72714), To: rune(72750)},
+ &CodePointRange{From: rune(72768), To: rune(72768)},
+ &CodePointRange{From: rune(72818), To: rune(72847)},
+ &CodePointRange{From: rune(72960), To: rune(72966)},
+ &CodePointRange{From: rune(72968), To: rune(72969)},
+ &CodePointRange{From: rune(72971), To: rune(73008)},
+ &CodePointRange{From: rune(73030), To: rune(73030)},
+ &CodePointRange{From: rune(73056), To: rune(73061)},
+ &CodePointRange{From: rune(73063), To: rune(73064)},
+ &CodePointRange{From: rune(73066), To: rune(73097)},
+ &CodePointRange{From: rune(73112), To: rune(73112)},
+ &CodePointRange{From: rune(73440), To: rune(73458)},
+ &CodePointRange{From: rune(73648), To: rune(73648)},
+ &CodePointRange{From: rune(73728), To: rune(74649)},
+ &CodePointRange{From: rune(74880), To: rune(75075)},
+ &CodePointRange{From: rune(77824), To: rune(78894)},
+ &CodePointRange{From: rune(82944), To: rune(83526)},
+ &CodePointRange{From: rune(92160), To: rune(92728)},
+ &CodePointRange{From: rune(92736), To: rune(92766)},
+ &CodePointRange{From: rune(92880), To: rune(92909)},
+ &CodePointRange{From: rune(92928), To: rune(92975)},
+ &CodePointRange{From: rune(93027), To: rune(93047)},
+ &CodePointRange{From: rune(93053), To: rune(93071)},
+ &CodePointRange{From: rune(93952), To: rune(94026)},
+ &CodePointRange{From: rune(94032), To: rune(94032)},
+ &CodePointRange{From: rune(94208), To: rune(94208)},
+ &CodePointRange{From: rune(100343), To: rune(100343)},
+ &CodePointRange{From: rune(100352), To: rune(101589)},
+ &CodePointRange{From: rune(101632), To: rune(101632)},
+ &CodePointRange{From: rune(101640), To: rune(101640)},
+ &CodePointRange{From: rune(110592), To: rune(110878)},
+ &CodePointRange{From: rune(110928), To: rune(110930)},
+ &CodePointRange{From: rune(110948), To: rune(110951)},
+ &CodePointRange{From: rune(110960), To: rune(111355)},
+ &CodePointRange{From: rune(113664), To: rune(113770)},
+ &CodePointRange{From: rune(113776), To: rune(113788)},
+ &CodePointRange{From: rune(113792), To: rune(113800)},
+ &CodePointRange{From: rune(113808), To: rune(113817)},
+ &CodePointRange{From: rune(123136), To: rune(123180)},
+ &CodePointRange{From: rune(123214), To: rune(123214)},
+ &CodePointRange{From: rune(123584), To: rune(123627)},
+ &CodePointRange{From: rune(124928), To: rune(125124)},
+ &CodePointRange{From: rune(126464), To: rune(126467)},
+ &CodePointRange{From: rune(126469), To: rune(126495)},
+ &CodePointRange{From: rune(126497), To: rune(126498)},
+ &CodePointRange{From: rune(126500), To: rune(126500)},
+ &CodePointRange{From: rune(126503), To: rune(126503)},
+ &CodePointRange{From: rune(126505), To: rune(126514)},
+ &CodePointRange{From: rune(126516), To: rune(126519)},
+ &CodePointRange{From: rune(126521), To: rune(126521)},
+ &CodePointRange{From: rune(126523), To: rune(126523)},
+ &CodePointRange{From: rune(126530), To: rune(126530)},
+ &CodePointRange{From: rune(126535), To: rune(126535)},
+ &CodePointRange{From: rune(126537), To: rune(126537)},
+ &CodePointRange{From: rune(126539), To: rune(126539)},
+ &CodePointRange{From: rune(126541), To: rune(126543)},
+ &CodePointRange{From: rune(126545), To: rune(126546)},
+ &CodePointRange{From: rune(126548), To: rune(126548)},
+ &CodePointRange{From: rune(126551), To: rune(126551)},
+ &CodePointRange{From: rune(126553), To: rune(126553)},
+ &CodePointRange{From: rune(126555), To: rune(126555)},
+ &CodePointRange{From: rune(126557), To: rune(126557)},
+ &CodePointRange{From: rune(126559), To: rune(126559)},
+ &CodePointRange{From: rune(126561), To: rune(126562)},
+ &CodePointRange{From: rune(126564), To: rune(126564)},
+ &CodePointRange{From: rune(126567), To: rune(126570)},
+ &CodePointRange{From: rune(126572), To: rune(126578)},
+ &CodePointRange{From: rune(126580), To: rune(126583)},
+ &CodePointRange{From: rune(126585), To: rune(126588)},
+ &CodePointRange{From: rune(126590), To: rune(126590)},
+ &CodePointRange{From: rune(126592), To: rune(126601)},
+ &CodePointRange{From: rune(126603), To: rune(126619)},
+ &CodePointRange{From: rune(126625), To: rune(126627)},
+ &CodePointRange{From: rune(126629), To: rune(126633)},
+ &CodePointRange{From: rune(126635), To: rune(126651)},
+ &CodePointRange{From: rune(131072), To: rune(131072)},
+ &CodePointRange{From: rune(173789), To: rune(173789)},
+ &CodePointRange{From: rune(173824), To: rune(173824)},
+ &CodePointRange{From: rune(177972), To: rune(177972)},
+ &CodePointRange{From: rune(177984), To: rune(177984)},
+ &CodePointRange{From: rune(178205), To: rune(178205)},
+ &CodePointRange{From: rune(178208), To: rune(178208)},
+ &CodePointRange{From: rune(183969), To: rune(183969)},
+ &CodePointRange{From: rune(183984), To: rune(183984)},
+ &CodePointRange{From: rune(191456), To: rune(191456)},
+ &CodePointRange{From: rune(194560), To: rune(195101)},
+ &CodePointRange{From: rune(196608), To: rune(196608)},
+ &CodePointRange{From: rune(201546), To: rune(201546)},
+ },
+ "lt": {
+ &CodePointRange{From: rune(453), To: rune(453)},
+ &CodePointRange{From: rune(456), To: rune(456)},
+ &CodePointRange{From: rune(459), To: rune(459)},
+ &CodePointRange{From: rune(498), To: rune(498)},
+ &CodePointRange{From: rune(8072), To: rune(8079)},
+ &CodePointRange{From: rune(8088), To: rune(8095)},
+ &CodePointRange{From: rune(8104), To: rune(8111)},
+ &CodePointRange{From: rune(8124), To: rune(8124)},
+ &CodePointRange{From: rune(8140), To: rune(8140)},
+ &CodePointRange{From: rune(8188), To: rune(8188)},
+ },
+ "lu": {
+ &CodePointRange{From: rune(65), To: rune(90)},
+ &CodePointRange{From: rune(192), To: rune(214)},
+ &CodePointRange{From: rune(216), To: rune(222)},
+ &CodePointRange{From: rune(256), To: rune(256)},
+ &CodePointRange{From: rune(258), To: rune(258)},
+ &CodePointRange{From: rune(260), To: rune(260)},
+ &CodePointRange{From: rune(262), To: rune(262)},
+ &CodePointRange{From: rune(264), To: rune(264)},
+ &CodePointRange{From: rune(266), To: rune(266)},
+ &CodePointRange{From: rune(268), To: rune(268)},
+ &CodePointRange{From: rune(270), To: rune(270)},
+ &CodePointRange{From: rune(272), To: rune(272)},
+ &CodePointRange{From: rune(274), To: rune(274)},
+ &CodePointRange{From: rune(276), To: rune(276)},
+ &CodePointRange{From: rune(278), To: rune(278)},
+ &CodePointRange{From: rune(280), To: rune(280)},
+ &CodePointRange{From: rune(282), To: rune(282)},
+ &CodePointRange{From: rune(284), To: rune(284)},
+ &CodePointRange{From: rune(286), To: rune(286)},
+ &CodePointRange{From: rune(288), To: rune(288)},
+ &CodePointRange{From: rune(290), To: rune(290)},
+ &CodePointRange{From: rune(292), To: rune(292)},
+ &CodePointRange{From: rune(294), To: rune(294)},
+ &CodePointRange{From: rune(296), To: rune(296)},
+ &CodePointRange{From: rune(298), To: rune(298)},
+ &CodePointRange{From: rune(300), To: rune(300)},
+ &CodePointRange{From: rune(302), To: rune(302)},
+ &CodePointRange{From: rune(304), To: rune(304)},
+ &CodePointRange{From: rune(306), To: rune(306)},
+ &CodePointRange{From: rune(308), To: rune(308)},
+ &CodePointRange{From: rune(310), To: rune(310)},
+ &CodePointRange{From: rune(313), To: rune(313)},
+ &CodePointRange{From: rune(315), To: rune(315)},
+ &CodePointRange{From: rune(317), To: rune(317)},
+ &CodePointRange{From: rune(319), To: rune(319)},
+ &CodePointRange{From: rune(321), To: rune(321)},
+ &CodePointRange{From: rune(323), To: rune(323)},
+ &CodePointRange{From: rune(325), To: rune(325)},
+ &CodePointRange{From: rune(327), To: rune(327)},
+ &CodePointRange{From: rune(330), To: rune(330)},
+ &CodePointRange{From: rune(332), To: rune(332)},
+ &CodePointRange{From: rune(334), To: rune(334)},
+ &CodePointRange{From: rune(336), To: rune(336)},
+ &CodePointRange{From: rune(338), To: rune(338)},
+ &CodePointRange{From: rune(340), To: rune(340)},
+ &CodePointRange{From: rune(342), To: rune(342)},
+ &CodePointRange{From: rune(344), To: rune(344)},
+ &CodePointRange{From: rune(346), To: rune(346)},
+ &CodePointRange{From: rune(348), To: rune(348)},
+ &CodePointRange{From: rune(350), To: rune(350)},
+ &CodePointRange{From: rune(352), To: rune(352)},
+ &CodePointRange{From: rune(354), To: rune(354)},
+ &CodePointRange{From: rune(356), To: rune(356)},
+ &CodePointRange{From: rune(358), To: rune(358)},
+ &CodePointRange{From: rune(360), To: rune(360)},
+ &CodePointRange{From: rune(362), To: rune(362)},
+ &CodePointRange{From: rune(364), To: rune(364)},
+ &CodePointRange{From: rune(366), To: rune(366)},
+ &CodePointRange{From: rune(368), To: rune(368)},
+ &CodePointRange{From: rune(370), To: rune(370)},
+ &CodePointRange{From: rune(372), To: rune(372)},
+ &CodePointRange{From: rune(374), To: rune(374)},
+ &CodePointRange{From: rune(376), To: rune(377)},
+ &CodePointRange{From: rune(379), To: rune(379)},
+ &CodePointRange{From: rune(381), To: rune(381)},
+ &CodePointRange{From: rune(385), To: rune(386)},
+ &CodePointRange{From: rune(388), To: rune(388)},
+ &CodePointRange{From: rune(390), To: rune(391)},
+ &CodePointRange{From: rune(393), To: rune(395)},
+ &CodePointRange{From: rune(398), To: rune(401)},
+ &CodePointRange{From: rune(403), To: rune(404)},
+ &CodePointRange{From: rune(406), To: rune(408)},
+ &CodePointRange{From: rune(412), To: rune(413)},
+ &CodePointRange{From: rune(415), To: rune(416)},
+ &CodePointRange{From: rune(418), To: rune(418)},
+ &CodePointRange{From: rune(420), To: rune(420)},
+ &CodePointRange{From: rune(422), To: rune(423)},
+ &CodePointRange{From: rune(425), To: rune(425)},
+ &CodePointRange{From: rune(428), To: rune(428)},
+ &CodePointRange{From: rune(430), To: rune(431)},
+ &CodePointRange{From: rune(433), To: rune(435)},
+ &CodePointRange{From: rune(437), To: rune(437)},
+ &CodePointRange{From: rune(439), To: rune(440)},
+ &CodePointRange{From: rune(444), To: rune(444)},
+ &CodePointRange{From: rune(452), To: rune(452)},
+ &CodePointRange{From: rune(455), To: rune(455)},
+ &CodePointRange{From: rune(458), To: rune(458)},
+ &CodePointRange{From: rune(461), To: rune(461)},
+ &CodePointRange{From: rune(463), To: rune(463)},
+ &CodePointRange{From: rune(465), To: rune(465)},
+ &CodePointRange{From: rune(467), To: rune(467)},
+ &CodePointRange{From: rune(469), To: rune(469)},
+ &CodePointRange{From: rune(471), To: rune(471)},
+ &CodePointRange{From: rune(473), To: rune(473)},
+ &CodePointRange{From: rune(475), To: rune(475)},
+ &CodePointRange{From: rune(478), To: rune(478)},
+ &CodePointRange{From: rune(480), To: rune(480)},
+ &CodePointRange{From: rune(482), To: rune(482)},
+ &CodePointRange{From: rune(484), To: rune(484)},
+ &CodePointRange{From: rune(486), To: rune(486)},
+ &CodePointRange{From: rune(488), To: rune(488)},
+ &CodePointRange{From: rune(490), To: rune(490)},
+ &CodePointRange{From: rune(492), To: rune(492)},
+ &CodePointRange{From: rune(494), To: rune(494)},
+ &CodePointRange{From: rune(497), To: rune(497)},
+ &CodePointRange{From: rune(500), To: rune(500)},
+ &CodePointRange{From: rune(502), To: rune(504)},
+ &CodePointRange{From: rune(506), To: rune(506)},
+ &CodePointRange{From: rune(508), To: rune(508)},
+ &CodePointRange{From: rune(510), To: rune(510)},
+ &CodePointRange{From: rune(512), To: rune(512)},
+ &CodePointRange{From: rune(514), To: rune(514)},
+ &CodePointRange{From: rune(516), To: rune(516)},
+ &CodePointRange{From: rune(518), To: rune(518)},
+ &CodePointRange{From: rune(520), To: rune(520)},
+ &CodePointRange{From: rune(522), To: rune(522)},
+ &CodePointRange{From: rune(524), To: rune(524)},
+ &CodePointRange{From: rune(526), To: rune(526)},
+ &CodePointRange{From: rune(528), To: rune(528)},
+ &CodePointRange{From: rune(530), To: rune(530)},
+ &CodePointRange{From: rune(532), To: rune(532)},
+ &CodePointRange{From: rune(534), To: rune(534)},
+ &CodePointRange{From: rune(536), To: rune(536)},
+ &CodePointRange{From: rune(538), To: rune(538)},
+ &CodePointRange{From: rune(540), To: rune(540)},
+ &CodePointRange{From: rune(542), To: rune(542)},
+ &CodePointRange{From: rune(544), To: rune(544)},
+ &CodePointRange{From: rune(546), To: rune(546)},
+ &CodePointRange{From: rune(548), To: rune(548)},
+ &CodePointRange{From: rune(550), To: rune(550)},
+ &CodePointRange{From: rune(552), To: rune(552)},
+ &CodePointRange{From: rune(554), To: rune(554)},
+ &CodePointRange{From: rune(556), To: rune(556)},
+ &CodePointRange{From: rune(558), To: rune(558)},
+ &CodePointRange{From: rune(560), To: rune(560)},
+ &CodePointRange{From: rune(562), To: rune(562)},
+ &CodePointRange{From: rune(570), To: rune(571)},
+ &CodePointRange{From: rune(573), To: rune(574)},
+ &CodePointRange{From: rune(577), To: rune(577)},
+ &CodePointRange{From: rune(579), To: rune(582)},
+ &CodePointRange{From: rune(584), To: rune(584)},
+ &CodePointRange{From: rune(586), To: rune(586)},
+ &CodePointRange{From: rune(588), To: rune(588)},
+ &CodePointRange{From: rune(590), To: rune(590)},
+ &CodePointRange{From: rune(880), To: rune(880)},
+ &CodePointRange{From: rune(882), To: rune(882)},
+ &CodePointRange{From: rune(886), To: rune(886)},
+ &CodePointRange{From: rune(895), To: rune(895)},
+ &CodePointRange{From: rune(902), To: rune(902)},
+ &CodePointRange{From: rune(904), To: rune(906)},
+ &CodePointRange{From: rune(908), To: rune(908)},
+ &CodePointRange{From: rune(910), To: rune(911)},
+ &CodePointRange{From: rune(913), To: rune(929)},
+ &CodePointRange{From: rune(931), To: rune(939)},
+ &CodePointRange{From: rune(975), To: rune(975)},
+ &CodePointRange{From: rune(978), To: rune(980)},
+ &CodePointRange{From: rune(984), To: rune(984)},
+ &CodePointRange{From: rune(986), To: rune(986)},
+ &CodePointRange{From: rune(988), To: rune(988)},
+ &CodePointRange{From: rune(990), To: rune(990)},
+ &CodePointRange{From: rune(992), To: rune(992)},
+ &CodePointRange{From: rune(994), To: rune(994)},
+ &CodePointRange{From: rune(996), To: rune(996)},
+ &CodePointRange{From: rune(998), To: rune(998)},
+ &CodePointRange{From: rune(1000), To: rune(1000)},
+ &CodePointRange{From: rune(1002), To: rune(1002)},
+ &CodePointRange{From: rune(1004), To: rune(1004)},
+ &CodePointRange{From: rune(1006), To: rune(1006)},
+ &CodePointRange{From: rune(1012), To: rune(1012)},
+ &CodePointRange{From: rune(1015), To: rune(1015)},
+ &CodePointRange{From: rune(1017), To: rune(1018)},
+ &CodePointRange{From: rune(1021), To: rune(1071)},
+ &CodePointRange{From: rune(1120), To: rune(1120)},
+ &CodePointRange{From: rune(1122), To: rune(1122)},
+ &CodePointRange{From: rune(1124), To: rune(1124)},
+ &CodePointRange{From: rune(1126), To: rune(1126)},
+ &CodePointRange{From: rune(1128), To: rune(1128)},
+ &CodePointRange{From: rune(1130), To: rune(1130)},
+ &CodePointRange{From: rune(1132), To: rune(1132)},
+ &CodePointRange{From: rune(1134), To: rune(1134)},
+ &CodePointRange{From: rune(1136), To: rune(1136)},
+ &CodePointRange{From: rune(1138), To: rune(1138)},
+ &CodePointRange{From: rune(1140), To: rune(1140)},
+ &CodePointRange{From: rune(1142), To: rune(1142)},
+ &CodePointRange{From: rune(1144), To: rune(1144)},
+ &CodePointRange{From: rune(1146), To: rune(1146)},
+ &CodePointRange{From: rune(1148), To: rune(1148)},
+ &CodePointRange{From: rune(1150), To: rune(1150)},
+ &CodePointRange{From: rune(1152), To: rune(1152)},
+ &CodePointRange{From: rune(1162), To: rune(1162)},
+ &CodePointRange{From: rune(1164), To: rune(1164)},
+ &CodePointRange{From: rune(1166), To: rune(1166)},
+ &CodePointRange{From: rune(1168), To: rune(1168)},
+ &CodePointRange{From: rune(1170), To: rune(1170)},
+ &CodePointRange{From: rune(1172), To: rune(1172)},
+ &CodePointRange{From: rune(1174), To: rune(1174)},
+ &CodePointRange{From: rune(1176), To: rune(1176)},
+ &CodePointRange{From: rune(1178), To: rune(1178)},
+ &CodePointRange{From: rune(1180), To: rune(1180)},
+ &CodePointRange{From: rune(1182), To: rune(1182)},
+ &CodePointRange{From: rune(1184), To: rune(1184)},
+ &CodePointRange{From: rune(1186), To: rune(1186)},
+ &CodePointRange{From: rune(1188), To: rune(1188)},
+ &CodePointRange{From: rune(1190), To: rune(1190)},
+ &CodePointRange{From: rune(1192), To: rune(1192)},
+ &CodePointRange{From: rune(1194), To: rune(1194)},
+ &CodePointRange{From: rune(1196), To: rune(1196)},
+ &CodePointRange{From: rune(1198), To: rune(1198)},
+ &CodePointRange{From: rune(1200), To: rune(1200)},
+ &CodePointRange{From: rune(1202), To: rune(1202)},
+ &CodePointRange{From: rune(1204), To: rune(1204)},
+ &CodePointRange{From: rune(1206), To: rune(1206)},
+ &CodePointRange{From: rune(1208), To: rune(1208)},
+ &CodePointRange{From: rune(1210), To: rune(1210)},
+ &CodePointRange{From: rune(1212), To: rune(1212)},
+ &CodePointRange{From: rune(1214), To: rune(1214)},
+ &CodePointRange{From: rune(1216), To: rune(1217)},
+ &CodePointRange{From: rune(1219), To: rune(1219)},
+ &CodePointRange{From: rune(1221), To: rune(1221)},
+ &CodePointRange{From: rune(1223), To: rune(1223)},
+ &CodePointRange{From: rune(1225), To: rune(1225)},
+ &CodePointRange{From: rune(1227), To: rune(1227)},
+ &CodePointRange{From: rune(1229), To: rune(1229)},
+ &CodePointRange{From: rune(1232), To: rune(1232)},
+ &CodePointRange{From: rune(1234), To: rune(1234)},
+ &CodePointRange{From: rune(1236), To: rune(1236)},
+ &CodePointRange{From: rune(1238), To: rune(1238)},
+ &CodePointRange{From: rune(1240), To: rune(1240)},
+ &CodePointRange{From: rune(1242), To: rune(1242)},
+ &CodePointRange{From: rune(1244), To: rune(1244)},
+ &CodePointRange{From: rune(1246), To: rune(1246)},
+ &CodePointRange{From: rune(1248), To: rune(1248)},
+ &CodePointRange{From: rune(1250), To: rune(1250)},
+ &CodePointRange{From: rune(1252), To: rune(1252)},
+ &CodePointRange{From: rune(1254), To: rune(1254)},
+ &CodePointRange{From: rune(1256), To: rune(1256)},
+ &CodePointRange{From: rune(1258), To: rune(1258)},
+ &CodePointRange{From: rune(1260), To: rune(1260)},
+ &CodePointRange{From: rune(1262), To: rune(1262)},
+ &CodePointRange{From: rune(1264), To: rune(1264)},
+ &CodePointRange{From: rune(1266), To: rune(1266)},
+ &CodePointRange{From: rune(1268), To: rune(1268)},
+ &CodePointRange{From: rune(1270), To: rune(1270)},
+ &CodePointRange{From: rune(1272), To: rune(1272)},
+ &CodePointRange{From: rune(1274), To: rune(1274)},
+ &CodePointRange{From: rune(1276), To: rune(1276)},
+ &CodePointRange{From: rune(1278), To: rune(1278)},
+ &CodePointRange{From: rune(1280), To: rune(1280)},
+ &CodePointRange{From: rune(1282), To: rune(1282)},
+ &CodePointRange{From: rune(1284), To: rune(1284)},
+ &CodePointRange{From: rune(1286), To: rune(1286)},
+ &CodePointRange{From: rune(1288), To: rune(1288)},
+ &CodePointRange{From: rune(1290), To: rune(1290)},
+ &CodePointRange{From: rune(1292), To: rune(1292)},
+ &CodePointRange{From: rune(1294), To: rune(1294)},
+ &CodePointRange{From: rune(1296), To: rune(1296)},
+ &CodePointRange{From: rune(1298), To: rune(1298)},
+ &CodePointRange{From: rune(1300), To: rune(1300)},
+ &CodePointRange{From: rune(1302), To: rune(1302)},
+ &CodePointRange{From: rune(1304), To: rune(1304)},
+ &CodePointRange{From: rune(1306), To: rune(1306)},
+ &CodePointRange{From: rune(1308), To: rune(1308)},
+ &CodePointRange{From: rune(1310), To: rune(1310)},
+ &CodePointRange{From: rune(1312), To: rune(1312)},
+ &CodePointRange{From: rune(1314), To: rune(1314)},
+ &CodePointRange{From: rune(1316), To: rune(1316)},
+ &CodePointRange{From: rune(1318), To: rune(1318)},
+ &CodePointRange{From: rune(1320), To: rune(1320)},
+ &CodePointRange{From: rune(1322), To: rune(1322)},
+ &CodePointRange{From: rune(1324), To: rune(1324)},
+ &CodePointRange{From: rune(1326), To: rune(1326)},
+ &CodePointRange{From: rune(1329), To: rune(1366)},
+ &CodePointRange{From: rune(4256), To: rune(4293)},
+ &CodePointRange{From: rune(4295), To: rune(4295)},
+ &CodePointRange{From: rune(4301), To: rune(4301)},
+ &CodePointRange{From: rune(5024), To: rune(5109)},
+ &CodePointRange{From: rune(7312), To: rune(7354)},
+ &CodePointRange{From: rune(7357), To: rune(7359)},
+ &CodePointRange{From: rune(7680), To: rune(7680)},
+ &CodePointRange{From: rune(7682), To: rune(7682)},
+ &CodePointRange{From: rune(7684), To: rune(7684)},
+ &CodePointRange{From: rune(7686), To: rune(7686)},
+ &CodePointRange{From: rune(7688), To: rune(7688)},
+ &CodePointRange{From: rune(7690), To: rune(7690)},
+ &CodePointRange{From: rune(7692), To: rune(7692)},
+ &CodePointRange{From: rune(7694), To: rune(7694)},
+ &CodePointRange{From: rune(7696), To: rune(7696)},
+ &CodePointRange{From: rune(7698), To: rune(7698)},
+ &CodePointRange{From: rune(7700), To: rune(7700)},
+ &CodePointRange{From: rune(7702), To: rune(7702)},
+ &CodePointRange{From: rune(7704), To: rune(7704)},
+ &CodePointRange{From: rune(7706), To: rune(7706)},
+ &CodePointRange{From: rune(7708), To: rune(7708)},
+ &CodePointRange{From: rune(7710), To: rune(7710)},
+ &CodePointRange{From: rune(7712), To: rune(7712)},
+ &CodePointRange{From: rune(7714), To: rune(7714)},
+ &CodePointRange{From: rune(7716), To: rune(7716)},
+ &CodePointRange{From: rune(7718), To: rune(7718)},
+ &CodePointRange{From: rune(7720), To: rune(7720)},
+ &CodePointRange{From: rune(7722), To: rune(7722)},
+ &CodePointRange{From: rune(7724), To: rune(7724)},
+ &CodePointRange{From: rune(7726), To: rune(7726)},
+ &CodePointRange{From: rune(7728), To: rune(7728)},
+ &CodePointRange{From: rune(7730), To: rune(7730)},
+ &CodePointRange{From: rune(7732), To: rune(7732)},
+ &CodePointRange{From: rune(7734), To: rune(7734)},
+ &CodePointRange{From: rune(7736), To: rune(7736)},
+ &CodePointRange{From: rune(7738), To: rune(7738)},
+ &CodePointRange{From: rune(7740), To: rune(7740)},
+ &CodePointRange{From: rune(7742), To: rune(7742)},
+ &CodePointRange{From: rune(7744), To: rune(7744)},
+ &CodePointRange{From: rune(7746), To: rune(7746)},
+ &CodePointRange{From: rune(7748), To: rune(7748)},
+ &CodePointRange{From: rune(7750), To: rune(7750)},
+ &CodePointRange{From: rune(7752), To: rune(7752)},
+ &CodePointRange{From: rune(7754), To: rune(7754)},
+ &CodePointRange{From: rune(7756), To: rune(7756)},
+ &CodePointRange{From: rune(7758), To: rune(7758)},
+ &CodePointRange{From: rune(7760), To: rune(7760)},
+ &CodePointRange{From: rune(7762), To: rune(7762)},
+ &CodePointRange{From: rune(7764), To: rune(7764)},
+ &CodePointRange{From: rune(7766), To: rune(7766)},
+ &CodePointRange{From: rune(7768), To: rune(7768)},
+ &CodePointRange{From: rune(7770), To: rune(7770)},
+ &CodePointRange{From: rune(7772), To: rune(7772)},
+ &CodePointRange{From: rune(7774), To: rune(7774)},
+ &CodePointRange{From: rune(7776), To: rune(7776)},
+ &CodePointRange{From: rune(7778), To: rune(7778)},
+ &CodePointRange{From: rune(7780), To: rune(7780)},
+ &CodePointRange{From: rune(7782), To: rune(7782)},
+ &CodePointRange{From: rune(7784), To: rune(7784)},
+ &CodePointRange{From: rune(7786), To: rune(7786)},
+ &CodePointRange{From: rune(7788), To: rune(7788)},
+ &CodePointRange{From: rune(7790), To: rune(7790)},
+ &CodePointRange{From: rune(7792), To: rune(7792)},
+ &CodePointRange{From: rune(7794), To: rune(7794)},
+ &CodePointRange{From: rune(7796), To: rune(7796)},
+ &CodePointRange{From: rune(7798), To: rune(7798)},
+ &CodePointRange{From: rune(7800), To: rune(7800)},
+ &CodePointRange{From: rune(7802), To: rune(7802)},
+ &CodePointRange{From: rune(7804), To: rune(7804)},
+ &CodePointRange{From: rune(7806), To: rune(7806)},
+ &CodePointRange{From: rune(7808), To: rune(7808)},
+ &CodePointRange{From: rune(7810), To: rune(7810)},
+ &CodePointRange{From: rune(7812), To: rune(7812)},
+ &CodePointRange{From: rune(7814), To: rune(7814)},
+ &CodePointRange{From: rune(7816), To: rune(7816)},
+ &CodePointRange{From: rune(7818), To: rune(7818)},
+ &CodePointRange{From: rune(7820), To: rune(7820)},
+ &CodePointRange{From: rune(7822), To: rune(7822)},
+ &CodePointRange{From: rune(7824), To: rune(7824)},
+ &CodePointRange{From: rune(7826), To: rune(7826)},
+ &CodePointRange{From: rune(7828), To: rune(7828)},
+ &CodePointRange{From: rune(7838), To: rune(7838)},
+ &CodePointRange{From: rune(7840), To: rune(7840)},
+ &CodePointRange{From: rune(7842), To: rune(7842)},
+ &CodePointRange{From: rune(7844), To: rune(7844)},
+ &CodePointRange{From: rune(7846), To: rune(7846)},
+ &CodePointRange{From: rune(7848), To: rune(7848)},
+ &CodePointRange{From: rune(7850), To: rune(7850)},
+ &CodePointRange{From: rune(7852), To: rune(7852)},
+ &CodePointRange{From: rune(7854), To: rune(7854)},
+ &CodePointRange{From: rune(7856), To: rune(7856)},
+ &CodePointRange{From: rune(7858), To: rune(7858)},
+ &CodePointRange{From: rune(7860), To: rune(7860)},
+ &CodePointRange{From: rune(7862), To: rune(7862)},
+ &CodePointRange{From: rune(7864), To: rune(7864)},
+ &CodePointRange{From: rune(7866), To: rune(7866)},
+ &CodePointRange{From: rune(7868), To: rune(7868)},
+ &CodePointRange{From: rune(7870), To: rune(7870)},
+ &CodePointRange{From: rune(7872), To: rune(7872)},
+ &CodePointRange{From: rune(7874), To: rune(7874)},
+ &CodePointRange{From: rune(7876), To: rune(7876)},
+ &CodePointRange{From: rune(7878), To: rune(7878)},
+ &CodePointRange{From: rune(7880), To: rune(7880)},
+ &CodePointRange{From: rune(7882), To: rune(7882)},
+ &CodePointRange{From: rune(7884), To: rune(7884)},
+ &CodePointRange{From: rune(7886), To: rune(7886)},
+ &CodePointRange{From: rune(7888), To: rune(7888)},
+ &CodePointRange{From: rune(7890), To: rune(7890)},
+ &CodePointRange{From: rune(7892), To: rune(7892)},
+ &CodePointRange{From: rune(7894), To: rune(7894)},
+ &CodePointRange{From: rune(7896), To: rune(7896)},
+ &CodePointRange{From: rune(7898), To: rune(7898)},
+ &CodePointRange{From: rune(7900), To: rune(7900)},
+ &CodePointRange{From: rune(7902), To: rune(7902)},
+ &CodePointRange{From: rune(7904), To: rune(7904)},
+ &CodePointRange{From: rune(7906), To: rune(7906)},
+ &CodePointRange{From: rune(7908), To: rune(7908)},
+ &CodePointRange{From: rune(7910), To: rune(7910)},
+ &CodePointRange{From: rune(7912), To: rune(7912)},
+ &CodePointRange{From: rune(7914), To: rune(7914)},
+ &CodePointRange{From: rune(7916), To: rune(7916)},
+ &CodePointRange{From: rune(7918), To: rune(7918)},
+ &CodePointRange{From: rune(7920), To: rune(7920)},
+ &CodePointRange{From: rune(7922), To: rune(7922)},
+ &CodePointRange{From: rune(7924), To: rune(7924)},
+ &CodePointRange{From: rune(7926), To: rune(7926)},
+ &CodePointRange{From: rune(7928), To: rune(7928)},
+ &CodePointRange{From: rune(7930), To: rune(7930)},
+ &CodePointRange{From: rune(7932), To: rune(7932)},
+ &CodePointRange{From: rune(7934), To: rune(7934)},
+ &CodePointRange{From: rune(7944), To: rune(7951)},
+ &CodePointRange{From: rune(7960), To: rune(7965)},
+ &CodePointRange{From: rune(7976), To: rune(7983)},
+ &CodePointRange{From: rune(7992), To: rune(7999)},
+ &CodePointRange{From: rune(8008), To: rune(8013)},
+ &CodePointRange{From: rune(8025), To: rune(8025)},
+ &CodePointRange{From: rune(8027), To: rune(8027)},
+ &CodePointRange{From: rune(8029), To: rune(8029)},
+ &CodePointRange{From: rune(8031), To: rune(8031)},
+ &CodePointRange{From: rune(8040), To: rune(8047)},
+ &CodePointRange{From: rune(8120), To: rune(8123)},
+ &CodePointRange{From: rune(8136), To: rune(8139)},
+ &CodePointRange{From: rune(8152), To: rune(8155)},
+ &CodePointRange{From: rune(8168), To: rune(8172)},
+ &CodePointRange{From: rune(8184), To: rune(8187)},
+ &CodePointRange{From: rune(8450), To: rune(8450)},
+ &CodePointRange{From: rune(8455), To: rune(8455)},
+ &CodePointRange{From: rune(8459), To: rune(8461)},
+ &CodePointRange{From: rune(8464), To: rune(8466)},
+ &CodePointRange{From: rune(8469), To: rune(8469)},
+ &CodePointRange{From: rune(8473), To: rune(8477)},
+ &CodePointRange{From: rune(8484), To: rune(8484)},
+ &CodePointRange{From: rune(8486), To: rune(8486)},
+ &CodePointRange{From: rune(8488), To: rune(8488)},
+ &CodePointRange{From: rune(8490), To: rune(8493)},
+ &CodePointRange{From: rune(8496), To: rune(8499)},
+ &CodePointRange{From: rune(8510), To: rune(8511)},
+ &CodePointRange{From: rune(8517), To: rune(8517)},
+ &CodePointRange{From: rune(8579), To: rune(8579)},
+ &CodePointRange{From: rune(11264), To: rune(11310)},
+ &CodePointRange{From: rune(11360), To: rune(11360)},
+ &CodePointRange{From: rune(11362), To: rune(11364)},
+ &CodePointRange{From: rune(11367), To: rune(11367)},
+ &CodePointRange{From: rune(11369), To: rune(11369)},
+ &CodePointRange{From: rune(11371), To: rune(11371)},
+ &CodePointRange{From: rune(11373), To: rune(11376)},
+ &CodePointRange{From: rune(11378), To: rune(11378)},
+ &CodePointRange{From: rune(11381), To: rune(11381)},
+ &CodePointRange{From: rune(11390), To: rune(11392)},
+ &CodePointRange{From: rune(11394), To: rune(11394)},
+ &CodePointRange{From: rune(11396), To: rune(11396)},
+ &CodePointRange{From: rune(11398), To: rune(11398)},
+ &CodePointRange{From: rune(11400), To: rune(11400)},
+ &CodePointRange{From: rune(11402), To: rune(11402)},
+ &CodePointRange{From: rune(11404), To: rune(11404)},
+ &CodePointRange{From: rune(11406), To: rune(11406)},
+ &CodePointRange{From: rune(11408), To: rune(11408)},
+ &CodePointRange{From: rune(11410), To: rune(11410)},
+ &CodePointRange{From: rune(11412), To: rune(11412)},
+ &CodePointRange{From: rune(11414), To: rune(11414)},
+ &CodePointRange{From: rune(11416), To: rune(11416)},
+ &CodePointRange{From: rune(11418), To: rune(11418)},
+ &CodePointRange{From: rune(11420), To: rune(11420)},
+ &CodePointRange{From: rune(11422), To: rune(11422)},
+ &CodePointRange{From: rune(11424), To: rune(11424)},
+ &CodePointRange{From: rune(11426), To: rune(11426)},
+ &CodePointRange{From: rune(11428), To: rune(11428)},
+ &CodePointRange{From: rune(11430), To: rune(11430)},
+ &CodePointRange{From: rune(11432), To: rune(11432)},
+ &CodePointRange{From: rune(11434), To: rune(11434)},
+ &CodePointRange{From: rune(11436), To: rune(11436)},
+ &CodePointRange{From: rune(11438), To: rune(11438)},
+ &CodePointRange{From: rune(11440), To: rune(11440)},
+ &CodePointRange{From: rune(11442), To: rune(11442)},
+ &CodePointRange{From: rune(11444), To: rune(11444)},
+ &CodePointRange{From: rune(11446), To: rune(11446)},
+ &CodePointRange{From: rune(11448), To: rune(11448)},
+ &CodePointRange{From: rune(11450), To: rune(11450)},
+ &CodePointRange{From: rune(11452), To: rune(11452)},
+ &CodePointRange{From: rune(11454), To: rune(11454)},
+ &CodePointRange{From: rune(11456), To: rune(11456)},
+ &CodePointRange{From: rune(11458), To: rune(11458)},
+ &CodePointRange{From: rune(11460), To: rune(11460)},
+ &CodePointRange{From: rune(11462), To: rune(11462)},
+ &CodePointRange{From: rune(11464), To: rune(11464)},
+ &CodePointRange{From: rune(11466), To: rune(11466)},
+ &CodePointRange{From: rune(11468), To: rune(11468)},
+ &CodePointRange{From: rune(11470), To: rune(11470)},
+ &CodePointRange{From: rune(11472), To: rune(11472)},
+ &CodePointRange{From: rune(11474), To: rune(11474)},
+ &CodePointRange{From: rune(11476), To: rune(11476)},
+ &CodePointRange{From: rune(11478), To: rune(11478)},
+ &CodePointRange{From: rune(11480), To: rune(11480)},
+ &CodePointRange{From: rune(11482), To: rune(11482)},
+ &CodePointRange{From: rune(11484), To: rune(11484)},
+ &CodePointRange{From: rune(11486), To: rune(11486)},
+ &CodePointRange{From: rune(11488), To: rune(11488)},
+ &CodePointRange{From: rune(11490), To: rune(11490)},
+ &CodePointRange{From: rune(11499), To: rune(11499)},
+ &CodePointRange{From: rune(11501), To: rune(11501)},
+ &CodePointRange{From: rune(11506), To: rune(11506)},
+ &CodePointRange{From: rune(42560), To: rune(42560)},
+ &CodePointRange{From: rune(42562), To: rune(42562)},
+ &CodePointRange{From: rune(42564), To: rune(42564)},
+ &CodePointRange{From: rune(42566), To: rune(42566)},
+ &CodePointRange{From: rune(42568), To: rune(42568)},
+ &CodePointRange{From: rune(42570), To: rune(42570)},
+ &CodePointRange{From: rune(42572), To: rune(42572)},
+ &CodePointRange{From: rune(42574), To: rune(42574)},
+ &CodePointRange{From: rune(42576), To: rune(42576)},
+ &CodePointRange{From: rune(42578), To: rune(42578)},
+ &CodePointRange{From: rune(42580), To: rune(42580)},
+ &CodePointRange{From: rune(42582), To: rune(42582)},
+ &CodePointRange{From: rune(42584), To: rune(42584)},
+ &CodePointRange{From: rune(42586), To: rune(42586)},
+ &CodePointRange{From: rune(42588), To: rune(42588)},
+ &CodePointRange{From: rune(42590), To: rune(42590)},
+ &CodePointRange{From: rune(42592), To: rune(42592)},
+ &CodePointRange{From: rune(42594), To: rune(42594)},
+ &CodePointRange{From: rune(42596), To: rune(42596)},
+ &CodePointRange{From: rune(42598), To: rune(42598)},
+ &CodePointRange{From: rune(42600), To: rune(42600)},
+ &CodePointRange{From: rune(42602), To: rune(42602)},
+ &CodePointRange{From: rune(42604), To: rune(42604)},
+ &CodePointRange{From: rune(42624), To: rune(42624)},
+ &CodePointRange{From: rune(42626), To: rune(42626)},
+ &CodePointRange{From: rune(42628), To: rune(42628)},
+ &CodePointRange{From: rune(42630), To: rune(42630)},
+ &CodePointRange{From: rune(42632), To: rune(42632)},
+ &CodePointRange{From: rune(42634), To: rune(42634)},
+ &CodePointRange{From: rune(42636), To: rune(42636)},
+ &CodePointRange{From: rune(42638), To: rune(42638)},
+ &CodePointRange{From: rune(42640), To: rune(42640)},
+ &CodePointRange{From: rune(42642), To: rune(42642)},
+ &CodePointRange{From: rune(42644), To: rune(42644)},
+ &CodePointRange{From: rune(42646), To: rune(42646)},
+ &CodePointRange{From: rune(42648), To: rune(42648)},
+ &CodePointRange{From: rune(42650), To: rune(42650)},
+ &CodePointRange{From: rune(42786), To: rune(42786)},
+ &CodePointRange{From: rune(42788), To: rune(42788)},
+ &CodePointRange{From: rune(42790), To: rune(42790)},
+ &CodePointRange{From: rune(42792), To: rune(42792)},
+ &CodePointRange{From: rune(42794), To: rune(42794)},
+ &CodePointRange{From: rune(42796), To: rune(42796)},
+ &CodePointRange{From: rune(42798), To: rune(42798)},
+ &CodePointRange{From: rune(42802), To: rune(42802)},
+ &CodePointRange{From: rune(42804), To: rune(42804)},
+ &CodePointRange{From: rune(42806), To: rune(42806)},
+ &CodePointRange{From: rune(42808), To: rune(42808)},
+ &CodePointRange{From: rune(42810), To: rune(42810)},
+ &CodePointRange{From: rune(42812), To: rune(42812)},
+ &CodePointRange{From: rune(42814), To: rune(42814)},
+ &CodePointRange{From: rune(42816), To: rune(42816)},
+ &CodePointRange{From: rune(42818), To: rune(42818)},
+ &CodePointRange{From: rune(42820), To: rune(42820)},
+ &CodePointRange{From: rune(42822), To: rune(42822)},
+ &CodePointRange{From: rune(42824), To: rune(42824)},
+ &CodePointRange{From: rune(42826), To: rune(42826)},
+ &CodePointRange{From: rune(42828), To: rune(42828)},
+ &CodePointRange{From: rune(42830), To: rune(42830)},
+ &CodePointRange{From: rune(42832), To: rune(42832)},
+ &CodePointRange{From: rune(42834), To: rune(42834)},
+ &CodePointRange{From: rune(42836), To: rune(42836)},
+ &CodePointRange{From: rune(42838), To: rune(42838)},
+ &CodePointRange{From: rune(42840), To: rune(42840)},
+ &CodePointRange{From: rune(42842), To: rune(42842)},
+ &CodePointRange{From: rune(42844), To: rune(42844)},
+ &CodePointRange{From: rune(42846), To: rune(42846)},
+ &CodePointRange{From: rune(42848), To: rune(42848)},
+ &CodePointRange{From: rune(42850), To: rune(42850)},
+ &CodePointRange{From: rune(42852), To: rune(42852)},
+ &CodePointRange{From: rune(42854), To: rune(42854)},
+ &CodePointRange{From: rune(42856), To: rune(42856)},
+ &CodePointRange{From: rune(42858), To: rune(42858)},
+ &CodePointRange{From: rune(42860), To: rune(42860)},
+ &CodePointRange{From: rune(42862), To: rune(42862)},
+ &CodePointRange{From: rune(42873), To: rune(42873)},
+ &CodePointRange{From: rune(42875), To: rune(42875)},
+ &CodePointRange{From: rune(42877), To: rune(42878)},
+ &CodePointRange{From: rune(42880), To: rune(42880)},
+ &CodePointRange{From: rune(42882), To: rune(42882)},
+ &CodePointRange{From: rune(42884), To: rune(42884)},
+ &CodePointRange{From: rune(42886), To: rune(42886)},
+ &CodePointRange{From: rune(42891), To: rune(42891)},
+ &CodePointRange{From: rune(42893), To: rune(42893)},
+ &CodePointRange{From: rune(42896), To: rune(42896)},
+ &CodePointRange{From: rune(42898), To: rune(42898)},
+ &CodePointRange{From: rune(42902), To: rune(42902)},
+ &CodePointRange{From: rune(42904), To: rune(42904)},
+ &CodePointRange{From: rune(42906), To: rune(42906)},
+ &CodePointRange{From: rune(42908), To: rune(42908)},
+ &CodePointRange{From: rune(42910), To: rune(42910)},
+ &CodePointRange{From: rune(42912), To: rune(42912)},
+ &CodePointRange{From: rune(42914), To: rune(42914)},
+ &CodePointRange{From: rune(42916), To: rune(42916)},
+ &CodePointRange{From: rune(42918), To: rune(42918)},
+ &CodePointRange{From: rune(42920), To: rune(42920)},
+ &CodePointRange{From: rune(42922), To: rune(42926)},
+ &CodePointRange{From: rune(42928), To: rune(42932)},
+ &CodePointRange{From: rune(42934), To: rune(42934)},
+ &CodePointRange{From: rune(42936), To: rune(42936)},
+ &CodePointRange{From: rune(42938), To: rune(42938)},
+ &CodePointRange{From: rune(42940), To: rune(42940)},
+ &CodePointRange{From: rune(42942), To: rune(42942)},
+ &CodePointRange{From: rune(42946), To: rune(42946)},
+ &CodePointRange{From: rune(42948), To: rune(42951)},
+ &CodePointRange{From: rune(42953), To: rune(42953)},
+ &CodePointRange{From: rune(42997), To: rune(42997)},
+ &CodePointRange{From: rune(65313), To: rune(65338)},
+ &CodePointRange{From: rune(66560), To: rune(66599)},
+ &CodePointRange{From: rune(66736), To: rune(66771)},
+ &CodePointRange{From: rune(68736), To: rune(68786)},
+ &CodePointRange{From: rune(71840), To: rune(71871)},
+ &CodePointRange{From: rune(93760), To: rune(93791)},
+ &CodePointRange{From: rune(119808), To: rune(119833)},
+ &CodePointRange{From: rune(119860), To: rune(119885)},
+ &CodePointRange{From: rune(119912), To: rune(119937)},
+ &CodePointRange{From: rune(119964), To: rune(119964)},
+ &CodePointRange{From: rune(119966), To: rune(119967)},
+ &CodePointRange{From: rune(119970), To: rune(119970)},
+ &CodePointRange{From: rune(119973), To: rune(119974)},
+ &CodePointRange{From: rune(119977), To: rune(119980)},
+ &CodePointRange{From: rune(119982), To: rune(119989)},
+ &CodePointRange{From: rune(120016), To: rune(120041)},
+ &CodePointRange{From: rune(120068), To: rune(120069)},
+ &CodePointRange{From: rune(120071), To: rune(120074)},
+ &CodePointRange{From: rune(120077), To: rune(120084)},
+ &CodePointRange{From: rune(120086), To: rune(120092)},
+ &CodePointRange{From: rune(120120), To: rune(120121)},
+ &CodePointRange{From: rune(120123), To: rune(120126)},
+ &CodePointRange{From: rune(120128), To: rune(120132)},
+ &CodePointRange{From: rune(120134), To: rune(120134)},
+ &CodePointRange{From: rune(120138), To: rune(120144)},
+ &CodePointRange{From: rune(120172), To: rune(120197)},
+ &CodePointRange{From: rune(120224), To: rune(120249)},
+ &CodePointRange{From: rune(120276), To: rune(120301)},
+ &CodePointRange{From: rune(120328), To: rune(120353)},
+ &CodePointRange{From: rune(120380), To: rune(120405)},
+ &CodePointRange{From: rune(120432), To: rune(120457)},
+ &CodePointRange{From: rune(120488), To: rune(120512)},
+ &CodePointRange{From: rune(120546), To: rune(120570)},
+ &CodePointRange{From: rune(120604), To: rune(120628)},
+ &CodePointRange{From: rune(120662), To: rune(120686)},
+ &CodePointRange{From: rune(120720), To: rune(120744)},
+ &CodePointRange{From: rune(120778), To: rune(120778)},
+ &CodePointRange{From: rune(125184), To: rune(125217)},
+ },
+ "mc": {
+ &CodePointRange{From: rune(2307), To: rune(2307)},
+ &CodePointRange{From: rune(2363), To: rune(2363)},
+ &CodePointRange{From: rune(2366), To: rune(2368)},
+ &CodePointRange{From: rune(2377), To: rune(2380)},
+ &CodePointRange{From: rune(2382), To: rune(2383)},
+ &CodePointRange{From: rune(2434), To: rune(2435)},
+ &CodePointRange{From: rune(2494), To: rune(2496)},
+ &CodePointRange{From: rune(2503), To: rune(2504)},
+ &CodePointRange{From: rune(2507), To: rune(2508)},
+ &CodePointRange{From: rune(2519), To: rune(2519)},
+ &CodePointRange{From: rune(2563), To: rune(2563)},
+ &CodePointRange{From: rune(2622), To: rune(2624)},
+ &CodePointRange{From: rune(2691), To: rune(2691)},
+ &CodePointRange{From: rune(2750), To: rune(2752)},
+ &CodePointRange{From: rune(2761), To: rune(2761)},
+ &CodePointRange{From: rune(2763), To: rune(2764)},
+ &CodePointRange{From: rune(2818), To: rune(2819)},
+ &CodePointRange{From: rune(2878), To: rune(2878)},
+ &CodePointRange{From: rune(2880), To: rune(2880)},
+ &CodePointRange{From: rune(2887), To: rune(2888)},
+ &CodePointRange{From: rune(2891), To: rune(2892)},
+ &CodePointRange{From: rune(2903), To: rune(2903)},
+ &CodePointRange{From: rune(3006), To: rune(3007)},
+ &CodePointRange{From: rune(3009), To: rune(3010)},
+ &CodePointRange{From: rune(3014), To: rune(3016)},
+ &CodePointRange{From: rune(3018), To: rune(3020)},
+ &CodePointRange{From: rune(3031), To: rune(3031)},
+ &CodePointRange{From: rune(3073), To: rune(3075)},
+ &CodePointRange{From: rune(3137), To: rune(3140)},
+ &CodePointRange{From: rune(3202), To: rune(3203)},
+ &CodePointRange{From: rune(3262), To: rune(3262)},
+ &CodePointRange{From: rune(3264), To: rune(3268)},
+ &CodePointRange{From: rune(3271), To: rune(3272)},
+ &CodePointRange{From: rune(3274), To: rune(3275)},
+ &CodePointRange{From: rune(3285), To: rune(3286)},
+ &CodePointRange{From: rune(3330), To: rune(3331)},
+ &CodePointRange{From: rune(3390), To: rune(3392)},
+ &CodePointRange{From: rune(3398), To: rune(3400)},
+ &CodePointRange{From: rune(3402), To: rune(3404)},
+ &CodePointRange{From: rune(3415), To: rune(3415)},
+ &CodePointRange{From: rune(3458), To: rune(3459)},
+ &CodePointRange{From: rune(3535), To: rune(3537)},
+ &CodePointRange{From: rune(3544), To: rune(3551)},
+ &CodePointRange{From: rune(3570), To: rune(3571)},
+ &CodePointRange{From: rune(3902), To: rune(3903)},
+ &CodePointRange{From: rune(3967), To: rune(3967)},
+ &CodePointRange{From: rune(4139), To: rune(4140)},
+ &CodePointRange{From: rune(4145), To: rune(4145)},
+ &CodePointRange{From: rune(4152), To: rune(4152)},
+ &CodePointRange{From: rune(4155), To: rune(4156)},
+ &CodePointRange{From: rune(4182), To: rune(4183)},
+ &CodePointRange{From: rune(4194), To: rune(4196)},
+ &CodePointRange{From: rune(4199), To: rune(4205)},
+ &CodePointRange{From: rune(4227), To: rune(4228)},
+ &CodePointRange{From: rune(4231), To: rune(4236)},
+ &CodePointRange{From: rune(4239), To: rune(4239)},
+ &CodePointRange{From: rune(4250), To: rune(4252)},
+ &CodePointRange{From: rune(6070), To: rune(6070)},
+ &CodePointRange{From: rune(6078), To: rune(6085)},
+ &CodePointRange{From: rune(6087), To: rune(6088)},
+ &CodePointRange{From: rune(6435), To: rune(6438)},
+ &CodePointRange{From: rune(6441), To: rune(6443)},
+ &CodePointRange{From: rune(6448), To: rune(6449)},
+ &CodePointRange{From: rune(6451), To: rune(6456)},
+ &CodePointRange{From: rune(6681), To: rune(6682)},
+ &CodePointRange{From: rune(6741), To: rune(6741)},
+ &CodePointRange{From: rune(6743), To: rune(6743)},
+ &CodePointRange{From: rune(6753), To: rune(6753)},
+ &CodePointRange{From: rune(6755), To: rune(6756)},
+ &CodePointRange{From: rune(6765), To: rune(6770)},
+ &CodePointRange{From: rune(6916), To: rune(6916)},
+ &CodePointRange{From: rune(6965), To: rune(6965)},
+ &CodePointRange{From: rune(6971), To: rune(6971)},
+ &CodePointRange{From: rune(6973), To: rune(6977)},
+ &CodePointRange{From: rune(6979), To: rune(6980)},
+ &CodePointRange{From: rune(7042), To: rune(7042)},
+ &CodePointRange{From: rune(7073), To: rune(7073)},
+ &CodePointRange{From: rune(7078), To: rune(7079)},
+ &CodePointRange{From: rune(7082), To: rune(7082)},
+ &CodePointRange{From: rune(7143), To: rune(7143)},
+ &CodePointRange{From: rune(7146), To: rune(7148)},
+ &CodePointRange{From: rune(7150), To: rune(7150)},
+ &CodePointRange{From: rune(7154), To: rune(7155)},
+ &CodePointRange{From: rune(7204), To: rune(7211)},
+ &CodePointRange{From: rune(7220), To: rune(7221)},
+ &CodePointRange{From: rune(7393), To: rune(7393)},
+ &CodePointRange{From: rune(7415), To: rune(7415)},
+ &CodePointRange{From: rune(12334), To: rune(12335)},
+ &CodePointRange{From: rune(43043), To: rune(43044)},
+ &CodePointRange{From: rune(43047), To: rune(43047)},
+ &CodePointRange{From: rune(43136), To: rune(43137)},
+ &CodePointRange{From: rune(43188), To: rune(43203)},
+ &CodePointRange{From: rune(43346), To: rune(43347)},
+ &CodePointRange{From: rune(43395), To: rune(43395)},
+ &CodePointRange{From: rune(43444), To: rune(43445)},
+ &CodePointRange{From: rune(43450), To: rune(43451)},
+ &CodePointRange{From: rune(43454), To: rune(43456)},
+ &CodePointRange{From: rune(43567), To: rune(43568)},
+ &CodePointRange{From: rune(43571), To: rune(43572)},
+ &CodePointRange{From: rune(43597), To: rune(43597)},
+ &CodePointRange{From: rune(43643), To: rune(43643)},
+ &CodePointRange{From: rune(43645), To: rune(43645)},
+ &CodePointRange{From: rune(43755), To: rune(43755)},
+ &CodePointRange{From: rune(43758), To: rune(43759)},
+ &CodePointRange{From: rune(43765), To: rune(43765)},
+ &CodePointRange{From: rune(44003), To: rune(44004)},
+ &CodePointRange{From: rune(44006), To: rune(44007)},
+ &CodePointRange{From: rune(44009), To: rune(44010)},
+ &CodePointRange{From: rune(44012), To: rune(44012)},
+ &CodePointRange{From: rune(69632), To: rune(69632)},
+ &CodePointRange{From: rune(69634), To: rune(69634)},
+ &CodePointRange{From: rune(69762), To: rune(69762)},
+ &CodePointRange{From: rune(69808), To: rune(69810)},
+ &CodePointRange{From: rune(69815), To: rune(69816)},
+ &CodePointRange{From: rune(69932), To: rune(69932)},
+ &CodePointRange{From: rune(69957), To: rune(69958)},
+ &CodePointRange{From: rune(70018), To: rune(70018)},
+ &CodePointRange{From: rune(70067), To: rune(70069)},
+ &CodePointRange{From: rune(70079), To: rune(70080)},
+ &CodePointRange{From: rune(70094), To: rune(70094)},
+ &CodePointRange{From: rune(70188), To: rune(70190)},
+ &CodePointRange{From: rune(70194), To: rune(70195)},
+ &CodePointRange{From: rune(70197), To: rune(70197)},
+ &CodePointRange{From: rune(70368), To: rune(70370)},
+ &CodePointRange{From: rune(70402), To: rune(70403)},
+ &CodePointRange{From: rune(70462), To: rune(70463)},
+ &CodePointRange{From: rune(70465), To: rune(70468)},
+ &CodePointRange{From: rune(70471), To: rune(70472)},
+ &CodePointRange{From: rune(70475), To: rune(70477)},
+ &CodePointRange{From: rune(70487), To: rune(70487)},
+ &CodePointRange{From: rune(70498), To: rune(70499)},
+ &CodePointRange{From: rune(70709), To: rune(70711)},
+ &CodePointRange{From: rune(70720), To: rune(70721)},
+ &CodePointRange{From: rune(70725), To: rune(70725)},
+ &CodePointRange{From: rune(70832), To: rune(70834)},
+ &CodePointRange{From: rune(70841), To: rune(70841)},
+ &CodePointRange{From: rune(70843), To: rune(70846)},
+ &CodePointRange{From: rune(70849), To: rune(70849)},
+ &CodePointRange{From: rune(71087), To: rune(71089)},
+ &CodePointRange{From: rune(71096), To: rune(71099)},
+ &CodePointRange{From: rune(71102), To: rune(71102)},
+ &CodePointRange{From: rune(71216), To: rune(71218)},
+ &CodePointRange{From: rune(71227), To: rune(71228)},
+ &CodePointRange{From: rune(71230), To: rune(71230)},
+ &CodePointRange{From: rune(71340), To: rune(71340)},
+ &CodePointRange{From: rune(71342), To: rune(71343)},
+ &CodePointRange{From: rune(71350), To: rune(71350)},
+ &CodePointRange{From: rune(71456), To: rune(71457)},
+ &CodePointRange{From: rune(71462), To: rune(71462)},
+ &CodePointRange{From: rune(71724), To: rune(71726)},
+ &CodePointRange{From: rune(71736), To: rune(71736)},
+ &CodePointRange{From: rune(71984), To: rune(71989)},
+ &CodePointRange{From: rune(71991), To: rune(71992)},
+ &CodePointRange{From: rune(71997), To: rune(71997)},
+ &CodePointRange{From: rune(72000), To: rune(72000)},
+ &CodePointRange{From: rune(72002), To: rune(72002)},
+ &CodePointRange{From: rune(72145), To: rune(72147)},
+ &CodePointRange{From: rune(72156), To: rune(72159)},
+ &CodePointRange{From: rune(72164), To: rune(72164)},
+ &CodePointRange{From: rune(72249), To: rune(72249)},
+ &CodePointRange{From: rune(72279), To: rune(72280)},
+ &CodePointRange{From: rune(72343), To: rune(72343)},
+ &CodePointRange{From: rune(72751), To: rune(72751)},
+ &CodePointRange{From: rune(72766), To: rune(72766)},
+ &CodePointRange{From: rune(72873), To: rune(72873)},
+ &CodePointRange{From: rune(72881), To: rune(72881)},
+ &CodePointRange{From: rune(72884), To: rune(72884)},
+ &CodePointRange{From: rune(73098), To: rune(73102)},
+ &CodePointRange{From: rune(73107), To: rune(73108)},
+ &CodePointRange{From: rune(73110), To: rune(73110)},
+ &CodePointRange{From: rune(73461), To: rune(73462)},
+ &CodePointRange{From: rune(94033), To: rune(94087)},
+ &CodePointRange{From: rune(94192), To: rune(94193)},
+ &CodePointRange{From: rune(119141), To: rune(119142)},
+ &CodePointRange{From: rune(119149), To: rune(119154)},
+ },
+ "me": {
+ &CodePointRange{From: rune(1160), To: rune(1161)},
+ &CodePointRange{From: rune(6846), To: rune(6846)},
+ &CodePointRange{From: rune(8413), To: rune(8416)},
+ &CodePointRange{From: rune(8418), To: rune(8420)},
+ &CodePointRange{From: rune(42608), To: rune(42610)},
+ },
+ "mn": {
+ &CodePointRange{From: rune(768), To: rune(879)},
+ &CodePointRange{From: rune(1155), To: rune(1159)},
+ &CodePointRange{From: rune(1425), To: rune(1469)},
+ &CodePointRange{From: rune(1471), To: rune(1471)},
+ &CodePointRange{From: rune(1473), To: rune(1474)},
+ &CodePointRange{From: rune(1476), To: rune(1477)},
+ &CodePointRange{From: rune(1479), To: rune(1479)},
+ &CodePointRange{From: rune(1552), To: rune(1562)},
+ &CodePointRange{From: rune(1611), To: rune(1631)},
+ &CodePointRange{From: rune(1648), To: rune(1648)},
+ &CodePointRange{From: rune(1750), To: rune(1756)},
+ &CodePointRange{From: rune(1759), To: rune(1764)},
+ &CodePointRange{From: rune(1767), To: rune(1768)},
+ &CodePointRange{From: rune(1770), To: rune(1773)},
+ &CodePointRange{From: rune(1809), To: rune(1809)},
+ &CodePointRange{From: rune(1840), To: rune(1866)},
+ &CodePointRange{From: rune(1958), To: rune(1968)},
+ &CodePointRange{From: rune(2027), To: rune(2035)},
+ &CodePointRange{From: rune(2045), To: rune(2045)},
+ &CodePointRange{From: rune(2070), To: rune(2073)},
+ &CodePointRange{From: rune(2075), To: rune(2083)},
+ &CodePointRange{From: rune(2085), To: rune(2087)},
+ &CodePointRange{From: rune(2089), To: rune(2093)},
+ &CodePointRange{From: rune(2137), To: rune(2139)},
+ &CodePointRange{From: rune(2259), To: rune(2273)},
+ &CodePointRange{From: rune(2275), To: rune(2306)},
+ &CodePointRange{From: rune(2362), To: rune(2362)},
+ &CodePointRange{From: rune(2364), To: rune(2364)},
+ &CodePointRange{From: rune(2369), To: rune(2376)},
+ &CodePointRange{From: rune(2381), To: rune(2381)},
+ &CodePointRange{From: rune(2385), To: rune(2391)},
+ &CodePointRange{From: rune(2402), To: rune(2403)},
+ &CodePointRange{From: rune(2433), To: rune(2433)},
+ &CodePointRange{From: rune(2492), To: rune(2492)},
+ &CodePointRange{From: rune(2497), To: rune(2500)},
+ &CodePointRange{From: rune(2509), To: rune(2509)},
+ &CodePointRange{From: rune(2530), To: rune(2531)},
+ &CodePointRange{From: rune(2558), To: rune(2558)},
+ &CodePointRange{From: rune(2561), To: rune(2562)},
+ &CodePointRange{From: rune(2620), To: rune(2620)},
+ &CodePointRange{From: rune(2625), To: rune(2626)},
+ &CodePointRange{From: rune(2631), To: rune(2632)},
+ &CodePointRange{From: rune(2635), To: rune(2637)},
+ &CodePointRange{From: rune(2641), To: rune(2641)},
+ &CodePointRange{From: rune(2672), To: rune(2673)},
+ &CodePointRange{From: rune(2677), To: rune(2677)},
+ &CodePointRange{From: rune(2689), To: rune(2690)},
+ &CodePointRange{From: rune(2748), To: rune(2748)},
+ &CodePointRange{From: rune(2753), To: rune(2757)},
+ &CodePointRange{From: rune(2759), To: rune(2760)},
+ &CodePointRange{From: rune(2765), To: rune(2765)},
+ &CodePointRange{From: rune(2786), To: rune(2787)},
+ &CodePointRange{From: rune(2810), To: rune(2815)},
+ &CodePointRange{From: rune(2817), To: rune(2817)},
+ &CodePointRange{From: rune(2876), To: rune(2876)},
+ &CodePointRange{From: rune(2879), To: rune(2879)},
+ &CodePointRange{From: rune(2881), To: rune(2884)},
+ &CodePointRange{From: rune(2893), To: rune(2893)},
+ &CodePointRange{From: rune(2901), To: rune(2902)},
+ &CodePointRange{From: rune(2914), To: rune(2915)},
+ &CodePointRange{From: rune(2946), To: rune(2946)},
+ &CodePointRange{From: rune(3008), To: rune(3008)},
+ &CodePointRange{From: rune(3021), To: rune(3021)},
+ &CodePointRange{From: rune(3072), To: rune(3072)},
+ &CodePointRange{From: rune(3076), To: rune(3076)},
+ &CodePointRange{From: rune(3134), To: rune(3136)},
+ &CodePointRange{From: rune(3142), To: rune(3144)},
+ &CodePointRange{From: rune(3146), To: rune(3149)},
+ &CodePointRange{From: rune(3157), To: rune(3158)},
+ &CodePointRange{From: rune(3170), To: rune(3171)},
+ &CodePointRange{From: rune(3201), To: rune(3201)},
+ &CodePointRange{From: rune(3260), To: rune(3260)},
+ &CodePointRange{From: rune(3263), To: rune(3263)},
+ &CodePointRange{From: rune(3270), To: rune(3270)},
+ &CodePointRange{From: rune(3276), To: rune(3277)},
+ &CodePointRange{From: rune(3298), To: rune(3299)},
+ &CodePointRange{From: rune(3328), To: rune(3329)},
+ &CodePointRange{From: rune(3387), To: rune(3388)},
+ &CodePointRange{From: rune(3393), To: rune(3396)},
+ &CodePointRange{From: rune(3405), To: rune(3405)},
+ &CodePointRange{From: rune(3426), To: rune(3427)},
+ &CodePointRange{From: rune(3457), To: rune(3457)},
+ &CodePointRange{From: rune(3530), To: rune(3530)},
+ &CodePointRange{From: rune(3538), To: rune(3540)},
+ &CodePointRange{From: rune(3542), To: rune(3542)},
+ &CodePointRange{From: rune(3633), To: rune(3633)},
+ &CodePointRange{From: rune(3636), To: rune(3642)},
+ &CodePointRange{From: rune(3655), To: rune(3662)},
+ &CodePointRange{From: rune(3761), To: rune(3761)},
+ &CodePointRange{From: rune(3764), To: rune(3772)},
+ &CodePointRange{From: rune(3784), To: rune(3789)},
+ &CodePointRange{From: rune(3864), To: rune(3865)},
+ &CodePointRange{From: rune(3893), To: rune(3893)},
+ &CodePointRange{From: rune(3895), To: rune(3895)},
+ &CodePointRange{From: rune(3897), To: rune(3897)},
+ &CodePointRange{From: rune(3953), To: rune(3966)},
+ &CodePointRange{From: rune(3968), To: rune(3972)},
+ &CodePointRange{From: rune(3974), To: rune(3975)},
+ &CodePointRange{From: rune(3981), To: rune(3991)},
+ &CodePointRange{From: rune(3993), To: rune(4028)},
+ &CodePointRange{From: rune(4038), To: rune(4038)},
+ &CodePointRange{From: rune(4141), To: rune(4144)},
+ &CodePointRange{From: rune(4146), To: rune(4151)},
+ &CodePointRange{From: rune(4153), To: rune(4154)},
+ &CodePointRange{From: rune(4157), To: rune(4158)},
+ &CodePointRange{From: rune(4184), To: rune(4185)},
+ &CodePointRange{From: rune(4190), To: rune(4192)},
+ &CodePointRange{From: rune(4209), To: rune(4212)},
+ &CodePointRange{From: rune(4226), To: rune(4226)},
+ &CodePointRange{From: rune(4229), To: rune(4230)},
+ &CodePointRange{From: rune(4237), To: rune(4237)},
+ &CodePointRange{From: rune(4253), To: rune(4253)},
+ &CodePointRange{From: rune(4957), To: rune(4959)},
+ &CodePointRange{From: rune(5906), To: rune(5908)},
+ &CodePointRange{From: rune(5938), To: rune(5940)},
+ &CodePointRange{From: rune(5970), To: rune(5971)},
+ &CodePointRange{From: rune(6002), To: rune(6003)},
+ &CodePointRange{From: rune(6068), To: rune(6069)},
+ &CodePointRange{From: rune(6071), To: rune(6077)},
+ &CodePointRange{From: rune(6086), To: rune(6086)},
+ &CodePointRange{From: rune(6089), To: rune(6099)},
+ &CodePointRange{From: rune(6109), To: rune(6109)},
+ &CodePointRange{From: rune(6155), To: rune(6157)},
+ &CodePointRange{From: rune(6277), To: rune(6278)},
+ &CodePointRange{From: rune(6313), To: rune(6313)},
+ &CodePointRange{From: rune(6432), To: rune(6434)},
+ &CodePointRange{From: rune(6439), To: rune(6440)},
+ &CodePointRange{From: rune(6450), To: rune(6450)},
+ &CodePointRange{From: rune(6457), To: rune(6459)},
+ &CodePointRange{From: rune(6679), To: rune(6680)},
+ &CodePointRange{From: rune(6683), To: rune(6683)},
+ &CodePointRange{From: rune(6742), To: rune(6742)},
+ &CodePointRange{From: rune(6744), To: rune(6750)},
+ &CodePointRange{From: rune(6752), To: rune(6752)},
+ &CodePointRange{From: rune(6754), To: rune(6754)},
+ &CodePointRange{From: rune(6757), To: rune(6764)},
+ &CodePointRange{From: rune(6771), To: rune(6780)},
+ &CodePointRange{From: rune(6783), To: rune(6783)},
+ &CodePointRange{From: rune(6832), To: rune(6845)},
+ &CodePointRange{From: rune(6847), To: rune(6848)},
+ &CodePointRange{From: rune(6912), To: rune(6915)},
+ &CodePointRange{From: rune(6964), To: rune(6964)},
+ &CodePointRange{From: rune(6966), To: rune(6970)},
+ &CodePointRange{From: rune(6972), To: rune(6972)},
+ &CodePointRange{From: rune(6978), To: rune(6978)},
+ &CodePointRange{From: rune(7019), To: rune(7027)},
+ &CodePointRange{From: rune(7040), To: rune(7041)},
+ &CodePointRange{From: rune(7074), To: rune(7077)},
+ &CodePointRange{From: rune(7080), To: rune(7081)},
+ &CodePointRange{From: rune(7083), To: rune(7085)},
+ &CodePointRange{From: rune(7142), To: rune(7142)},
+ &CodePointRange{From: rune(7144), To: rune(7145)},
+ &CodePointRange{From: rune(7149), To: rune(7149)},
+ &CodePointRange{From: rune(7151), To: rune(7153)},
+ &CodePointRange{From: rune(7212), To: rune(7219)},
+ &CodePointRange{From: rune(7222), To: rune(7223)},
+ &CodePointRange{From: rune(7376), To: rune(7378)},
+ &CodePointRange{From: rune(7380), To: rune(7392)},
+ &CodePointRange{From: rune(7394), To: rune(7400)},
+ &CodePointRange{From: rune(7405), To: rune(7405)},
+ &CodePointRange{From: rune(7412), To: rune(7412)},
+ &CodePointRange{From: rune(7416), To: rune(7417)},
+ &CodePointRange{From: rune(7616), To: rune(7673)},
+ &CodePointRange{From: rune(7675), To: rune(7679)},
+ &CodePointRange{From: rune(8400), To: rune(8412)},
+ &CodePointRange{From: rune(8417), To: rune(8417)},
+ &CodePointRange{From: rune(8421), To: rune(8432)},
+ &CodePointRange{From: rune(11503), To: rune(11505)},
+ &CodePointRange{From: rune(11647), To: rune(11647)},
+ &CodePointRange{From: rune(11744), To: rune(11775)},
+ &CodePointRange{From: rune(12330), To: rune(12333)},
+ &CodePointRange{From: rune(12441), To: rune(12442)},
+ &CodePointRange{From: rune(42607), To: rune(42607)},
+ &CodePointRange{From: rune(42612), To: rune(42621)},
+ &CodePointRange{From: rune(42654), To: rune(42655)},
+ &CodePointRange{From: rune(42736), To: rune(42737)},
+ &CodePointRange{From: rune(43010), To: rune(43010)},
+ &CodePointRange{From: rune(43014), To: rune(43014)},
+ &CodePointRange{From: rune(43019), To: rune(43019)},
+ &CodePointRange{From: rune(43045), To: rune(43046)},
+ &CodePointRange{From: rune(43052), To: rune(43052)},
+ &CodePointRange{From: rune(43204), To: rune(43205)},
+ &CodePointRange{From: rune(43232), To: rune(43249)},
+ &CodePointRange{From: rune(43263), To: rune(43263)},
+ &CodePointRange{From: rune(43302), To: rune(43309)},
+ &CodePointRange{From: rune(43335), To: rune(43345)},
+ &CodePointRange{From: rune(43392), To: rune(43394)},
+ &CodePointRange{From: rune(43443), To: rune(43443)},
+ &CodePointRange{From: rune(43446), To: rune(43449)},
+ &CodePointRange{From: rune(43452), To: rune(43453)},
+ &CodePointRange{From: rune(43493), To: rune(43493)},
+ &CodePointRange{From: rune(43561), To: rune(43566)},
+ &CodePointRange{From: rune(43569), To: rune(43570)},
+ &CodePointRange{From: rune(43573), To: rune(43574)},
+ &CodePointRange{From: rune(43587), To: rune(43587)},
+ &CodePointRange{From: rune(43596), To: rune(43596)},
+ &CodePointRange{From: rune(43644), To: rune(43644)},
+ &CodePointRange{From: rune(43696), To: rune(43696)},
+ &CodePointRange{From: rune(43698), To: rune(43700)},
+ &CodePointRange{From: rune(43703), To: rune(43704)},
+ &CodePointRange{From: rune(43710), To: rune(43711)},
+ &CodePointRange{From: rune(43713), To: rune(43713)},
+ &CodePointRange{From: rune(43756), To: rune(43757)},
+ &CodePointRange{From: rune(43766), To: rune(43766)},
+ &CodePointRange{From: rune(44005), To: rune(44005)},
+ &CodePointRange{From: rune(44008), To: rune(44008)},
+ &CodePointRange{From: rune(44013), To: rune(44013)},
+ &CodePointRange{From: rune(64286), To: rune(64286)},
+ &CodePointRange{From: rune(65024), To: rune(65039)},
+ &CodePointRange{From: rune(65056), To: rune(65071)},
+ &CodePointRange{From: rune(66045), To: rune(66045)},
+ &CodePointRange{From: rune(66272), To: rune(66272)},
+ &CodePointRange{From: rune(66422), To: rune(66426)},
+ &CodePointRange{From: rune(68097), To: rune(68099)},
+ &CodePointRange{From: rune(68101), To: rune(68102)},
+ &CodePointRange{From: rune(68108), To: rune(68111)},
+ &CodePointRange{From: rune(68152), To: rune(68154)},
+ &CodePointRange{From: rune(68159), To: rune(68159)},
+ &CodePointRange{From: rune(68325), To: rune(68326)},
+ &CodePointRange{From: rune(68900), To: rune(68903)},
+ &CodePointRange{From: rune(69291), To: rune(69292)},
+ &CodePointRange{From: rune(69446), To: rune(69456)},
+ &CodePointRange{From: rune(69633), To: rune(69633)},
+ &CodePointRange{From: rune(69688), To: rune(69702)},
+ &CodePointRange{From: rune(69759), To: rune(69761)},
+ &CodePointRange{From: rune(69811), To: rune(69814)},
+ &CodePointRange{From: rune(69817), To: rune(69818)},
+ &CodePointRange{From: rune(69888), To: rune(69890)},
+ &CodePointRange{From: rune(69927), To: rune(69931)},
+ &CodePointRange{From: rune(69933), To: rune(69940)},
+ &CodePointRange{From: rune(70003), To: rune(70003)},
+ &CodePointRange{From: rune(70016), To: rune(70017)},
+ &CodePointRange{From: rune(70070), To: rune(70078)},
+ &CodePointRange{From: rune(70089), To: rune(70092)},
+ &CodePointRange{From: rune(70095), To: rune(70095)},
+ &CodePointRange{From: rune(70191), To: rune(70193)},
+ &CodePointRange{From: rune(70196), To: rune(70196)},
+ &CodePointRange{From: rune(70198), To: rune(70199)},
+ &CodePointRange{From: rune(70206), To: rune(70206)},
+ &CodePointRange{From: rune(70367), To: rune(70367)},
+ &CodePointRange{From: rune(70371), To: rune(70378)},
+ &CodePointRange{From: rune(70400), To: rune(70401)},
+ &CodePointRange{From: rune(70459), To: rune(70460)},
+ &CodePointRange{From: rune(70464), To: rune(70464)},
+ &CodePointRange{From: rune(70502), To: rune(70508)},
+ &CodePointRange{From: rune(70512), To: rune(70516)},
+ &CodePointRange{From: rune(70712), To: rune(70719)},
+ &CodePointRange{From: rune(70722), To: rune(70724)},
+ &CodePointRange{From: rune(70726), To: rune(70726)},
+ &CodePointRange{From: rune(70750), To: rune(70750)},
+ &CodePointRange{From: rune(70835), To: rune(70840)},
+ &CodePointRange{From: rune(70842), To: rune(70842)},
+ &CodePointRange{From: rune(70847), To: rune(70848)},
+ &CodePointRange{From: rune(70850), To: rune(70851)},
+ &CodePointRange{From: rune(71090), To: rune(71093)},
+ &CodePointRange{From: rune(71100), To: rune(71101)},
+ &CodePointRange{From: rune(71103), To: rune(71104)},
+ &CodePointRange{From: rune(71132), To: rune(71133)},
+ &CodePointRange{From: rune(71219), To: rune(71226)},
+ &CodePointRange{From: rune(71229), To: rune(71229)},
+ &CodePointRange{From: rune(71231), To: rune(71232)},
+ &CodePointRange{From: rune(71339), To: rune(71339)},
+ &CodePointRange{From: rune(71341), To: rune(71341)},
+ &CodePointRange{From: rune(71344), To: rune(71349)},
+ &CodePointRange{From: rune(71351), To: rune(71351)},
+ &CodePointRange{From: rune(71453), To: rune(71455)},
+ &CodePointRange{From: rune(71458), To: rune(71461)},
+ &CodePointRange{From: rune(71463), To: rune(71467)},
+ &CodePointRange{From: rune(71727), To: rune(71735)},
+ &CodePointRange{From: rune(71737), To: rune(71738)},
+ &CodePointRange{From: rune(71995), To: rune(71996)},
+ &CodePointRange{From: rune(71998), To: rune(71998)},
+ &CodePointRange{From: rune(72003), To: rune(72003)},
+ &CodePointRange{From: rune(72148), To: rune(72151)},
+ &CodePointRange{From: rune(72154), To: rune(72155)},
+ &CodePointRange{From: rune(72160), To: rune(72160)},
+ &CodePointRange{From: rune(72193), To: rune(72202)},
+ &CodePointRange{From: rune(72243), To: rune(72248)},
+ &CodePointRange{From: rune(72251), To: rune(72254)},
+ &CodePointRange{From: rune(72263), To: rune(72263)},
+ &CodePointRange{From: rune(72273), To: rune(72278)},
+ &CodePointRange{From: rune(72281), To: rune(72283)},
+ &CodePointRange{From: rune(72330), To: rune(72342)},
+ &CodePointRange{From: rune(72344), To: rune(72345)},
+ &CodePointRange{From: rune(72752), To: rune(72758)},
+ &CodePointRange{From: rune(72760), To: rune(72765)},
+ &CodePointRange{From: rune(72767), To: rune(72767)},
+ &CodePointRange{From: rune(72850), To: rune(72871)},
+ &CodePointRange{From: rune(72874), To: rune(72880)},
+ &CodePointRange{From: rune(72882), To: rune(72883)},
+ &CodePointRange{From: rune(72885), To: rune(72886)},
+ &CodePointRange{From: rune(73009), To: rune(73014)},
+ &CodePointRange{From: rune(73018), To: rune(73018)},
+ &CodePointRange{From: rune(73020), To: rune(73021)},
+ &CodePointRange{From: rune(73023), To: rune(73029)},
+ &CodePointRange{From: rune(73031), To: rune(73031)},
+ &CodePointRange{From: rune(73104), To: rune(73105)},
+ &CodePointRange{From: rune(73109), To: rune(73109)},
+ &CodePointRange{From: rune(73111), To: rune(73111)},
+ &CodePointRange{From: rune(73459), To: rune(73460)},
+ &CodePointRange{From: rune(92912), To: rune(92916)},
+ &CodePointRange{From: rune(92976), To: rune(92982)},
+ &CodePointRange{From: rune(94031), To: rune(94031)},
+ &CodePointRange{From: rune(94095), To: rune(94098)},
+ &CodePointRange{From: rune(94180), To: rune(94180)},
+ &CodePointRange{From: rune(113821), To: rune(113822)},
+ &CodePointRange{From: rune(119143), To: rune(119145)},
+ &CodePointRange{From: rune(119163), To: rune(119170)},
+ &CodePointRange{From: rune(119173), To: rune(119179)},
+ &CodePointRange{From: rune(119210), To: rune(119213)},
+ &CodePointRange{From: rune(119362), To: rune(119364)},
+ &CodePointRange{From: rune(121344), To: rune(121398)},
+ &CodePointRange{From: rune(121403), To: rune(121452)},
+ &CodePointRange{From: rune(121461), To: rune(121461)},
+ &CodePointRange{From: rune(121476), To: rune(121476)},
+ &CodePointRange{From: rune(121499), To: rune(121503)},
+ &CodePointRange{From: rune(121505), To: rune(121519)},
+ &CodePointRange{From: rune(122880), To: rune(122886)},
+ &CodePointRange{From: rune(122888), To: rune(122904)},
+ &CodePointRange{From: rune(122907), To: rune(122913)},
+ &CodePointRange{From: rune(122915), To: rune(122916)},
+ &CodePointRange{From: rune(122918), To: rune(122922)},
+ &CodePointRange{From: rune(123184), To: rune(123190)},
+ &CodePointRange{From: rune(123628), To: rune(123631)},
+ &CodePointRange{From: rune(125136), To: rune(125142)},
+ &CodePointRange{From: rune(125252), To: rune(125258)},
+ &CodePointRange{From: rune(917760), To: rune(917999)},
+ },
+ "nd": {
+ &CodePointRange{From: rune(48), To: rune(57)},
+ &CodePointRange{From: rune(1632), To: rune(1641)},
+ &CodePointRange{From: rune(1776), To: rune(1785)},
+ &CodePointRange{From: rune(1984), To: rune(1993)},
+ &CodePointRange{From: rune(2406), To: rune(2415)},
+ &CodePointRange{From: rune(2534), To: rune(2543)},
+ &CodePointRange{From: rune(2662), To: rune(2671)},
+ &CodePointRange{From: rune(2790), To: rune(2799)},
+ &CodePointRange{From: rune(2918), To: rune(2927)},
+ &CodePointRange{From: rune(3046), To: rune(3055)},
+ &CodePointRange{From: rune(3174), To: rune(3183)},
+ &CodePointRange{From: rune(3302), To: rune(3311)},
+ &CodePointRange{From: rune(3430), To: rune(3439)},
+ &CodePointRange{From: rune(3558), To: rune(3567)},
+ &CodePointRange{From: rune(3664), To: rune(3673)},
+ &CodePointRange{From: rune(3792), To: rune(3801)},
+ &CodePointRange{From: rune(3872), To: rune(3881)},
+ &CodePointRange{From: rune(4160), To: rune(4169)},
+ &CodePointRange{From: rune(4240), To: rune(4249)},
+ &CodePointRange{From: rune(6112), To: rune(6121)},
+ &CodePointRange{From: rune(6160), To: rune(6169)},
+ &CodePointRange{From: rune(6470), To: rune(6479)},
+ &CodePointRange{From: rune(6608), To: rune(6617)},
+ &CodePointRange{From: rune(6784), To: rune(6793)},
+ &CodePointRange{From: rune(6800), To: rune(6809)},
+ &CodePointRange{From: rune(6992), To: rune(7001)},
+ &CodePointRange{From: rune(7088), To: rune(7097)},
+ &CodePointRange{From: rune(7232), To: rune(7241)},
+ &CodePointRange{From: rune(7248), To: rune(7257)},
+ &CodePointRange{From: rune(42528), To: rune(42537)},
+ &CodePointRange{From: rune(43216), To: rune(43225)},
+ &CodePointRange{From: rune(43264), To: rune(43273)},
+ &CodePointRange{From: rune(43472), To: rune(43481)},
+ &CodePointRange{From: rune(43504), To: rune(43513)},
+ &CodePointRange{From: rune(43600), To: rune(43609)},
+ &CodePointRange{From: rune(44016), To: rune(44025)},
+ &CodePointRange{From: rune(65296), To: rune(65305)},
+ &CodePointRange{From: rune(66720), To: rune(66729)},
+ &CodePointRange{From: rune(68912), To: rune(68921)},
+ &CodePointRange{From: rune(69734), To: rune(69743)},
+ &CodePointRange{From: rune(69872), To: rune(69881)},
+ &CodePointRange{From: rune(69942), To: rune(69951)},
+ &CodePointRange{From: rune(70096), To: rune(70105)},
+ &CodePointRange{From: rune(70384), To: rune(70393)},
+ &CodePointRange{From: rune(70736), To: rune(70745)},
+ &CodePointRange{From: rune(70864), To: rune(70873)},
+ &CodePointRange{From: rune(71248), To: rune(71257)},
+ &CodePointRange{From: rune(71360), To: rune(71369)},
+ &CodePointRange{From: rune(71472), To: rune(71481)},
+ &CodePointRange{From: rune(71904), To: rune(71913)},
+ &CodePointRange{From: rune(72016), To: rune(72025)},
+ &CodePointRange{From: rune(72784), To: rune(72793)},
+ &CodePointRange{From: rune(73040), To: rune(73049)},
+ &CodePointRange{From: rune(73120), To: rune(73129)},
+ &CodePointRange{From: rune(92768), To: rune(92777)},
+ &CodePointRange{From: rune(93008), To: rune(93017)},
+ &CodePointRange{From: rune(120782), To: rune(120831)},
+ &CodePointRange{From: rune(123200), To: rune(123209)},
+ &CodePointRange{From: rune(123632), To: rune(123641)},
+ &CodePointRange{From: rune(125264), To: rune(125273)},
+ &CodePointRange{From: rune(130032), To: rune(130041)},
+ },
+ "nl": {
+ &CodePointRange{From: rune(5870), To: rune(5872)},
+ &CodePointRange{From: rune(8544), To: rune(8578)},
+ &CodePointRange{From: rune(8581), To: rune(8584)},
+ &CodePointRange{From: rune(12295), To: rune(12295)},
+ &CodePointRange{From: rune(12321), To: rune(12329)},
+ &CodePointRange{From: rune(12344), To: rune(12346)},
+ &CodePointRange{From: rune(42726), To: rune(42735)},
+ &CodePointRange{From: rune(65856), To: rune(65908)},
+ &CodePointRange{From: rune(66369), To: rune(66369)},
+ &CodePointRange{From: rune(66378), To: rune(66378)},
+ &CodePointRange{From: rune(66513), To: rune(66517)},
+ &CodePointRange{From: rune(74752), To: rune(74862)},
+ },
+ "no": {
+ &CodePointRange{From: rune(178), To: rune(179)},
+ &CodePointRange{From: rune(185), To: rune(185)},
+ &CodePointRange{From: rune(188), To: rune(190)},
+ &CodePointRange{From: rune(2548), To: rune(2553)},
+ &CodePointRange{From: rune(2930), To: rune(2935)},
+ &CodePointRange{From: rune(3056), To: rune(3058)},
+ &CodePointRange{From: rune(3192), To: rune(3198)},
+ &CodePointRange{From: rune(3416), To: rune(3422)},
+ &CodePointRange{From: rune(3440), To: rune(3448)},
+ &CodePointRange{From: rune(3882), To: rune(3891)},
+ &CodePointRange{From: rune(4969), To: rune(4988)},
+ &CodePointRange{From: rune(6128), To: rune(6137)},
+ &CodePointRange{From: rune(6618), To: rune(6618)},
+ &CodePointRange{From: rune(8304), To: rune(8304)},
+ &CodePointRange{From: rune(8308), To: rune(8313)},
+ &CodePointRange{From: rune(8320), To: rune(8329)},
+ &CodePointRange{From: rune(8528), To: rune(8543)},
+ &CodePointRange{From: rune(8585), To: rune(8585)},
+ &CodePointRange{From: rune(9312), To: rune(9371)},
+ &CodePointRange{From: rune(9450), To: rune(9471)},
+ &CodePointRange{From: rune(10102), To: rune(10131)},
+ &CodePointRange{From: rune(11517), To: rune(11517)},
+ &CodePointRange{From: rune(12690), To: rune(12693)},
+ &CodePointRange{From: rune(12832), To: rune(12841)},
+ &CodePointRange{From: rune(12872), To: rune(12879)},
+ &CodePointRange{From: rune(12881), To: rune(12895)},
+ &CodePointRange{From: rune(12928), To: rune(12937)},
+ &CodePointRange{From: rune(12977), To: rune(12991)},
+ &CodePointRange{From: rune(43056), To: rune(43061)},
+ &CodePointRange{From: rune(65799), To: rune(65843)},
+ &CodePointRange{From: rune(65909), To: rune(65912)},
+ &CodePointRange{From: rune(65930), To: rune(65931)},
+ &CodePointRange{From: rune(66273), To: rune(66299)},
+ &CodePointRange{From: rune(66336), To: rune(66339)},
+ &CodePointRange{From: rune(67672), To: rune(67679)},
+ &CodePointRange{From: rune(67705), To: rune(67711)},
+ &CodePointRange{From: rune(67751), To: rune(67759)},
+ &CodePointRange{From: rune(67835), To: rune(67839)},
+ &CodePointRange{From: rune(67862), To: rune(67867)},
+ &CodePointRange{From: rune(68028), To: rune(68029)},
+ &CodePointRange{From: rune(68032), To: rune(68047)},
+ &CodePointRange{From: rune(68050), To: rune(68095)},
+ &CodePointRange{From: rune(68160), To: rune(68168)},
+ &CodePointRange{From: rune(68221), To: rune(68222)},
+ &CodePointRange{From: rune(68253), To: rune(68255)},
+ &CodePointRange{From: rune(68331), To: rune(68335)},
+ &CodePointRange{From: rune(68440), To: rune(68447)},
+ &CodePointRange{From: rune(68472), To: rune(68479)},
+ &CodePointRange{From: rune(68521), To: rune(68527)},
+ &CodePointRange{From: rune(68858), To: rune(68863)},
+ &CodePointRange{From: rune(69216), To: rune(69246)},
+ &CodePointRange{From: rune(69405), To: rune(69414)},
+ &CodePointRange{From: rune(69457), To: rune(69460)},
+ &CodePointRange{From: rune(69573), To: rune(69579)},
+ &CodePointRange{From: rune(69714), To: rune(69733)},
+ &CodePointRange{From: rune(70113), To: rune(70132)},
+ &CodePointRange{From: rune(71482), To: rune(71483)},
+ &CodePointRange{From: rune(71914), To: rune(71922)},
+ &CodePointRange{From: rune(72794), To: rune(72812)},
+ &CodePointRange{From: rune(73664), To: rune(73684)},
+ &CodePointRange{From: rune(93019), To: rune(93025)},
+ &CodePointRange{From: rune(93824), To: rune(93846)},
+ &CodePointRange{From: rune(119520), To: rune(119539)},
+ &CodePointRange{From: rune(119648), To: rune(119672)},
+ &CodePointRange{From: rune(125127), To: rune(125135)},
+ &CodePointRange{From: rune(126065), To: rune(126123)},
+ &CodePointRange{From: rune(126125), To: rune(126127)},
+ &CodePointRange{From: rune(126129), To: rune(126132)},
+ &CodePointRange{From: rune(126209), To: rune(126253)},
+ &CodePointRange{From: rune(126255), To: rune(126269)},
+ &CodePointRange{From: rune(127232), To: rune(127244)},
+ },
+ "pc": {
+ &CodePointRange{From: rune(95), To: rune(95)},
+ &CodePointRange{From: rune(8255), To: rune(8256)},
+ &CodePointRange{From: rune(8276), To: rune(8276)},
+ &CodePointRange{From: rune(65075), To: rune(65076)},
+ &CodePointRange{From: rune(65101), To: rune(65103)},
+ &CodePointRange{From: rune(65343), To: rune(65343)},
+ },
+ "pd": {
+ &CodePointRange{From: rune(45), To: rune(45)},
+ &CodePointRange{From: rune(1418), To: rune(1418)},
+ &CodePointRange{From: rune(1470), To: rune(1470)},
+ &CodePointRange{From: rune(5120), To: rune(5120)},
+ &CodePointRange{From: rune(6150), To: rune(6150)},
+ &CodePointRange{From: rune(8208), To: rune(8213)},
+ &CodePointRange{From: rune(11799), To: rune(11799)},
+ &CodePointRange{From: rune(11802), To: rune(11802)},
+ &CodePointRange{From: rune(11834), To: rune(11835)},
+ &CodePointRange{From: rune(11840), To: rune(11840)},
+ &CodePointRange{From: rune(12316), To: rune(12316)},
+ &CodePointRange{From: rune(12336), To: rune(12336)},
+ &CodePointRange{From: rune(12448), To: rune(12448)},
+ &CodePointRange{From: rune(65073), To: rune(65074)},
+ &CodePointRange{From: rune(65112), To: rune(65112)},
+ &CodePointRange{From: rune(65123), To: rune(65123)},
+ &CodePointRange{From: rune(65293), To: rune(65293)},
+ &CodePointRange{From: rune(69293), To: rune(69293)},
+ },
+ "pe": {
+ &CodePointRange{From: rune(41), To: rune(41)},
+ &CodePointRange{From: rune(93), To: rune(93)},
+ &CodePointRange{From: rune(125), To: rune(125)},
+ &CodePointRange{From: rune(3899), To: rune(3899)},
+ &CodePointRange{From: rune(3901), To: rune(3901)},
+ &CodePointRange{From: rune(5788), To: rune(5788)},
+ &CodePointRange{From: rune(8262), To: rune(8262)},
+ &CodePointRange{From: rune(8318), To: rune(8318)},
+ &CodePointRange{From: rune(8334), To: rune(8334)},
+ &CodePointRange{From: rune(8969), To: rune(8969)},
+ &CodePointRange{From: rune(8971), To: rune(8971)},
+ &CodePointRange{From: rune(9002), To: rune(9002)},
+ &CodePointRange{From: rune(10089), To: rune(10089)},
+ &CodePointRange{From: rune(10091), To: rune(10091)},
+ &CodePointRange{From: rune(10093), To: rune(10093)},
+ &CodePointRange{From: rune(10095), To: rune(10095)},
+ &CodePointRange{From: rune(10097), To: rune(10097)},
+ &CodePointRange{From: rune(10099), To: rune(10099)},
+ &CodePointRange{From: rune(10101), To: rune(10101)},
+ &CodePointRange{From: rune(10182), To: rune(10182)},
+ &CodePointRange{From: rune(10215), To: rune(10215)},
+ &CodePointRange{From: rune(10217), To: rune(10217)},
+ &CodePointRange{From: rune(10219), To: rune(10219)},
+ &CodePointRange{From: rune(10221), To: rune(10221)},
+ &CodePointRange{From: rune(10223), To: rune(10223)},
+ &CodePointRange{From: rune(10628), To: rune(10628)},
+ &CodePointRange{From: rune(10630), To: rune(10630)},
+ &CodePointRange{From: rune(10632), To: rune(10632)},
+ &CodePointRange{From: rune(10634), To: rune(10634)},
+ &CodePointRange{From: rune(10636), To: rune(10636)},
+ &CodePointRange{From: rune(10638), To: rune(10638)},
+ &CodePointRange{From: rune(10640), To: rune(10640)},
+ &CodePointRange{From: rune(10642), To: rune(10642)},
+ &CodePointRange{From: rune(10644), To: rune(10644)},
+ &CodePointRange{From: rune(10646), To: rune(10646)},
+ &CodePointRange{From: rune(10648), To: rune(10648)},
+ &CodePointRange{From: rune(10713), To: rune(10713)},
+ &CodePointRange{From: rune(10715), To: rune(10715)},
+ &CodePointRange{From: rune(10749), To: rune(10749)},
+ &CodePointRange{From: rune(11811), To: rune(11811)},
+ &CodePointRange{From: rune(11813), To: rune(11813)},
+ &CodePointRange{From: rune(11815), To: rune(11815)},
+ &CodePointRange{From: rune(11817), To: rune(11817)},
+ &CodePointRange{From: rune(12297), To: rune(12297)},
+ &CodePointRange{From: rune(12299), To: rune(12299)},
+ &CodePointRange{From: rune(12301), To: rune(12301)},
+ &CodePointRange{From: rune(12303), To: rune(12303)},
+ &CodePointRange{From: rune(12305), To: rune(12305)},
+ &CodePointRange{From: rune(12309), To: rune(12309)},
+ &CodePointRange{From: rune(12311), To: rune(12311)},
+ &CodePointRange{From: rune(12313), To: rune(12313)},
+ &CodePointRange{From: rune(12315), To: rune(12315)},
+ &CodePointRange{From: rune(12318), To: rune(12319)},
+ &CodePointRange{From: rune(64830), To: rune(64830)},
+ &CodePointRange{From: rune(65048), To: rune(65048)},
+ &CodePointRange{From: rune(65078), To: rune(65078)},
+ &CodePointRange{From: rune(65080), To: rune(65080)},
+ &CodePointRange{From: rune(65082), To: rune(65082)},
+ &CodePointRange{From: rune(65084), To: rune(65084)},
+ &CodePointRange{From: rune(65086), To: rune(65086)},
+ &CodePointRange{From: rune(65088), To: rune(65088)},
+ &CodePointRange{From: rune(65090), To: rune(65090)},
+ &CodePointRange{From: rune(65092), To: rune(65092)},
+ &CodePointRange{From: rune(65096), To: rune(65096)},
+ &CodePointRange{From: rune(65114), To: rune(65114)},
+ &CodePointRange{From: rune(65116), To: rune(65116)},
+ &CodePointRange{From: rune(65118), To: rune(65118)},
+ &CodePointRange{From: rune(65289), To: rune(65289)},
+ &CodePointRange{From: rune(65341), To: rune(65341)},
+ &CodePointRange{From: rune(65373), To: rune(65373)},
+ &CodePointRange{From: rune(65376), To: rune(65376)},
+ &CodePointRange{From: rune(65379), To: rune(65379)},
+ },
+ "pf": {
+ &CodePointRange{From: rune(187), To: rune(187)},
+ &CodePointRange{From: rune(8217), To: rune(8217)},
+ &CodePointRange{From: rune(8221), To: rune(8221)},
+ &CodePointRange{From: rune(8250), To: rune(8250)},
+ &CodePointRange{From: rune(11779), To: rune(11779)},
+ &CodePointRange{From: rune(11781), To: rune(11781)},
+ &CodePointRange{From: rune(11786), To: rune(11786)},
+ &CodePointRange{From: rune(11789), To: rune(11789)},
+ &CodePointRange{From: rune(11805), To: rune(11805)},
+ &CodePointRange{From: rune(11809), To: rune(11809)},
+ },
+ "pi": {
+ &CodePointRange{From: rune(171), To: rune(171)},
+ &CodePointRange{From: rune(8216), To: rune(8216)},
+ &CodePointRange{From: rune(8219), To: rune(8220)},
+ &CodePointRange{From: rune(8223), To: rune(8223)},
+ &CodePointRange{From: rune(8249), To: rune(8249)},
+ &CodePointRange{From: rune(11778), To: rune(11778)},
+ &CodePointRange{From: rune(11780), To: rune(11780)},
+ &CodePointRange{From: rune(11785), To: rune(11785)},
+ &CodePointRange{From: rune(11788), To: rune(11788)},
+ &CodePointRange{From: rune(11804), To: rune(11804)},
+ &CodePointRange{From: rune(11808), To: rune(11808)},
+ },
+ "po": {
+ &CodePointRange{From: rune(33), To: rune(35)},
+ &CodePointRange{From: rune(37), To: rune(39)},
+ &CodePointRange{From: rune(42), To: rune(42)},
+ &CodePointRange{From: rune(44), To: rune(44)},
+ &CodePointRange{From: rune(46), To: rune(47)},
+ &CodePointRange{From: rune(58), To: rune(59)},
+ &CodePointRange{From: rune(63), To: rune(64)},
+ &CodePointRange{From: rune(92), To: rune(92)},
+ &CodePointRange{From: rune(161), To: rune(161)},
+ &CodePointRange{From: rune(167), To: rune(167)},
+ &CodePointRange{From: rune(182), To: rune(183)},
+ &CodePointRange{From: rune(191), To: rune(191)},
+ &CodePointRange{From: rune(894), To: rune(894)},
+ &CodePointRange{From: rune(903), To: rune(903)},
+ &CodePointRange{From: rune(1370), To: rune(1375)},
+ &CodePointRange{From: rune(1417), To: rune(1417)},
+ &CodePointRange{From: rune(1472), To: rune(1472)},
+ &CodePointRange{From: rune(1475), To: rune(1475)},
+ &CodePointRange{From: rune(1478), To: rune(1478)},
+ &CodePointRange{From: rune(1523), To: rune(1524)},
+ &CodePointRange{From: rune(1545), To: rune(1546)},
+ &CodePointRange{From: rune(1548), To: rune(1549)},
+ &CodePointRange{From: rune(1563), To: rune(1563)},
+ &CodePointRange{From: rune(1566), To: rune(1567)},
+ &CodePointRange{From: rune(1642), To: rune(1645)},
+ &CodePointRange{From: rune(1748), To: rune(1748)},
+ &CodePointRange{From: rune(1792), To: rune(1805)},
+ &CodePointRange{From: rune(2039), To: rune(2041)},
+ &CodePointRange{From: rune(2096), To: rune(2110)},
+ &CodePointRange{From: rune(2142), To: rune(2142)},
+ &CodePointRange{From: rune(2404), To: rune(2405)},
+ &CodePointRange{From: rune(2416), To: rune(2416)},
+ &CodePointRange{From: rune(2557), To: rune(2557)},
+ &CodePointRange{From: rune(2678), To: rune(2678)},
+ &CodePointRange{From: rune(2800), To: rune(2800)},
+ &CodePointRange{From: rune(3191), To: rune(3191)},
+ &CodePointRange{From: rune(3204), To: rune(3204)},
+ &CodePointRange{From: rune(3572), To: rune(3572)},
+ &CodePointRange{From: rune(3663), To: rune(3663)},
+ &CodePointRange{From: rune(3674), To: rune(3675)},
+ &CodePointRange{From: rune(3844), To: rune(3858)},
+ &CodePointRange{From: rune(3860), To: rune(3860)},
+ &CodePointRange{From: rune(3973), To: rune(3973)},
+ &CodePointRange{From: rune(4048), To: rune(4052)},
+ &CodePointRange{From: rune(4057), To: rune(4058)},
+ &CodePointRange{From: rune(4170), To: rune(4175)},
+ &CodePointRange{From: rune(4347), To: rune(4347)},
+ &CodePointRange{From: rune(4960), To: rune(4968)},
+ &CodePointRange{From: rune(5742), To: rune(5742)},
+ &CodePointRange{From: rune(5867), To: rune(5869)},
+ &CodePointRange{From: rune(5941), To: rune(5942)},
+ &CodePointRange{From: rune(6100), To: rune(6102)},
+ &CodePointRange{From: rune(6104), To: rune(6106)},
+ &CodePointRange{From: rune(6144), To: rune(6149)},
+ &CodePointRange{From: rune(6151), To: rune(6154)},
+ &CodePointRange{From: rune(6468), To: rune(6469)},
+ &CodePointRange{From: rune(6686), To: rune(6687)},
+ &CodePointRange{From: rune(6816), To: rune(6822)},
+ &CodePointRange{From: rune(6824), To: rune(6829)},
+ &CodePointRange{From: rune(7002), To: rune(7008)},
+ &CodePointRange{From: rune(7164), To: rune(7167)},
+ &CodePointRange{From: rune(7227), To: rune(7231)},
+ &CodePointRange{From: rune(7294), To: rune(7295)},
+ &CodePointRange{From: rune(7360), To: rune(7367)},
+ &CodePointRange{From: rune(7379), To: rune(7379)},
+ &CodePointRange{From: rune(8214), To: rune(8215)},
+ &CodePointRange{From: rune(8224), To: rune(8231)},
+ &CodePointRange{From: rune(8240), To: rune(8248)},
+ &CodePointRange{From: rune(8251), To: rune(8254)},
+ &CodePointRange{From: rune(8257), To: rune(8259)},
+ &CodePointRange{From: rune(8263), To: rune(8273)},
+ &CodePointRange{From: rune(8275), To: rune(8275)},
+ &CodePointRange{From: rune(8277), To: rune(8286)},
+ &CodePointRange{From: rune(11513), To: rune(11516)},
+ &CodePointRange{From: rune(11518), To: rune(11519)},
+ &CodePointRange{From: rune(11632), To: rune(11632)},
+ &CodePointRange{From: rune(11776), To: rune(11777)},
+ &CodePointRange{From: rune(11782), To: rune(11784)},
+ &CodePointRange{From: rune(11787), To: rune(11787)},
+ &CodePointRange{From: rune(11790), To: rune(11798)},
+ &CodePointRange{From: rune(11800), To: rune(11801)},
+ &CodePointRange{From: rune(11803), To: rune(11803)},
+ &CodePointRange{From: rune(11806), To: rune(11807)},
+ &CodePointRange{From: rune(11818), To: rune(11822)},
+ &CodePointRange{From: rune(11824), To: rune(11833)},
+ &CodePointRange{From: rune(11836), To: rune(11839)},
+ &CodePointRange{From: rune(11841), To: rune(11841)},
+ &CodePointRange{From: rune(11843), To: rune(11855)},
+ &CodePointRange{From: rune(11858), To: rune(11858)},
+ &CodePointRange{From: rune(12289), To: rune(12291)},
+ &CodePointRange{From: rune(12349), To: rune(12349)},
+ &CodePointRange{From: rune(12539), To: rune(12539)},
+ &CodePointRange{From: rune(42238), To: rune(42239)},
+ &CodePointRange{From: rune(42509), To: rune(42511)},
+ &CodePointRange{From: rune(42611), To: rune(42611)},
+ &CodePointRange{From: rune(42622), To: rune(42622)},
+ &CodePointRange{From: rune(42738), To: rune(42743)},
+ &CodePointRange{From: rune(43124), To: rune(43127)},
+ &CodePointRange{From: rune(43214), To: rune(43215)},
+ &CodePointRange{From: rune(43256), To: rune(43258)},
+ &CodePointRange{From: rune(43260), To: rune(43260)},
+ &CodePointRange{From: rune(43310), To: rune(43311)},
+ &CodePointRange{From: rune(43359), To: rune(43359)},
+ &CodePointRange{From: rune(43457), To: rune(43469)},
+ &CodePointRange{From: rune(43486), To: rune(43487)},
+ &CodePointRange{From: rune(43612), To: rune(43615)},
+ &CodePointRange{From: rune(43742), To: rune(43743)},
+ &CodePointRange{From: rune(43760), To: rune(43761)},
+ &CodePointRange{From: rune(44011), To: rune(44011)},
+ &CodePointRange{From: rune(65040), To: rune(65046)},
+ &CodePointRange{From: rune(65049), To: rune(65049)},
+ &CodePointRange{From: rune(65072), To: rune(65072)},
+ &CodePointRange{From: rune(65093), To: rune(65094)},
+ &CodePointRange{From: rune(65097), To: rune(65100)},
+ &CodePointRange{From: rune(65104), To: rune(65106)},
+ &CodePointRange{From: rune(65108), To: rune(65111)},
+ &CodePointRange{From: rune(65119), To: rune(65121)},
+ &CodePointRange{From: rune(65128), To: rune(65128)},
+ &CodePointRange{From: rune(65130), To: rune(65131)},
+ &CodePointRange{From: rune(65281), To: rune(65283)},
+ &CodePointRange{From: rune(65285), To: rune(65287)},
+ &CodePointRange{From: rune(65290), To: rune(65290)},
+ &CodePointRange{From: rune(65292), To: rune(65292)},
+ &CodePointRange{From: rune(65294), To: rune(65295)},
+ &CodePointRange{From: rune(65306), To: rune(65307)},
+ &CodePointRange{From: rune(65311), To: rune(65312)},
+ &CodePointRange{From: rune(65340), To: rune(65340)},
+ &CodePointRange{From: rune(65377), To: rune(65377)},
+ &CodePointRange{From: rune(65380), To: rune(65381)},
+ &CodePointRange{From: rune(65792), To: rune(65794)},
+ &CodePointRange{From: rune(66463), To: rune(66463)},
+ &CodePointRange{From: rune(66512), To: rune(66512)},
+ &CodePointRange{From: rune(66927), To: rune(66927)},
+ &CodePointRange{From: rune(67671), To: rune(67671)},
+ &CodePointRange{From: rune(67871), To: rune(67871)},
+ &CodePointRange{From: rune(67903), To: rune(67903)},
+ &CodePointRange{From: rune(68176), To: rune(68184)},
+ &CodePointRange{From: rune(68223), To: rune(68223)},
+ &CodePointRange{From: rune(68336), To: rune(68342)},
+ &CodePointRange{From: rune(68409), To: rune(68415)},
+ &CodePointRange{From: rune(68505), To: rune(68508)},
+ &CodePointRange{From: rune(69461), To: rune(69465)},
+ &CodePointRange{From: rune(69703), To: rune(69709)},
+ &CodePointRange{From: rune(69819), To: rune(69820)},
+ &CodePointRange{From: rune(69822), To: rune(69825)},
+ &CodePointRange{From: rune(69952), To: rune(69955)},
+ &CodePointRange{From: rune(70004), To: rune(70005)},
+ &CodePointRange{From: rune(70085), To: rune(70088)},
+ &CodePointRange{From: rune(70093), To: rune(70093)},
+ &CodePointRange{From: rune(70107), To: rune(70107)},
+ &CodePointRange{From: rune(70109), To: rune(70111)},
+ &CodePointRange{From: rune(70200), To: rune(70205)},
+ &CodePointRange{From: rune(70313), To: rune(70313)},
+ &CodePointRange{From: rune(70731), To: rune(70735)},
+ &CodePointRange{From: rune(70746), To: rune(70747)},
+ &CodePointRange{From: rune(70749), To: rune(70749)},
+ &CodePointRange{From: rune(70854), To: rune(70854)},
+ &CodePointRange{From: rune(71105), To: rune(71127)},
+ &CodePointRange{From: rune(71233), To: rune(71235)},
+ &CodePointRange{From: rune(71264), To: rune(71276)},
+ &CodePointRange{From: rune(71484), To: rune(71486)},
+ &CodePointRange{From: rune(71739), To: rune(71739)},
+ &CodePointRange{From: rune(72004), To: rune(72006)},
+ &CodePointRange{From: rune(72162), To: rune(72162)},
+ &CodePointRange{From: rune(72255), To: rune(72262)},
+ &CodePointRange{From: rune(72346), To: rune(72348)},
+ &CodePointRange{From: rune(72350), To: rune(72354)},
+ &CodePointRange{From: rune(72769), To: rune(72773)},
+ &CodePointRange{From: rune(72816), To: rune(72817)},
+ &CodePointRange{From: rune(73463), To: rune(73464)},
+ &CodePointRange{From: rune(73727), To: rune(73727)},
+ &CodePointRange{From: rune(74864), To: rune(74868)},
+ &CodePointRange{From: rune(92782), To: rune(92783)},
+ &CodePointRange{From: rune(92917), To: rune(92917)},
+ &CodePointRange{From: rune(92983), To: rune(92987)},
+ &CodePointRange{From: rune(92996), To: rune(92996)},
+ &CodePointRange{From: rune(93847), To: rune(93850)},
+ &CodePointRange{From: rune(94178), To: rune(94178)},
+ &CodePointRange{From: rune(113823), To: rune(113823)},
+ &CodePointRange{From: rune(121479), To: rune(121483)},
+ &CodePointRange{From: rune(125278), To: rune(125279)},
+ },
+ "ps": {
+ &CodePointRange{From: rune(40), To: rune(40)},
+ &CodePointRange{From: rune(91), To: rune(91)},
+ &CodePointRange{From: rune(123), To: rune(123)},
+ &CodePointRange{From: rune(3898), To: rune(3898)},
+ &CodePointRange{From: rune(3900), To: rune(3900)},
+ &CodePointRange{From: rune(5787), To: rune(5787)},
+ &CodePointRange{From: rune(8218), To: rune(8218)},
+ &CodePointRange{From: rune(8222), To: rune(8222)},
+ &CodePointRange{From: rune(8261), To: rune(8261)},
+ &CodePointRange{From: rune(8317), To: rune(8317)},
+ &CodePointRange{From: rune(8333), To: rune(8333)},
+ &CodePointRange{From: rune(8968), To: rune(8968)},
+ &CodePointRange{From: rune(8970), To: rune(8970)},
+ &CodePointRange{From: rune(9001), To: rune(9001)},
+ &CodePointRange{From: rune(10088), To: rune(10088)},
+ &CodePointRange{From: rune(10090), To: rune(10090)},
+ &CodePointRange{From: rune(10092), To: rune(10092)},
+ &CodePointRange{From: rune(10094), To: rune(10094)},
+ &CodePointRange{From: rune(10096), To: rune(10096)},
+ &CodePointRange{From: rune(10098), To: rune(10098)},
+ &CodePointRange{From: rune(10100), To: rune(10100)},
+ &CodePointRange{From: rune(10181), To: rune(10181)},
+ &CodePointRange{From: rune(10214), To: rune(10214)},
+ &CodePointRange{From: rune(10216), To: rune(10216)},
+ &CodePointRange{From: rune(10218), To: rune(10218)},
+ &CodePointRange{From: rune(10220), To: rune(10220)},
+ &CodePointRange{From: rune(10222), To: rune(10222)},
+ &CodePointRange{From: rune(10627), To: rune(10627)},
+ &CodePointRange{From: rune(10629), To: rune(10629)},
+ &CodePointRange{From: rune(10631), To: rune(10631)},
+ &CodePointRange{From: rune(10633), To: rune(10633)},
+ &CodePointRange{From: rune(10635), To: rune(10635)},
+ &CodePointRange{From: rune(10637), To: rune(10637)},
+ &CodePointRange{From: rune(10639), To: rune(10639)},
+ &CodePointRange{From: rune(10641), To: rune(10641)},
+ &CodePointRange{From: rune(10643), To: rune(10643)},
+ &CodePointRange{From: rune(10645), To: rune(10645)},
+ &CodePointRange{From: rune(10647), To: rune(10647)},
+ &CodePointRange{From: rune(10712), To: rune(10712)},
+ &CodePointRange{From: rune(10714), To: rune(10714)},
+ &CodePointRange{From: rune(10748), To: rune(10748)},
+ &CodePointRange{From: rune(11810), To: rune(11810)},
+ &CodePointRange{From: rune(11812), To: rune(11812)},
+ &CodePointRange{From: rune(11814), To: rune(11814)},
+ &CodePointRange{From: rune(11816), To: rune(11816)},
+ &CodePointRange{From: rune(11842), To: rune(11842)},
+ &CodePointRange{From: rune(12296), To: rune(12296)},
+ &CodePointRange{From: rune(12298), To: rune(12298)},
+ &CodePointRange{From: rune(12300), To: rune(12300)},
+ &CodePointRange{From: rune(12302), To: rune(12302)},
+ &CodePointRange{From: rune(12304), To: rune(12304)},
+ &CodePointRange{From: rune(12308), To: rune(12308)},
+ &CodePointRange{From: rune(12310), To: rune(12310)},
+ &CodePointRange{From: rune(12312), To: rune(12312)},
+ &CodePointRange{From: rune(12314), To: rune(12314)},
+ &CodePointRange{From: rune(12317), To: rune(12317)},
+ &CodePointRange{From: rune(64831), To: rune(64831)},
+ &CodePointRange{From: rune(65047), To: rune(65047)},
+ &CodePointRange{From: rune(65077), To: rune(65077)},
+ &CodePointRange{From: rune(65079), To: rune(65079)},
+ &CodePointRange{From: rune(65081), To: rune(65081)},
+ &CodePointRange{From: rune(65083), To: rune(65083)},
+ &CodePointRange{From: rune(65085), To: rune(65085)},
+ &CodePointRange{From: rune(65087), To: rune(65087)},
+ &CodePointRange{From: rune(65089), To: rune(65089)},
+ &CodePointRange{From: rune(65091), To: rune(65091)},
+ &CodePointRange{From: rune(65095), To: rune(65095)},
+ &CodePointRange{From: rune(65113), To: rune(65113)},
+ &CodePointRange{From: rune(65115), To: rune(65115)},
+ &CodePointRange{From: rune(65117), To: rune(65117)},
+ &CodePointRange{From: rune(65288), To: rune(65288)},
+ &CodePointRange{From: rune(65339), To: rune(65339)},
+ &CodePointRange{From: rune(65371), To: rune(65371)},
+ &CodePointRange{From: rune(65375), To: rune(65375)},
+ &CodePointRange{From: rune(65378), To: rune(65378)},
+ },
+ "sc": {
+ &CodePointRange{From: rune(36), To: rune(36)},
+ &CodePointRange{From: rune(162), To: rune(165)},
+ &CodePointRange{From: rune(1423), To: rune(1423)},
+ &CodePointRange{From: rune(1547), To: rune(1547)},
+ &CodePointRange{From: rune(2046), To: rune(2047)},
+ &CodePointRange{From: rune(2546), To: rune(2547)},
+ &CodePointRange{From: rune(2555), To: rune(2555)},
+ &CodePointRange{From: rune(2801), To: rune(2801)},
+ &CodePointRange{From: rune(3065), To: rune(3065)},
+ &CodePointRange{From: rune(3647), To: rune(3647)},
+ &CodePointRange{From: rune(6107), To: rune(6107)},
+ &CodePointRange{From: rune(8352), To: rune(8383)},
+ &CodePointRange{From: rune(43064), To: rune(43064)},
+ &CodePointRange{From: rune(65020), To: rune(65020)},
+ &CodePointRange{From: rune(65129), To: rune(65129)},
+ &CodePointRange{From: rune(65284), To: rune(65284)},
+ &CodePointRange{From: rune(65504), To: rune(65505)},
+ &CodePointRange{From: rune(65509), To: rune(65510)},
+ &CodePointRange{From: rune(73693), To: rune(73696)},
+ &CodePointRange{From: rune(123647), To: rune(123647)},
+ &CodePointRange{From: rune(126128), To: rune(126128)},
+ },
+ "sk": {
+ &CodePointRange{From: rune(94), To: rune(94)},
+ &CodePointRange{From: rune(96), To: rune(96)},
+ &CodePointRange{From: rune(168), To: rune(168)},
+ &CodePointRange{From: rune(175), To: rune(175)},
+ &CodePointRange{From: rune(180), To: rune(180)},
+ &CodePointRange{From: rune(184), To: rune(184)},
+ &CodePointRange{From: rune(706), To: rune(709)},
+ &CodePointRange{From: rune(722), To: rune(735)},
+ &CodePointRange{From: rune(741), To: rune(747)},
+ &CodePointRange{From: rune(749), To: rune(749)},
+ &CodePointRange{From: rune(751), To: rune(767)},
+ &CodePointRange{From: rune(885), To: rune(885)},
+ &CodePointRange{From: rune(900), To: rune(901)},
+ &CodePointRange{From: rune(8125), To: rune(8125)},
+ &CodePointRange{From: rune(8127), To: rune(8129)},
+ &CodePointRange{From: rune(8141), To: rune(8143)},
+ &CodePointRange{From: rune(8157), To: rune(8159)},
+ &CodePointRange{From: rune(8173), To: rune(8175)},
+ &CodePointRange{From: rune(8189), To: rune(8190)},
+ &CodePointRange{From: rune(12443), To: rune(12444)},
+ &CodePointRange{From: rune(42752), To: rune(42774)},
+ &CodePointRange{From: rune(42784), To: rune(42785)},
+ &CodePointRange{From: rune(42889), To: rune(42890)},
+ &CodePointRange{From: rune(43867), To: rune(43867)},
+ &CodePointRange{From: rune(43882), To: rune(43883)},
+ &CodePointRange{From: rune(64434), To: rune(64449)},
+ &CodePointRange{From: rune(65342), To: rune(65342)},
+ &CodePointRange{From: rune(65344), To: rune(65344)},
+ &CodePointRange{From: rune(65507), To: rune(65507)},
+ &CodePointRange{From: rune(127995), To: rune(127999)},
+ },
+ "sm": {
+ &CodePointRange{From: rune(43), To: rune(43)},
+ &CodePointRange{From: rune(60), To: rune(62)},
+ &CodePointRange{From: rune(124), To: rune(124)},
+ &CodePointRange{From: rune(126), To: rune(126)},
+ &CodePointRange{From: rune(172), To: rune(172)},
+ &CodePointRange{From: rune(177), To: rune(177)},
+ &CodePointRange{From: rune(215), To: rune(215)},
+ &CodePointRange{From: rune(247), To: rune(247)},
+ &CodePointRange{From: rune(1014), To: rune(1014)},
+ &CodePointRange{From: rune(1542), To: rune(1544)},
+ &CodePointRange{From: rune(8260), To: rune(8260)},
+ &CodePointRange{From: rune(8274), To: rune(8274)},
+ &CodePointRange{From: rune(8314), To: rune(8316)},
+ &CodePointRange{From: rune(8330), To: rune(8332)},
+ &CodePointRange{From: rune(8472), To: rune(8472)},
+ &CodePointRange{From: rune(8512), To: rune(8516)},
+ &CodePointRange{From: rune(8523), To: rune(8523)},
+ &CodePointRange{From: rune(8592), To: rune(8596)},
+ &CodePointRange{From: rune(8602), To: rune(8603)},
+ &CodePointRange{From: rune(8608), To: rune(8608)},
+ &CodePointRange{From: rune(8611), To: rune(8611)},
+ &CodePointRange{From: rune(8614), To: rune(8614)},
+ &CodePointRange{From: rune(8622), To: rune(8622)},
+ &CodePointRange{From: rune(8654), To: rune(8655)},
+ &CodePointRange{From: rune(8658), To: rune(8658)},
+ &CodePointRange{From: rune(8660), To: rune(8660)},
+ &CodePointRange{From: rune(8692), To: rune(8959)},
+ &CodePointRange{From: rune(8992), To: rune(8993)},
+ &CodePointRange{From: rune(9084), To: rune(9084)},
+ &CodePointRange{From: rune(9115), To: rune(9139)},
+ &CodePointRange{From: rune(9180), To: rune(9185)},
+ &CodePointRange{From: rune(9655), To: rune(9655)},
+ &CodePointRange{From: rune(9665), To: rune(9665)},
+ &CodePointRange{From: rune(9720), To: rune(9727)},
+ &CodePointRange{From: rune(9839), To: rune(9839)},
+ &CodePointRange{From: rune(10176), To: rune(10180)},
+ &CodePointRange{From: rune(10183), To: rune(10213)},
+ &CodePointRange{From: rune(10224), To: rune(10239)},
+ &CodePointRange{From: rune(10496), To: rune(10626)},
+ &CodePointRange{From: rune(10649), To: rune(10711)},
+ &CodePointRange{From: rune(10716), To: rune(10747)},
+ &CodePointRange{From: rune(10750), To: rune(11007)},
+ &CodePointRange{From: rune(11056), To: rune(11076)},
+ &CodePointRange{From: rune(11079), To: rune(11084)},
+ &CodePointRange{From: rune(64297), To: rune(64297)},
+ &CodePointRange{From: rune(65122), To: rune(65122)},
+ &CodePointRange{From: rune(65124), To: rune(65126)},
+ &CodePointRange{From: rune(65291), To: rune(65291)},
+ &CodePointRange{From: rune(65308), To: rune(65310)},
+ &CodePointRange{From: rune(65372), To: rune(65372)},
+ &CodePointRange{From: rune(65374), To: rune(65374)},
+ &CodePointRange{From: rune(65506), To: rune(65506)},
+ &CodePointRange{From: rune(65513), To: rune(65516)},
+ &CodePointRange{From: rune(120513), To: rune(120513)},
+ &CodePointRange{From: rune(120539), To: rune(120539)},
+ &CodePointRange{From: rune(120571), To: rune(120571)},
+ &CodePointRange{From: rune(120597), To: rune(120597)},
+ &CodePointRange{From: rune(120629), To: rune(120629)},
+ &CodePointRange{From: rune(120655), To: rune(120655)},
+ &CodePointRange{From: rune(120687), To: rune(120687)},
+ &CodePointRange{From: rune(120713), To: rune(120713)},
+ &CodePointRange{From: rune(120745), To: rune(120745)},
+ &CodePointRange{From: rune(120771), To: rune(120771)},
+ &CodePointRange{From: rune(126704), To: rune(126705)},
+ },
+ "so": {
+ &CodePointRange{From: rune(166), To: rune(166)},
+ &CodePointRange{From: rune(169), To: rune(169)},
+ &CodePointRange{From: rune(174), To: rune(174)},
+ &CodePointRange{From: rune(176), To: rune(176)},
+ &CodePointRange{From: rune(1154), To: rune(1154)},
+ &CodePointRange{From: rune(1421), To: rune(1422)},
+ &CodePointRange{From: rune(1550), To: rune(1551)},
+ &CodePointRange{From: rune(1758), To: rune(1758)},
+ &CodePointRange{From: rune(1769), To: rune(1769)},
+ &CodePointRange{From: rune(1789), To: rune(1790)},
+ &CodePointRange{From: rune(2038), To: rune(2038)},
+ &CodePointRange{From: rune(2554), To: rune(2554)},
+ &CodePointRange{From: rune(2928), To: rune(2928)},
+ &CodePointRange{From: rune(3059), To: rune(3064)},
+ &CodePointRange{From: rune(3066), To: rune(3066)},
+ &CodePointRange{From: rune(3199), To: rune(3199)},
+ &CodePointRange{From: rune(3407), To: rune(3407)},
+ &CodePointRange{From: rune(3449), To: rune(3449)},
+ &CodePointRange{From: rune(3841), To: rune(3843)},
+ &CodePointRange{From: rune(3859), To: rune(3859)},
+ &CodePointRange{From: rune(3861), To: rune(3863)},
+ &CodePointRange{From: rune(3866), To: rune(3871)},
+ &CodePointRange{From: rune(3892), To: rune(3892)},
+ &CodePointRange{From: rune(3894), To: rune(3894)},
+ &CodePointRange{From: rune(3896), To: rune(3896)},
+ &CodePointRange{From: rune(4030), To: rune(4037)},
+ &CodePointRange{From: rune(4039), To: rune(4044)},
+ &CodePointRange{From: rune(4046), To: rune(4047)},
+ &CodePointRange{From: rune(4053), To: rune(4056)},
+ &CodePointRange{From: rune(4254), To: rune(4255)},
+ &CodePointRange{From: rune(5008), To: rune(5017)},
+ &CodePointRange{From: rune(5741), To: rune(5741)},
+ &CodePointRange{From: rune(6464), To: rune(6464)},
+ &CodePointRange{From: rune(6622), To: rune(6655)},
+ &CodePointRange{From: rune(7009), To: rune(7018)},
+ &CodePointRange{From: rune(7028), To: rune(7036)},
+ &CodePointRange{From: rune(8448), To: rune(8449)},
+ &CodePointRange{From: rune(8451), To: rune(8454)},
+ &CodePointRange{From: rune(8456), To: rune(8457)},
+ &CodePointRange{From: rune(8468), To: rune(8468)},
+ &CodePointRange{From: rune(8470), To: rune(8471)},
+ &CodePointRange{From: rune(8478), To: rune(8483)},
+ &CodePointRange{From: rune(8485), To: rune(8485)},
+ &CodePointRange{From: rune(8487), To: rune(8487)},
+ &CodePointRange{From: rune(8489), To: rune(8489)},
+ &CodePointRange{From: rune(8494), To: rune(8494)},
+ &CodePointRange{From: rune(8506), To: rune(8507)},
+ &CodePointRange{From: rune(8522), To: rune(8522)},
+ &CodePointRange{From: rune(8524), To: rune(8525)},
+ &CodePointRange{From: rune(8527), To: rune(8527)},
+ &CodePointRange{From: rune(8586), To: rune(8587)},
+ &CodePointRange{From: rune(8597), To: rune(8601)},
+ &CodePointRange{From: rune(8604), To: rune(8607)},
+ &CodePointRange{From: rune(8609), To: rune(8610)},
+ &CodePointRange{From: rune(8612), To: rune(8613)},
+ &CodePointRange{From: rune(8615), To: rune(8621)},
+ &CodePointRange{From: rune(8623), To: rune(8653)},
+ &CodePointRange{From: rune(8656), To: rune(8657)},
+ &CodePointRange{From: rune(8659), To: rune(8659)},
+ &CodePointRange{From: rune(8661), To: rune(8691)},
+ &CodePointRange{From: rune(8960), To: rune(8967)},
+ &CodePointRange{From: rune(8972), To: rune(8991)},
+ &CodePointRange{From: rune(8994), To: rune(9000)},
+ &CodePointRange{From: rune(9003), To: rune(9083)},
+ &CodePointRange{From: rune(9085), To: rune(9114)},
+ &CodePointRange{From: rune(9140), To: rune(9179)},
+ &CodePointRange{From: rune(9186), To: rune(9254)},
+ &CodePointRange{From: rune(9280), To: rune(9290)},
+ &CodePointRange{From: rune(9372), To: rune(9449)},
+ &CodePointRange{From: rune(9472), To: rune(9654)},
+ &CodePointRange{From: rune(9656), To: rune(9664)},
+ &CodePointRange{From: rune(9666), To: rune(9719)},
+ &CodePointRange{From: rune(9728), To: rune(9838)},
+ &CodePointRange{From: rune(9840), To: rune(10087)},
+ &CodePointRange{From: rune(10132), To: rune(10175)},
+ &CodePointRange{From: rune(10240), To: rune(10495)},
+ &CodePointRange{From: rune(11008), To: rune(11055)},
+ &CodePointRange{From: rune(11077), To: rune(11078)},
+ &CodePointRange{From: rune(11085), To: rune(11123)},
+ &CodePointRange{From: rune(11126), To: rune(11157)},
+ &CodePointRange{From: rune(11159), To: rune(11263)},
+ &CodePointRange{From: rune(11493), To: rune(11498)},
+ &CodePointRange{From: rune(11856), To: rune(11857)},
+ &CodePointRange{From: rune(11904), To: rune(11929)},
+ &CodePointRange{From: rune(11931), To: rune(12019)},
+ &CodePointRange{From: rune(12032), To: rune(12245)},
+ &CodePointRange{From: rune(12272), To: rune(12283)},
+ &CodePointRange{From: rune(12292), To: rune(12292)},
+ &CodePointRange{From: rune(12306), To: rune(12307)},
+ &CodePointRange{From: rune(12320), To: rune(12320)},
+ &CodePointRange{From: rune(12342), To: rune(12343)},
+ &CodePointRange{From: rune(12350), To: rune(12351)},
+ &CodePointRange{From: rune(12688), To: rune(12689)},
+ &CodePointRange{From: rune(12694), To: rune(12703)},
+ &CodePointRange{From: rune(12736), To: rune(12771)},
+ &CodePointRange{From: rune(12800), To: rune(12830)},
+ &CodePointRange{From: rune(12842), To: rune(12871)},
+ &CodePointRange{From: rune(12880), To: rune(12880)},
+ &CodePointRange{From: rune(12896), To: rune(12927)},
+ &CodePointRange{From: rune(12938), To: rune(12976)},
+ &CodePointRange{From: rune(12992), To: rune(13311)},
+ &CodePointRange{From: rune(19904), To: rune(19967)},
+ &CodePointRange{From: rune(42128), To: rune(42182)},
+ &CodePointRange{From: rune(43048), To: rune(43051)},
+ &CodePointRange{From: rune(43062), To: rune(43063)},
+ &CodePointRange{From: rune(43065), To: rune(43065)},
+ &CodePointRange{From: rune(43639), To: rune(43641)},
+ &CodePointRange{From: rune(65021), To: rune(65021)},
+ &CodePointRange{From: rune(65508), To: rune(65508)},
+ &CodePointRange{From: rune(65512), To: rune(65512)},
+ &CodePointRange{From: rune(65517), To: rune(65518)},
+ &CodePointRange{From: rune(65532), To: rune(65533)},
+ &CodePointRange{From: rune(65847), To: rune(65855)},
+ &CodePointRange{From: rune(65913), To: rune(65929)},
+ &CodePointRange{From: rune(65932), To: rune(65934)},
+ &CodePointRange{From: rune(65936), To: rune(65948)},
+ &CodePointRange{From: rune(65952), To: rune(65952)},
+ &CodePointRange{From: rune(66000), To: rune(66044)},
+ &CodePointRange{From: rune(67703), To: rune(67704)},
+ &CodePointRange{From: rune(68296), To: rune(68296)},
+ &CodePointRange{From: rune(71487), To: rune(71487)},
+ &CodePointRange{From: rune(73685), To: rune(73692)},
+ &CodePointRange{From: rune(73697), To: rune(73713)},
+ &CodePointRange{From: rune(92988), To: rune(92991)},
+ &CodePointRange{From: rune(92997), To: rune(92997)},
+ &CodePointRange{From: rune(113820), To: rune(113820)},
+ &CodePointRange{From: rune(118784), To: rune(119029)},
+ &CodePointRange{From: rune(119040), To: rune(119078)},
+ &CodePointRange{From: rune(119081), To: rune(119140)},
+ &CodePointRange{From: rune(119146), To: rune(119148)},
+ &CodePointRange{From: rune(119171), To: rune(119172)},
+ &CodePointRange{From: rune(119180), To: rune(119209)},
+ &CodePointRange{From: rune(119214), To: rune(119272)},
+ &CodePointRange{From: rune(119296), To: rune(119361)},
+ &CodePointRange{From: rune(119365), To: rune(119365)},
+ &CodePointRange{From: rune(119552), To: rune(119638)},
+ &CodePointRange{From: rune(120832), To: rune(121343)},
+ &CodePointRange{From: rune(121399), To: rune(121402)},
+ &CodePointRange{From: rune(121453), To: rune(121460)},
+ &CodePointRange{From: rune(121462), To: rune(121475)},
+ &CodePointRange{From: rune(121477), To: rune(121478)},
+ &CodePointRange{From: rune(123215), To: rune(123215)},
+ &CodePointRange{From: rune(126124), To: rune(126124)},
+ &CodePointRange{From: rune(126254), To: rune(126254)},
+ &CodePointRange{From: rune(126976), To: rune(127019)},
+ &CodePointRange{From: rune(127024), To: rune(127123)},
+ &CodePointRange{From: rune(127136), To: rune(127150)},
+ &CodePointRange{From: rune(127153), To: rune(127167)},
+ &CodePointRange{From: rune(127169), To: rune(127183)},
+ &CodePointRange{From: rune(127185), To: rune(127221)},
+ &CodePointRange{From: rune(127245), To: rune(127405)},
+ &CodePointRange{From: rune(127462), To: rune(127490)},
+ &CodePointRange{From: rune(127504), To: rune(127547)},
+ &CodePointRange{From: rune(127552), To: rune(127560)},
+ &CodePointRange{From: rune(127568), To: rune(127569)},
+ &CodePointRange{From: rune(127584), To: rune(127589)},
+ &CodePointRange{From: rune(127744), To: rune(127994)},
+ &CodePointRange{From: rune(128000), To: rune(128727)},
+ &CodePointRange{From: rune(128736), To: rune(128748)},
+ &CodePointRange{From: rune(128752), To: rune(128764)},
+ &CodePointRange{From: rune(128768), To: rune(128883)},
+ &CodePointRange{From: rune(128896), To: rune(128984)},
+ &CodePointRange{From: rune(128992), To: rune(129003)},
+ &CodePointRange{From: rune(129024), To: rune(129035)},
+ &CodePointRange{From: rune(129040), To: rune(129095)},
+ &CodePointRange{From: rune(129104), To: rune(129113)},
+ &CodePointRange{From: rune(129120), To: rune(129159)},
+ &CodePointRange{From: rune(129168), To: rune(129197)},
+ &CodePointRange{From: rune(129200), To: rune(129201)},
+ &CodePointRange{From: rune(129280), To: rune(129400)},
+ &CodePointRange{From: rune(129402), To: rune(129483)},
+ &CodePointRange{From: rune(129485), To: rune(129619)},
+ &CodePointRange{From: rune(129632), To: rune(129645)},
+ &CodePointRange{From: rune(129648), To: rune(129652)},
+ &CodePointRange{From: rune(129656), To: rune(129658)},
+ &CodePointRange{From: rune(129664), To: rune(129670)},
+ &CodePointRange{From: rune(129680), To: rune(129704)},
+ &CodePointRange{From: rune(129712), To: rune(129718)},
+ &CodePointRange{From: rune(129728), To: rune(129730)},
+ &CodePointRange{From: rune(129744), To: rune(129750)},
+ &CodePointRange{From: rune(129792), To: rune(129938)},
+ &CodePointRange{From: rune(129940), To: rune(129994)},
+ },
+ "zl": {
+ &CodePointRange{From: rune(8232), To: rune(8232)},
+ },
+ "zp": {
+ &CodePointRange{From: rune(8233), To: rune(8233)},
+ },
+ "zs": {
+ &CodePointRange{From: rune(32), To: rune(32)},
+ &CodePointRange{From: rune(160), To: rune(160)},
+ &CodePointRange{From: rune(5760), To: rune(5760)},
+ &CodePointRange{From: rune(8192), To: rune(8202)},
+ &CodePointRange{From: rune(8239), To: rune(8239)},
+ &CodePointRange{From: rune(8287), To: rune(8287)},
+ &CodePointRange{From: rune(12288), To: rune(12288)},
+ },
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/Scripts.txt
+var (
+ scriptDefaultRange = &CodePointRange{
+ From: rune(0),
+ To: rune(1114111),
+ }
+ scriptDefaultValue = "unknown"
+)
+
+// https://www.unicode.org/Public/13.0.0/ucd/Scripts.txt
+var scriptCodepoints = map[string][]*CodePointRange{
+ "adlm": {
+ &CodePointRange{From: rune(125184), To: rune(125251)},
+ &CodePointRange{From: rune(125252), To: rune(125258)},
+ &CodePointRange{From: rune(125259), To: rune(125259)},
+ &CodePointRange{From: rune(125264), To: rune(125273)},
+ &CodePointRange{From: rune(125278), To: rune(125279)},
+ },
+ "aghb": {
+ &CodePointRange{From: rune(66864), To: rune(66915)},
+ &CodePointRange{From: rune(66927), To: rune(66927)},
+ },
+ "ahom": {
+ &CodePointRange{From: rune(71424), To: rune(71450)},
+ &CodePointRange{From: rune(71453), To: rune(71455)},
+ &CodePointRange{From: rune(71456), To: rune(71457)},
+ &CodePointRange{From: rune(71458), To: rune(71461)},
+ &CodePointRange{From: rune(71462), To: rune(71462)},
+ &CodePointRange{From: rune(71463), To: rune(71467)},
+ &CodePointRange{From: rune(71472), To: rune(71481)},
+ &CodePointRange{From: rune(71482), To: rune(71483)},
+ &CodePointRange{From: rune(71484), To: rune(71486)},
+ &CodePointRange{From: rune(71487), To: rune(71487)},
+ },
+ "arab": {
+ &CodePointRange{From: rune(1536), To: rune(1540)},
+ &CodePointRange{From: rune(1542), To: rune(1544)},
+ &CodePointRange{From: rune(1545), To: rune(1546)},
+ &CodePointRange{From: rune(1547), To: rune(1547)},
+ &CodePointRange{From: rune(1549), To: rune(1549)},
+ &CodePointRange{From: rune(1550), To: rune(1551)},
+ &CodePointRange{From: rune(1552), To: rune(1562)},
+ &CodePointRange{From: rune(1564), To: rune(1564)},
+ &CodePointRange{From: rune(1566), To: rune(1566)},
+ &CodePointRange{From: rune(1568), To: rune(1599)},
+ &CodePointRange{From: rune(1601), To: rune(1610)},
+ &CodePointRange{From: rune(1622), To: rune(1631)},
+ &CodePointRange{From: rune(1632), To: rune(1641)},
+ &CodePointRange{From: rune(1642), To: rune(1645)},
+ &CodePointRange{From: rune(1646), To: rune(1647)},
+ &CodePointRange{From: rune(1649), To: rune(1747)},
+ &CodePointRange{From: rune(1748), To: rune(1748)},
+ &CodePointRange{From: rune(1749), To: rune(1749)},
+ &CodePointRange{From: rune(1750), To: rune(1756)},
+ &CodePointRange{From: rune(1758), To: rune(1758)},
+ &CodePointRange{From: rune(1759), To: rune(1764)},
+ &CodePointRange{From: rune(1765), To: rune(1766)},
+ &CodePointRange{From: rune(1767), To: rune(1768)},
+ &CodePointRange{From: rune(1769), To: rune(1769)},
+ &CodePointRange{From: rune(1770), To: rune(1773)},
+ &CodePointRange{From: rune(1774), To: rune(1775)},
+ &CodePointRange{From: rune(1776), To: rune(1785)},
+ &CodePointRange{From: rune(1786), To: rune(1788)},
+ &CodePointRange{From: rune(1789), To: rune(1790)},
+ &CodePointRange{From: rune(1791), To: rune(1791)},
+ &CodePointRange{From: rune(1872), To: rune(1919)},
+ &CodePointRange{From: rune(2208), To: rune(2228)},
+ &CodePointRange{From: rune(2230), To: rune(2247)},
+ &CodePointRange{From: rune(2259), To: rune(2273)},
+ &CodePointRange{From: rune(2275), To: rune(2303)},
+ &CodePointRange{From: rune(64336), To: rune(64433)},
+ &CodePointRange{From: rune(64434), To: rune(64449)},
+ &CodePointRange{From: rune(64467), To: rune(64829)},
+ &CodePointRange{From: rune(64848), To: rune(64911)},
+ &CodePointRange{From: rune(64914), To: rune(64967)},
+ &CodePointRange{From: rune(65008), To: rune(65019)},
+ &CodePointRange{From: rune(65020), To: rune(65020)},
+ &CodePointRange{From: rune(65021), To: rune(65021)},
+ &CodePointRange{From: rune(65136), To: rune(65140)},
+ &CodePointRange{From: rune(65142), To: rune(65276)},
+ &CodePointRange{From: rune(69216), To: rune(69246)},
+ &CodePointRange{From: rune(126464), To: rune(126467)},
+ &CodePointRange{From: rune(126469), To: rune(126495)},
+ &CodePointRange{From: rune(126497), To: rune(126498)},
+ &CodePointRange{From: rune(126500), To: rune(126500)},
+ &CodePointRange{From: rune(126503), To: rune(126503)},
+ &CodePointRange{From: rune(126505), To: rune(126514)},
+ &CodePointRange{From: rune(126516), To: rune(126519)},
+ &CodePointRange{From: rune(126521), To: rune(126521)},
+ &CodePointRange{From: rune(126523), To: rune(126523)},
+ &CodePointRange{From: rune(126530), To: rune(126530)},
+ &CodePointRange{From: rune(126535), To: rune(126535)},
+ &CodePointRange{From: rune(126537), To: rune(126537)},
+ &CodePointRange{From: rune(126539), To: rune(126539)},
+ &CodePointRange{From: rune(126541), To: rune(126543)},
+ &CodePointRange{From: rune(126545), To: rune(126546)},
+ &CodePointRange{From: rune(126548), To: rune(126548)},
+ &CodePointRange{From: rune(126551), To: rune(126551)},
+ &CodePointRange{From: rune(126553), To: rune(126553)},
+ &CodePointRange{From: rune(126555), To: rune(126555)},
+ &CodePointRange{From: rune(126557), To: rune(126557)},
+ &CodePointRange{From: rune(126559), To: rune(126559)},
+ &CodePointRange{From: rune(126561), To: rune(126562)},
+ &CodePointRange{From: rune(126564), To: rune(126564)},
+ &CodePointRange{From: rune(126567), To: rune(126570)},
+ &CodePointRange{From: rune(126572), To: rune(126578)},
+ &CodePointRange{From: rune(126580), To: rune(126583)},
+ &CodePointRange{From: rune(126585), To: rune(126588)},
+ &CodePointRange{From: rune(126590), To: rune(126590)},
+ &CodePointRange{From: rune(126592), To: rune(126601)},
+ &CodePointRange{From: rune(126603), To: rune(126619)},
+ &CodePointRange{From: rune(126625), To: rune(126627)},
+ &CodePointRange{From: rune(126629), To: rune(126633)},
+ &CodePointRange{From: rune(126635), To: rune(126651)},
+ &CodePointRange{From: rune(126704), To: rune(126705)},
+ },
+ "armi": {
+ &CodePointRange{From: rune(67648), To: rune(67669)},
+ &CodePointRange{From: rune(67671), To: rune(67671)},
+ &CodePointRange{From: rune(67672), To: rune(67679)},
+ },
+ "armn": {
+ &CodePointRange{From: rune(1329), To: rune(1366)},
+ &CodePointRange{From: rune(1369), To: rune(1369)},
+ &CodePointRange{From: rune(1370), To: rune(1375)},
+ &CodePointRange{From: rune(1376), To: rune(1416)},
+ &CodePointRange{From: rune(1417), To: rune(1417)},
+ &CodePointRange{From: rune(1418), To: rune(1418)},
+ &CodePointRange{From: rune(1421), To: rune(1422)},
+ &CodePointRange{From: rune(1423), To: rune(1423)},
+ &CodePointRange{From: rune(64275), To: rune(64279)},
+ },
+ "avst": {
+ &CodePointRange{From: rune(68352), To: rune(68405)},
+ &CodePointRange{From: rune(68409), To: rune(68415)},
+ },
+ "bali": {
+ &CodePointRange{From: rune(6912), To: rune(6915)},
+ &CodePointRange{From: rune(6916), To: rune(6916)},
+ &CodePointRange{From: rune(6917), To: rune(6963)},
+ &CodePointRange{From: rune(6964), To: rune(6964)},
+ &CodePointRange{From: rune(6965), To: rune(6965)},
+ &CodePointRange{From: rune(6966), To: rune(6970)},
+ &CodePointRange{From: rune(6971), To: rune(6971)},
+ &CodePointRange{From: rune(6972), To: rune(6972)},
+ &CodePointRange{From: rune(6973), To: rune(6977)},
+ &CodePointRange{From: rune(6978), To: rune(6978)},
+ &CodePointRange{From: rune(6979), To: rune(6980)},
+ &CodePointRange{From: rune(6981), To: rune(6987)},
+ &CodePointRange{From: rune(6992), To: rune(7001)},
+ &CodePointRange{From: rune(7002), To: rune(7008)},
+ &CodePointRange{From: rune(7009), To: rune(7018)},
+ &CodePointRange{From: rune(7019), To: rune(7027)},
+ &CodePointRange{From: rune(7028), To: rune(7036)},
+ },
+ "bamu": {
+ &CodePointRange{From: rune(42656), To: rune(42725)},
+ &CodePointRange{From: rune(42726), To: rune(42735)},
+ &CodePointRange{From: rune(42736), To: rune(42737)},
+ &CodePointRange{From: rune(42738), To: rune(42743)},
+ &CodePointRange{From: rune(92160), To: rune(92728)},
+ },
+ "bass": {
+ &CodePointRange{From: rune(92880), To: rune(92909)},
+ &CodePointRange{From: rune(92912), To: rune(92916)},
+ &CodePointRange{From: rune(92917), To: rune(92917)},
+ },
+ "batk": {
+ &CodePointRange{From: rune(7104), To: rune(7141)},
+ &CodePointRange{From: rune(7142), To: rune(7142)},
+ &CodePointRange{From: rune(7143), To: rune(7143)},
+ &CodePointRange{From: rune(7144), To: rune(7145)},
+ &CodePointRange{From: rune(7146), To: rune(7148)},
+ &CodePointRange{From: rune(7149), To: rune(7149)},
+ &CodePointRange{From: rune(7150), To: rune(7150)},
+ &CodePointRange{From: rune(7151), To: rune(7153)},
+ &CodePointRange{From: rune(7154), To: rune(7155)},
+ &CodePointRange{From: rune(7164), To: rune(7167)},
+ },
+ "beng": {
+ &CodePointRange{From: rune(2432), To: rune(2432)},
+ &CodePointRange{From: rune(2433), To: rune(2433)},
+ &CodePointRange{From: rune(2434), To: rune(2435)},
+ &CodePointRange{From: rune(2437), To: rune(2444)},
+ &CodePointRange{From: rune(2447), To: rune(2448)},
+ &CodePointRange{From: rune(2451), To: rune(2472)},
+ &CodePointRange{From: rune(2474), To: rune(2480)},
+ &CodePointRange{From: rune(2482), To: rune(2482)},
+ &CodePointRange{From: rune(2486), To: rune(2489)},
+ &CodePointRange{From: rune(2492), To: rune(2492)},
+ &CodePointRange{From: rune(2493), To: rune(2493)},
+ &CodePointRange{From: rune(2494), To: rune(2496)},
+ &CodePointRange{From: rune(2497), To: rune(2500)},
+ &CodePointRange{From: rune(2503), To: rune(2504)},
+ &CodePointRange{From: rune(2507), To: rune(2508)},
+ &CodePointRange{From: rune(2509), To: rune(2509)},
+ &CodePointRange{From: rune(2510), To: rune(2510)},
+ &CodePointRange{From: rune(2519), To: rune(2519)},
+ &CodePointRange{From: rune(2524), To: rune(2525)},
+ &CodePointRange{From: rune(2527), To: rune(2529)},
+ &CodePointRange{From: rune(2530), To: rune(2531)},
+ &CodePointRange{From: rune(2534), To: rune(2543)},
+ &CodePointRange{From: rune(2544), To: rune(2545)},
+ &CodePointRange{From: rune(2546), To: rune(2547)},
+ &CodePointRange{From: rune(2548), To: rune(2553)},
+ &CodePointRange{From: rune(2554), To: rune(2554)},
+ &CodePointRange{From: rune(2555), To: rune(2555)},
+ &CodePointRange{From: rune(2556), To: rune(2556)},
+ &CodePointRange{From: rune(2557), To: rune(2557)},
+ &CodePointRange{From: rune(2558), To: rune(2558)},
+ },
+ "bhks": {
+ &CodePointRange{From: rune(72704), To: rune(72712)},
+ &CodePointRange{From: rune(72714), To: rune(72750)},
+ &CodePointRange{From: rune(72751), To: rune(72751)},
+ &CodePointRange{From: rune(72752), To: rune(72758)},
+ &CodePointRange{From: rune(72760), To: rune(72765)},
+ &CodePointRange{From: rune(72766), To: rune(72766)},
+ &CodePointRange{From: rune(72767), To: rune(72767)},
+ &CodePointRange{From: rune(72768), To: rune(72768)},
+ &CodePointRange{From: rune(72769), To: rune(72773)},
+ &CodePointRange{From: rune(72784), To: rune(72793)},
+ &CodePointRange{From: rune(72794), To: rune(72812)},
+ },
+ "bopo": {
+ &CodePointRange{From: rune(746), To: rune(747)},
+ &CodePointRange{From: rune(12549), To: rune(12591)},
+ &CodePointRange{From: rune(12704), To: rune(12735)},
+ },
+ "brah": {
+ &CodePointRange{From: rune(69632), To: rune(69632)},
+ &CodePointRange{From: rune(69633), To: rune(69633)},
+ &CodePointRange{From: rune(69634), To: rune(69634)},
+ &CodePointRange{From: rune(69635), To: rune(69687)},
+ &CodePointRange{From: rune(69688), To: rune(69702)},
+ &CodePointRange{From: rune(69703), To: rune(69709)},
+ &CodePointRange{From: rune(69714), To: rune(69733)},
+ &CodePointRange{From: rune(69734), To: rune(69743)},
+ &CodePointRange{From: rune(69759), To: rune(69759)},
+ },
+ "brai": {
+ &CodePointRange{From: rune(10240), To: rune(10495)},
+ },
+ "bugi": {
+ &CodePointRange{From: rune(6656), To: rune(6678)},
+ &CodePointRange{From: rune(6679), To: rune(6680)},
+ &CodePointRange{From: rune(6681), To: rune(6682)},
+ &CodePointRange{From: rune(6683), To: rune(6683)},
+ &CodePointRange{From: rune(6686), To: rune(6687)},
+ },
+ "buhd": {
+ &CodePointRange{From: rune(5952), To: rune(5969)},
+ &CodePointRange{From: rune(5970), To: rune(5971)},
+ },
+ "cakm": {
+ &CodePointRange{From: rune(69888), To: rune(69890)},
+ &CodePointRange{From: rune(69891), To: rune(69926)},
+ &CodePointRange{From: rune(69927), To: rune(69931)},
+ &CodePointRange{From: rune(69932), To: rune(69932)},
+ &CodePointRange{From: rune(69933), To: rune(69940)},
+ &CodePointRange{From: rune(69942), To: rune(69951)},
+ &CodePointRange{From: rune(69952), To: rune(69955)},
+ &CodePointRange{From: rune(69956), To: rune(69956)},
+ &CodePointRange{From: rune(69957), To: rune(69958)},
+ &CodePointRange{From: rune(69959), To: rune(69959)},
+ },
+ "cans": {
+ &CodePointRange{From: rune(5120), To: rune(5120)},
+ &CodePointRange{From: rune(5121), To: rune(5740)},
+ &CodePointRange{From: rune(5741), To: rune(5741)},
+ &CodePointRange{From: rune(5742), To: rune(5742)},
+ &CodePointRange{From: rune(5743), To: rune(5759)},
+ &CodePointRange{From: rune(6320), To: rune(6389)},
+ },
+ "cari": {
+ &CodePointRange{From: rune(66208), To: rune(66256)},
+ },
+ "cham": {
+ &CodePointRange{From: rune(43520), To: rune(43560)},
+ &CodePointRange{From: rune(43561), To: rune(43566)},
+ &CodePointRange{From: rune(43567), To: rune(43568)},
+ &CodePointRange{From: rune(43569), To: rune(43570)},
+ &CodePointRange{From: rune(43571), To: rune(43572)},
+ &CodePointRange{From: rune(43573), To: rune(43574)},
+ &CodePointRange{From: rune(43584), To: rune(43586)},
+ &CodePointRange{From: rune(43587), To: rune(43587)},
+ &CodePointRange{From: rune(43588), To: rune(43595)},
+ &CodePointRange{From: rune(43596), To: rune(43596)},
+ &CodePointRange{From: rune(43597), To: rune(43597)},
+ &CodePointRange{From: rune(43600), To: rune(43609)},
+ &CodePointRange{From: rune(43612), To: rune(43615)},
+ },
+ "cher": {
+ &CodePointRange{From: rune(5024), To: rune(5109)},
+ &CodePointRange{From: rune(5112), To: rune(5117)},
+ &CodePointRange{From: rune(43888), To: rune(43967)},
+ },
+ "chrs": {
+ &CodePointRange{From: rune(69552), To: rune(69572)},
+ &CodePointRange{From: rune(69573), To: rune(69579)},
+ },
+ "copt": {
+ &CodePointRange{From: rune(994), To: rune(1007)},
+ &CodePointRange{From: rune(11392), To: rune(11492)},
+ &CodePointRange{From: rune(11493), To: rune(11498)},
+ &CodePointRange{From: rune(11499), To: rune(11502)},
+ &CodePointRange{From: rune(11503), To: rune(11505)},
+ &CodePointRange{From: rune(11506), To: rune(11507)},
+ &CodePointRange{From: rune(11513), To: rune(11516)},
+ &CodePointRange{From: rune(11517), To: rune(11517)},
+ &CodePointRange{From: rune(11518), To: rune(11519)},
+ },
+ "cprt": {
+ &CodePointRange{From: rune(67584), To: rune(67589)},
+ &CodePointRange{From: rune(67592), To: rune(67592)},
+ &CodePointRange{From: rune(67594), To: rune(67637)},
+ &CodePointRange{From: rune(67639), To: rune(67640)},
+ &CodePointRange{From: rune(67644), To: rune(67644)},
+ &CodePointRange{From: rune(67647), To: rune(67647)},
+ },
+ "cyrl": {
+ &CodePointRange{From: rune(1024), To: rune(1153)},
+ &CodePointRange{From: rune(1154), To: rune(1154)},
+ &CodePointRange{From: rune(1155), To: rune(1156)},
+ &CodePointRange{From: rune(1159), To: rune(1159)},
+ &CodePointRange{From: rune(1160), To: rune(1161)},
+ &CodePointRange{From: rune(1162), To: rune(1327)},
+ &CodePointRange{From: rune(7296), To: rune(7304)},
+ &CodePointRange{From: rune(7467), To: rune(7467)},
+ &CodePointRange{From: rune(7544), To: rune(7544)},
+ &CodePointRange{From: rune(11744), To: rune(11775)},
+ &CodePointRange{From: rune(42560), To: rune(42605)},
+ &CodePointRange{From: rune(42606), To: rune(42606)},
+ &CodePointRange{From: rune(42607), To: rune(42607)},
+ &CodePointRange{From: rune(42608), To: rune(42610)},
+ &CodePointRange{From: rune(42611), To: rune(42611)},
+ &CodePointRange{From: rune(42612), To: rune(42621)},
+ &CodePointRange{From: rune(42622), To: rune(42622)},
+ &CodePointRange{From: rune(42623), To: rune(42623)},
+ &CodePointRange{From: rune(42624), To: rune(42651)},
+ &CodePointRange{From: rune(42652), To: rune(42653)},
+ &CodePointRange{From: rune(42654), To: rune(42655)},
+ &CodePointRange{From: rune(65070), To: rune(65071)},
+ },
+ "deva": {
+ &CodePointRange{From: rune(2304), To: rune(2306)},
+ &CodePointRange{From: rune(2307), To: rune(2307)},
+ &CodePointRange{From: rune(2308), To: rune(2361)},
+ &CodePointRange{From: rune(2362), To: rune(2362)},
+ &CodePointRange{From: rune(2363), To: rune(2363)},
+ &CodePointRange{From: rune(2364), To: rune(2364)},
+ &CodePointRange{From: rune(2365), To: rune(2365)},
+ &CodePointRange{From: rune(2366), To: rune(2368)},
+ &CodePointRange{From: rune(2369), To: rune(2376)},
+ &CodePointRange{From: rune(2377), To: rune(2380)},
+ &CodePointRange{From: rune(2381), To: rune(2381)},
+ &CodePointRange{From: rune(2382), To: rune(2383)},
+ &CodePointRange{From: rune(2384), To: rune(2384)},
+ &CodePointRange{From: rune(2389), To: rune(2391)},
+ &CodePointRange{From: rune(2392), To: rune(2401)},
+ &CodePointRange{From: rune(2402), To: rune(2403)},
+ &CodePointRange{From: rune(2406), To: rune(2415)},
+ &CodePointRange{From: rune(2416), To: rune(2416)},
+ &CodePointRange{From: rune(2417), To: rune(2417)},
+ &CodePointRange{From: rune(2418), To: rune(2431)},
+ &CodePointRange{From: rune(43232), To: rune(43249)},
+ &CodePointRange{From: rune(43250), To: rune(43255)},
+ &CodePointRange{From: rune(43256), To: rune(43258)},
+ &CodePointRange{From: rune(43259), To: rune(43259)},
+ &CodePointRange{From: rune(43260), To: rune(43260)},
+ &CodePointRange{From: rune(43261), To: rune(43262)},
+ &CodePointRange{From: rune(43263), To: rune(43263)},
+ },
+ "diak": {
+ &CodePointRange{From: rune(71936), To: rune(71942)},
+ &CodePointRange{From: rune(71945), To: rune(71945)},
+ &CodePointRange{From: rune(71948), To: rune(71955)},
+ &CodePointRange{From: rune(71957), To: rune(71958)},
+ &CodePointRange{From: rune(71960), To: rune(71983)},
+ &CodePointRange{From: rune(71984), To: rune(71989)},
+ &CodePointRange{From: rune(71991), To: rune(71992)},
+ &CodePointRange{From: rune(71995), To: rune(71996)},
+ &CodePointRange{From: rune(71997), To: rune(71997)},
+ &CodePointRange{From: rune(71998), To: rune(71998)},
+ &CodePointRange{From: rune(71999), To: rune(71999)},
+ &CodePointRange{From: rune(72000), To: rune(72000)},
+ &CodePointRange{From: rune(72001), To: rune(72001)},
+ &CodePointRange{From: rune(72002), To: rune(72002)},
+ &CodePointRange{From: rune(72003), To: rune(72003)},
+ &CodePointRange{From: rune(72004), To: rune(72006)},
+ &CodePointRange{From: rune(72016), To: rune(72025)},
+ },
+ "dogr": {
+ &CodePointRange{From: rune(71680), To: rune(71723)},
+ &CodePointRange{From: rune(71724), To: rune(71726)},
+ &CodePointRange{From: rune(71727), To: rune(71735)},
+ &CodePointRange{From: rune(71736), To: rune(71736)},
+ &CodePointRange{From: rune(71737), To: rune(71738)},
+ &CodePointRange{From: rune(71739), To: rune(71739)},
+ },
+ "dsrt": {
+ &CodePointRange{From: rune(66560), To: rune(66639)},
+ },
+ "dupl": {
+ &CodePointRange{From: rune(113664), To: rune(113770)},
+ &CodePointRange{From: rune(113776), To: rune(113788)},
+ &CodePointRange{From: rune(113792), To: rune(113800)},
+ &CodePointRange{From: rune(113808), To: rune(113817)},
+ &CodePointRange{From: rune(113820), To: rune(113820)},
+ &CodePointRange{From: rune(113821), To: rune(113822)},
+ &CodePointRange{From: rune(113823), To: rune(113823)},
+ },
+ "egyp": {
+ &CodePointRange{From: rune(77824), To: rune(78894)},
+ &CodePointRange{From: rune(78896), To: rune(78904)},
+ },
+ "elba": {
+ &CodePointRange{From: rune(66816), To: rune(66855)},
+ },
+ "elym": {
+ &CodePointRange{From: rune(69600), To: rune(69622)},
+ },
+ "ethi": {
+ &CodePointRange{From: rune(4608), To: rune(4680)},
+ &CodePointRange{From: rune(4682), To: rune(4685)},
+ &CodePointRange{From: rune(4688), To: rune(4694)},
+ &CodePointRange{From: rune(4696), To: rune(4696)},
+ &CodePointRange{From: rune(4698), To: rune(4701)},
+ &CodePointRange{From: rune(4704), To: rune(4744)},
+ &CodePointRange{From: rune(4746), To: rune(4749)},
+ &CodePointRange{From: rune(4752), To: rune(4784)},
+ &CodePointRange{From: rune(4786), To: rune(4789)},
+ &CodePointRange{From: rune(4792), To: rune(4798)},
+ &CodePointRange{From: rune(4800), To: rune(4800)},
+ &CodePointRange{From: rune(4802), To: rune(4805)},
+ &CodePointRange{From: rune(4808), To: rune(4822)},
+ &CodePointRange{From: rune(4824), To: rune(4880)},
+ &CodePointRange{From: rune(4882), To: rune(4885)},
+ &CodePointRange{From: rune(4888), To: rune(4954)},
+ &CodePointRange{From: rune(4957), To: rune(4959)},
+ &CodePointRange{From: rune(4960), To: rune(4968)},
+ &CodePointRange{From: rune(4969), To: rune(4988)},
+ &CodePointRange{From: rune(4992), To: rune(5007)},
+ &CodePointRange{From: rune(5008), To: rune(5017)},
+ &CodePointRange{From: rune(11648), To: rune(11670)},
+ &CodePointRange{From: rune(11680), To: rune(11686)},
+ &CodePointRange{From: rune(11688), To: rune(11694)},
+ &CodePointRange{From: rune(11696), To: rune(11702)},
+ &CodePointRange{From: rune(11704), To: rune(11710)},
+ &CodePointRange{From: rune(11712), To: rune(11718)},
+ &CodePointRange{From: rune(11720), To: rune(11726)},
+ &CodePointRange{From: rune(11728), To: rune(11734)},
+ &CodePointRange{From: rune(11736), To: rune(11742)},
+ &CodePointRange{From: rune(43777), To: rune(43782)},
+ &CodePointRange{From: rune(43785), To: rune(43790)},
+ &CodePointRange{From: rune(43793), To: rune(43798)},
+ &CodePointRange{From: rune(43808), To: rune(43814)},
+ &CodePointRange{From: rune(43816), To: rune(43822)},
+ },
+ "geor": {
+ &CodePointRange{From: rune(4256), To: rune(4293)},
+ &CodePointRange{From: rune(4295), To: rune(4295)},
+ &CodePointRange{From: rune(4301), To: rune(4301)},
+ &CodePointRange{From: rune(4304), To: rune(4346)},
+ &CodePointRange{From: rune(4348), To: rune(4348)},
+ &CodePointRange{From: rune(4349), To: rune(4351)},
+ &CodePointRange{From: rune(7312), To: rune(7354)},
+ &CodePointRange{From: rune(7357), To: rune(7359)},
+ &CodePointRange{From: rune(11520), To: rune(11557)},
+ &CodePointRange{From: rune(11559), To: rune(11559)},
+ &CodePointRange{From: rune(11565), To: rune(11565)},
+ },
+ "glag": {
+ &CodePointRange{From: rune(11264), To: rune(11310)},
+ &CodePointRange{From: rune(11312), To: rune(11358)},
+ &CodePointRange{From: rune(122880), To: rune(122886)},
+ &CodePointRange{From: rune(122888), To: rune(122904)},
+ &CodePointRange{From: rune(122907), To: rune(122913)},
+ &CodePointRange{From: rune(122915), To: rune(122916)},
+ &CodePointRange{From: rune(122918), To: rune(122922)},
+ },
+ "gong": {
+ &CodePointRange{From: rune(73056), To: rune(73061)},
+ &CodePointRange{From: rune(73063), To: rune(73064)},
+ &CodePointRange{From: rune(73066), To: rune(73097)},
+ &CodePointRange{From: rune(73098), To: rune(73102)},
+ &CodePointRange{From: rune(73104), To: rune(73105)},
+ &CodePointRange{From: rune(73107), To: rune(73108)},
+ &CodePointRange{From: rune(73109), To: rune(73109)},
+ &CodePointRange{From: rune(73110), To: rune(73110)},
+ &CodePointRange{From: rune(73111), To: rune(73111)},
+ &CodePointRange{From: rune(73112), To: rune(73112)},
+ &CodePointRange{From: rune(73120), To: rune(73129)},
+ },
+ "gonm": {
+ &CodePointRange{From: rune(72960), To: rune(72966)},
+ &CodePointRange{From: rune(72968), To: rune(72969)},
+ &CodePointRange{From: rune(72971), To: rune(73008)},
+ &CodePointRange{From: rune(73009), To: rune(73014)},
+ &CodePointRange{From: rune(73018), To: rune(73018)},
+ &CodePointRange{From: rune(73020), To: rune(73021)},
+ &CodePointRange{From: rune(73023), To: rune(73029)},
+ &CodePointRange{From: rune(73030), To: rune(73030)},
+ &CodePointRange{From: rune(73031), To: rune(73031)},
+ &CodePointRange{From: rune(73040), To: rune(73049)},
+ },
+ "goth": {
+ &CodePointRange{From: rune(66352), To: rune(66368)},
+ &CodePointRange{From: rune(66369), To: rune(66369)},
+ &CodePointRange{From: rune(66370), To: rune(66377)},
+ &CodePointRange{From: rune(66378), To: rune(66378)},
+ },
+ "gran": {
+ &CodePointRange{From: rune(70400), To: rune(70401)},
+ &CodePointRange{From: rune(70402), To: rune(70403)},
+ &CodePointRange{From: rune(70405), To: rune(70412)},
+ &CodePointRange{From: rune(70415), To: rune(70416)},
+ &CodePointRange{From: rune(70419), To: rune(70440)},
+ &CodePointRange{From: rune(70442), To: rune(70448)},
+ &CodePointRange{From: rune(70450), To: rune(70451)},
+ &CodePointRange{From: rune(70453), To: rune(70457)},
+ &CodePointRange{From: rune(70460), To: rune(70460)},
+ &CodePointRange{From: rune(70461), To: rune(70461)},
+ &CodePointRange{From: rune(70462), To: rune(70463)},
+ &CodePointRange{From: rune(70464), To: rune(70464)},
+ &CodePointRange{From: rune(70465), To: rune(70468)},
+ &CodePointRange{From: rune(70471), To: rune(70472)},
+ &CodePointRange{From: rune(70475), To: rune(70477)},
+ &CodePointRange{From: rune(70480), To: rune(70480)},
+ &CodePointRange{From: rune(70487), To: rune(70487)},
+ &CodePointRange{From: rune(70493), To: rune(70497)},
+ &CodePointRange{From: rune(70498), To: rune(70499)},
+ &CodePointRange{From: rune(70502), To: rune(70508)},
+ &CodePointRange{From: rune(70512), To: rune(70516)},
+ },
+ "grek": {
+ &CodePointRange{From: rune(880), To: rune(883)},
+ &CodePointRange{From: rune(885), To: rune(885)},
+ &CodePointRange{From: rune(886), To: rune(887)},
+ &CodePointRange{From: rune(890), To: rune(890)},
+ &CodePointRange{From: rune(891), To: rune(893)},
+ &CodePointRange{From: rune(895), To: rune(895)},
+ &CodePointRange{From: rune(900), To: rune(900)},
+ &CodePointRange{From: rune(902), To: rune(902)},
+ &CodePointRange{From: rune(904), To: rune(906)},
+ &CodePointRange{From: rune(908), To: rune(908)},
+ &CodePointRange{From: rune(910), To: rune(929)},
+ &CodePointRange{From: rune(931), To: rune(993)},
+ &CodePointRange{From: rune(1008), To: rune(1013)},
+ &CodePointRange{From: rune(1014), To: rune(1014)},
+ &CodePointRange{From: rune(1015), To: rune(1023)},
+ &CodePointRange{From: rune(7462), To: rune(7466)},
+ &CodePointRange{From: rune(7517), To: rune(7521)},
+ &CodePointRange{From: rune(7526), To: rune(7530)},
+ &CodePointRange{From: rune(7615), To: rune(7615)},
+ &CodePointRange{From: rune(7936), To: rune(7957)},
+ &CodePointRange{From: rune(7960), To: rune(7965)},
+ &CodePointRange{From: rune(7968), To: rune(8005)},
+ &CodePointRange{From: rune(8008), To: rune(8013)},
+ &CodePointRange{From: rune(8016), To: rune(8023)},
+ &CodePointRange{From: rune(8025), To: rune(8025)},
+ &CodePointRange{From: rune(8027), To: rune(8027)},
+ &CodePointRange{From: rune(8029), To: rune(8029)},
+ &CodePointRange{From: rune(8031), To: rune(8061)},
+ &CodePointRange{From: rune(8064), To: rune(8116)},
+ &CodePointRange{From: rune(8118), To: rune(8124)},
+ &CodePointRange{From: rune(8125), To: rune(8125)},
+ &CodePointRange{From: rune(8126), To: rune(8126)},
+ &CodePointRange{From: rune(8127), To: rune(8129)},
+ &CodePointRange{From: rune(8130), To: rune(8132)},
+ &CodePointRange{From: rune(8134), To: rune(8140)},
+ &CodePointRange{From: rune(8141), To: rune(8143)},
+ &CodePointRange{From: rune(8144), To: rune(8147)},
+ &CodePointRange{From: rune(8150), To: rune(8155)},
+ &CodePointRange{From: rune(8157), To: rune(8159)},
+ &CodePointRange{From: rune(8160), To: rune(8172)},
+ &CodePointRange{From: rune(8173), To: rune(8175)},
+ &CodePointRange{From: rune(8178), To: rune(8180)},
+ &CodePointRange{From: rune(8182), To: rune(8188)},
+ &CodePointRange{From: rune(8189), To: rune(8190)},
+ &CodePointRange{From: rune(8486), To: rune(8486)},
+ &CodePointRange{From: rune(43877), To: rune(43877)},
+ &CodePointRange{From: rune(65856), To: rune(65908)},
+ &CodePointRange{From: rune(65909), To: rune(65912)},
+ &CodePointRange{From: rune(65913), To: rune(65929)},
+ &CodePointRange{From: rune(65930), To: rune(65931)},
+ &CodePointRange{From: rune(65932), To: rune(65934)},
+ &CodePointRange{From: rune(65952), To: rune(65952)},
+ &CodePointRange{From: rune(119296), To: rune(119361)},
+ &CodePointRange{From: rune(119362), To: rune(119364)},
+ &CodePointRange{From: rune(119365), To: rune(119365)},
+ },
+ "gujr": {
+ &CodePointRange{From: rune(2689), To: rune(2690)},
+ &CodePointRange{From: rune(2691), To: rune(2691)},
+ &CodePointRange{From: rune(2693), To: rune(2701)},
+ &CodePointRange{From: rune(2703), To: rune(2705)},
+ &CodePointRange{From: rune(2707), To: rune(2728)},
+ &CodePointRange{From: rune(2730), To: rune(2736)},
+ &CodePointRange{From: rune(2738), To: rune(2739)},
+ &CodePointRange{From: rune(2741), To: rune(2745)},
+ &CodePointRange{From: rune(2748), To: rune(2748)},
+ &CodePointRange{From: rune(2749), To: rune(2749)},
+ &CodePointRange{From: rune(2750), To: rune(2752)},
+ &CodePointRange{From: rune(2753), To: rune(2757)},
+ &CodePointRange{From: rune(2759), To: rune(2760)},
+ &CodePointRange{From: rune(2761), To: rune(2761)},
+ &CodePointRange{From: rune(2763), To: rune(2764)},
+ &CodePointRange{From: rune(2765), To: rune(2765)},
+ &CodePointRange{From: rune(2768), To: rune(2768)},
+ &CodePointRange{From: rune(2784), To: rune(2785)},
+ &CodePointRange{From: rune(2786), To: rune(2787)},
+ &CodePointRange{From: rune(2790), To: rune(2799)},
+ &CodePointRange{From: rune(2800), To: rune(2800)},
+ &CodePointRange{From: rune(2801), To: rune(2801)},
+ &CodePointRange{From: rune(2809), To: rune(2809)},
+ &CodePointRange{From: rune(2810), To: rune(2815)},
+ },
+ "guru": {
+ &CodePointRange{From: rune(2561), To: rune(2562)},
+ &CodePointRange{From: rune(2563), To: rune(2563)},
+ &CodePointRange{From: rune(2565), To: rune(2570)},
+ &CodePointRange{From: rune(2575), To: rune(2576)},
+ &CodePointRange{From: rune(2579), To: rune(2600)},
+ &CodePointRange{From: rune(2602), To: rune(2608)},
+ &CodePointRange{From: rune(2610), To: rune(2611)},
+ &CodePointRange{From: rune(2613), To: rune(2614)},
+ &CodePointRange{From: rune(2616), To: rune(2617)},
+ &CodePointRange{From: rune(2620), To: rune(2620)},
+ &CodePointRange{From: rune(2622), To: rune(2624)},
+ &CodePointRange{From: rune(2625), To: rune(2626)},
+ &CodePointRange{From: rune(2631), To: rune(2632)},
+ &CodePointRange{From: rune(2635), To: rune(2637)},
+ &CodePointRange{From: rune(2641), To: rune(2641)},
+ &CodePointRange{From: rune(2649), To: rune(2652)},
+ &CodePointRange{From: rune(2654), To: rune(2654)},
+ &CodePointRange{From: rune(2662), To: rune(2671)},
+ &CodePointRange{From: rune(2672), To: rune(2673)},
+ &CodePointRange{From: rune(2674), To: rune(2676)},
+ &CodePointRange{From: rune(2677), To: rune(2677)},
+ &CodePointRange{From: rune(2678), To: rune(2678)},
+ },
+ "hang": {
+ &CodePointRange{From: rune(4352), To: rune(4607)},
+ &CodePointRange{From: rune(12334), To: rune(12335)},
+ &CodePointRange{From: rune(12593), To: rune(12686)},
+ &CodePointRange{From: rune(12800), To: rune(12830)},
+ &CodePointRange{From: rune(12896), To: rune(12926)},
+ &CodePointRange{From: rune(43360), To: rune(43388)},
+ &CodePointRange{From: rune(44032), To: rune(55203)},
+ &CodePointRange{From: rune(55216), To: rune(55238)},
+ &CodePointRange{From: rune(55243), To: rune(55291)},
+ &CodePointRange{From: rune(65440), To: rune(65470)},
+ &CodePointRange{From: rune(65474), To: rune(65479)},
+ &CodePointRange{From: rune(65482), To: rune(65487)},
+ &CodePointRange{From: rune(65490), To: rune(65495)},
+ &CodePointRange{From: rune(65498), To: rune(65500)},
+ },
+ "hani": {
+ &CodePointRange{From: rune(11904), To: rune(11929)},
+ &CodePointRange{From: rune(11931), To: rune(12019)},
+ &CodePointRange{From: rune(12032), To: rune(12245)},
+ &CodePointRange{From: rune(12293), To: rune(12293)},
+ &CodePointRange{From: rune(12295), To: rune(12295)},
+ &CodePointRange{From: rune(12321), To: rune(12329)},
+ &CodePointRange{From: rune(12344), To: rune(12346)},
+ &CodePointRange{From: rune(12347), To: rune(12347)},
+ &CodePointRange{From: rune(13312), To: rune(19903)},
+ &CodePointRange{From: rune(19968), To: rune(40956)},
+ &CodePointRange{From: rune(63744), To: rune(64109)},
+ &CodePointRange{From: rune(64112), To: rune(64217)},
+ &CodePointRange{From: rune(94192), To: rune(94193)},
+ &CodePointRange{From: rune(131072), To: rune(173789)},
+ &CodePointRange{From: rune(173824), To: rune(177972)},
+ &CodePointRange{From: rune(177984), To: rune(178205)},
+ &CodePointRange{From: rune(178208), To: rune(183969)},
+ &CodePointRange{From: rune(183984), To: rune(191456)},
+ &CodePointRange{From: rune(194560), To: rune(195101)},
+ &CodePointRange{From: rune(196608), To: rune(201546)},
+ },
+ "hano": {
+ &CodePointRange{From: rune(5920), To: rune(5937)},
+ &CodePointRange{From: rune(5938), To: rune(5940)},
+ },
+ "hatr": {
+ &CodePointRange{From: rune(67808), To: rune(67826)},
+ &CodePointRange{From: rune(67828), To: rune(67829)},
+ &CodePointRange{From: rune(67835), To: rune(67839)},
+ },
+ "hebr": {
+ &CodePointRange{From: rune(1425), To: rune(1469)},
+ &CodePointRange{From: rune(1470), To: rune(1470)},
+ &CodePointRange{From: rune(1471), To: rune(1471)},
+ &CodePointRange{From: rune(1472), To: rune(1472)},
+ &CodePointRange{From: rune(1473), To: rune(1474)},
+ &CodePointRange{From: rune(1475), To: rune(1475)},
+ &CodePointRange{From: rune(1476), To: rune(1477)},
+ &CodePointRange{From: rune(1478), To: rune(1478)},
+ &CodePointRange{From: rune(1479), To: rune(1479)},
+ &CodePointRange{From: rune(1488), To: rune(1514)},
+ &CodePointRange{From: rune(1519), To: rune(1522)},
+ &CodePointRange{From: rune(1523), To: rune(1524)},
+ &CodePointRange{From: rune(64285), To: rune(64285)},
+ &CodePointRange{From: rune(64286), To: rune(64286)},
+ &CodePointRange{From: rune(64287), To: rune(64296)},
+ &CodePointRange{From: rune(64297), To: rune(64297)},
+ &CodePointRange{From: rune(64298), To: rune(64310)},
+ &CodePointRange{From: rune(64312), To: rune(64316)},
+ &CodePointRange{From: rune(64318), To: rune(64318)},
+ &CodePointRange{From: rune(64320), To: rune(64321)},
+ &CodePointRange{From: rune(64323), To: rune(64324)},
+ &CodePointRange{From: rune(64326), To: rune(64335)},
+ },
+ "hira": {
+ &CodePointRange{From: rune(12353), To: rune(12438)},
+ &CodePointRange{From: rune(12445), To: rune(12446)},
+ &CodePointRange{From: rune(12447), To: rune(12447)},
+ &CodePointRange{From: rune(110593), To: rune(110878)},
+ &CodePointRange{From: rune(110928), To: rune(110930)},
+ &CodePointRange{From: rune(127488), To: rune(127488)},
+ },
+ "hluw": {
+ &CodePointRange{From: rune(82944), To: rune(83526)},
+ },
+ "hmng": {
+ &CodePointRange{From: rune(92928), To: rune(92975)},
+ &CodePointRange{From: rune(92976), To: rune(92982)},
+ &CodePointRange{From: rune(92983), To: rune(92987)},
+ &CodePointRange{From: rune(92988), To: rune(92991)},
+ &CodePointRange{From: rune(92992), To: rune(92995)},
+ &CodePointRange{From: rune(92996), To: rune(92996)},
+ &CodePointRange{From: rune(92997), To: rune(92997)},
+ &CodePointRange{From: rune(93008), To: rune(93017)},
+ &CodePointRange{From: rune(93019), To: rune(93025)},
+ &CodePointRange{From: rune(93027), To: rune(93047)},
+ &CodePointRange{From: rune(93053), To: rune(93071)},
+ },
+ "hmnp": {
+ &CodePointRange{From: rune(123136), To: rune(123180)},
+ &CodePointRange{From: rune(123184), To: rune(123190)},
+ &CodePointRange{From: rune(123191), To: rune(123197)},
+ &CodePointRange{From: rune(123200), To: rune(123209)},
+ &CodePointRange{From: rune(123214), To: rune(123214)},
+ &CodePointRange{From: rune(123215), To: rune(123215)},
+ },
+ "hung": {
+ &CodePointRange{From: rune(68736), To: rune(68786)},
+ &CodePointRange{From: rune(68800), To: rune(68850)},
+ &CodePointRange{From: rune(68858), To: rune(68863)},
+ },
+ "ital": {
+ &CodePointRange{From: rune(66304), To: rune(66335)},
+ &CodePointRange{From: rune(66336), To: rune(66339)},
+ &CodePointRange{From: rune(66349), To: rune(66351)},
+ },
+ "java": {
+ &CodePointRange{From: rune(43392), To: rune(43394)},
+ &CodePointRange{From: rune(43395), To: rune(43395)},
+ &CodePointRange{From: rune(43396), To: rune(43442)},
+ &CodePointRange{From: rune(43443), To: rune(43443)},
+ &CodePointRange{From: rune(43444), To: rune(43445)},
+ &CodePointRange{From: rune(43446), To: rune(43449)},
+ &CodePointRange{From: rune(43450), To: rune(43451)},
+ &CodePointRange{From: rune(43452), To: rune(43453)},
+ &CodePointRange{From: rune(43454), To: rune(43456)},
+ &CodePointRange{From: rune(43457), To: rune(43469)},
+ &CodePointRange{From: rune(43472), To: rune(43481)},
+ &CodePointRange{From: rune(43486), To: rune(43487)},
+ },
+ "kali": {
+ &CodePointRange{From: rune(43264), To: rune(43273)},
+ &CodePointRange{From: rune(43274), To: rune(43301)},
+ &CodePointRange{From: rune(43302), To: rune(43309)},
+ &CodePointRange{From: rune(43311), To: rune(43311)},
+ },
+ "kana": {
+ &CodePointRange{From: rune(12449), To: rune(12538)},
+ &CodePointRange{From: rune(12541), To: rune(12542)},
+ &CodePointRange{From: rune(12543), To: rune(12543)},
+ &CodePointRange{From: rune(12784), To: rune(12799)},
+ &CodePointRange{From: rune(13008), To: rune(13054)},
+ &CodePointRange{From: rune(13056), To: rune(13143)},
+ &CodePointRange{From: rune(65382), To: rune(65391)},
+ &CodePointRange{From: rune(65393), To: rune(65437)},
+ &CodePointRange{From: rune(110592), To: rune(110592)},
+ &CodePointRange{From: rune(110948), To: rune(110951)},
+ },
+ "khar": {
+ &CodePointRange{From: rune(68096), To: rune(68096)},
+ &CodePointRange{From: rune(68097), To: rune(68099)},
+ &CodePointRange{From: rune(68101), To: rune(68102)},
+ &CodePointRange{From: rune(68108), To: rune(68111)},
+ &CodePointRange{From: rune(68112), To: rune(68115)},
+ &CodePointRange{From: rune(68117), To: rune(68119)},
+ &CodePointRange{From: rune(68121), To: rune(68149)},
+ &CodePointRange{From: rune(68152), To: rune(68154)},
+ &CodePointRange{From: rune(68159), To: rune(68159)},
+ &CodePointRange{From: rune(68160), To: rune(68168)},
+ &CodePointRange{From: rune(68176), To: rune(68184)},
+ },
+ "khmr": {
+ &CodePointRange{From: rune(6016), To: rune(6067)},
+ &CodePointRange{From: rune(6068), To: rune(6069)},
+ &CodePointRange{From: rune(6070), To: rune(6070)},
+ &CodePointRange{From: rune(6071), To: rune(6077)},
+ &CodePointRange{From: rune(6078), To: rune(6085)},
+ &CodePointRange{From: rune(6086), To: rune(6086)},
+ &CodePointRange{From: rune(6087), To: rune(6088)},
+ &CodePointRange{From: rune(6089), To: rune(6099)},
+ &CodePointRange{From: rune(6100), To: rune(6102)},
+ &CodePointRange{From: rune(6103), To: rune(6103)},
+ &CodePointRange{From: rune(6104), To: rune(6106)},
+ &CodePointRange{From: rune(6107), To: rune(6107)},
+ &CodePointRange{From: rune(6108), To: rune(6108)},
+ &CodePointRange{From: rune(6109), To: rune(6109)},
+ &CodePointRange{From: rune(6112), To: rune(6121)},
+ &CodePointRange{From: rune(6128), To: rune(6137)},
+ &CodePointRange{From: rune(6624), To: rune(6655)},
+ },
+ "khoj": {
+ &CodePointRange{From: rune(70144), To: rune(70161)},
+ &CodePointRange{From: rune(70163), To: rune(70187)},
+ &CodePointRange{From: rune(70188), To: rune(70190)},
+ &CodePointRange{From: rune(70191), To: rune(70193)},
+ &CodePointRange{From: rune(70194), To: rune(70195)},
+ &CodePointRange{From: rune(70196), To: rune(70196)},
+ &CodePointRange{From: rune(70197), To: rune(70197)},
+ &CodePointRange{From: rune(70198), To: rune(70199)},
+ &CodePointRange{From: rune(70200), To: rune(70205)},
+ &CodePointRange{From: rune(70206), To: rune(70206)},
+ },
+ "kits": {
+ &CodePointRange{From: rune(94180), To: rune(94180)},
+ &CodePointRange{From: rune(101120), To: rune(101589)},
+ },
+ "knda": {
+ &CodePointRange{From: rune(3200), To: rune(3200)},
+ &CodePointRange{From: rune(3201), To: rune(3201)},
+ &CodePointRange{From: rune(3202), To: rune(3203)},
+ &CodePointRange{From: rune(3204), To: rune(3204)},
+ &CodePointRange{From: rune(3205), To: rune(3212)},
+ &CodePointRange{From: rune(3214), To: rune(3216)},
+ &CodePointRange{From: rune(3218), To: rune(3240)},
+ &CodePointRange{From: rune(3242), To: rune(3251)},
+ &CodePointRange{From: rune(3253), To: rune(3257)},
+ &CodePointRange{From: rune(3260), To: rune(3260)},
+ &CodePointRange{From: rune(3261), To: rune(3261)},
+ &CodePointRange{From: rune(3262), To: rune(3262)},
+ &CodePointRange{From: rune(3263), To: rune(3263)},
+ &CodePointRange{From: rune(3264), To: rune(3268)},
+ &CodePointRange{From: rune(3270), To: rune(3270)},
+ &CodePointRange{From: rune(3271), To: rune(3272)},
+ &CodePointRange{From: rune(3274), To: rune(3275)},
+ &CodePointRange{From: rune(3276), To: rune(3277)},
+ &CodePointRange{From: rune(3285), To: rune(3286)},
+ &CodePointRange{From: rune(3294), To: rune(3294)},
+ &CodePointRange{From: rune(3296), To: rune(3297)},
+ &CodePointRange{From: rune(3298), To: rune(3299)},
+ &CodePointRange{From: rune(3302), To: rune(3311)},
+ &CodePointRange{From: rune(3313), To: rune(3314)},
+ },
+ "kthi": {
+ &CodePointRange{From: rune(69760), To: rune(69761)},
+ &CodePointRange{From: rune(69762), To: rune(69762)},
+ &CodePointRange{From: rune(69763), To: rune(69807)},
+ &CodePointRange{From: rune(69808), To: rune(69810)},
+ &CodePointRange{From: rune(69811), To: rune(69814)},
+ &CodePointRange{From: rune(69815), To: rune(69816)},
+ &CodePointRange{From: rune(69817), To: rune(69818)},
+ &CodePointRange{From: rune(69819), To: rune(69820)},
+ &CodePointRange{From: rune(69821), To: rune(69821)},
+ &CodePointRange{From: rune(69822), To: rune(69825)},
+ &CodePointRange{From: rune(69837), To: rune(69837)},
+ },
+ "lana": {
+ &CodePointRange{From: rune(6688), To: rune(6740)},
+ &CodePointRange{From: rune(6741), To: rune(6741)},
+ &CodePointRange{From: rune(6742), To: rune(6742)},
+ &CodePointRange{From: rune(6743), To: rune(6743)},
+ &CodePointRange{From: rune(6744), To: rune(6750)},
+ &CodePointRange{From: rune(6752), To: rune(6752)},
+ &CodePointRange{From: rune(6753), To: rune(6753)},
+ &CodePointRange{From: rune(6754), To: rune(6754)},
+ &CodePointRange{From: rune(6755), To: rune(6756)},
+ &CodePointRange{From: rune(6757), To: rune(6764)},
+ &CodePointRange{From: rune(6765), To: rune(6770)},
+ &CodePointRange{From: rune(6771), To: rune(6780)},
+ &CodePointRange{From: rune(6783), To: rune(6783)},
+ &CodePointRange{From: rune(6784), To: rune(6793)},
+ &CodePointRange{From: rune(6800), To: rune(6809)},
+ &CodePointRange{From: rune(6816), To: rune(6822)},
+ &CodePointRange{From: rune(6823), To: rune(6823)},
+ &CodePointRange{From: rune(6824), To: rune(6829)},
+ },
+ "laoo": {
+ &CodePointRange{From: rune(3713), To: rune(3714)},
+ &CodePointRange{From: rune(3716), To: rune(3716)},
+ &CodePointRange{From: rune(3718), To: rune(3722)},
+ &CodePointRange{From: rune(3724), To: rune(3747)},
+ &CodePointRange{From: rune(3749), To: rune(3749)},
+ &CodePointRange{From: rune(3751), To: rune(3760)},
+ &CodePointRange{From: rune(3761), To: rune(3761)},
+ &CodePointRange{From: rune(3762), To: rune(3763)},
+ &CodePointRange{From: rune(3764), To: rune(3772)},
+ &CodePointRange{From: rune(3773), To: rune(3773)},
+ &CodePointRange{From: rune(3776), To: rune(3780)},
+ &CodePointRange{From: rune(3782), To: rune(3782)},
+ &CodePointRange{From: rune(3784), To: rune(3789)},
+ &CodePointRange{From: rune(3792), To: rune(3801)},
+ &CodePointRange{From: rune(3804), To: rune(3807)},
+ },
+ "latn": {
+ &CodePointRange{From: rune(65), To: rune(90)},
+ &CodePointRange{From: rune(97), To: rune(122)},
+ &CodePointRange{From: rune(170), To: rune(170)},
+ &CodePointRange{From: rune(186), To: rune(186)},
+ &CodePointRange{From: rune(192), To: rune(214)},
+ &CodePointRange{From: rune(216), To: rune(246)},
+ &CodePointRange{From: rune(248), To: rune(442)},
+ &CodePointRange{From: rune(443), To: rune(443)},
+ &CodePointRange{From: rune(444), To: rune(447)},
+ &CodePointRange{From: rune(448), To: rune(451)},
+ &CodePointRange{From: rune(452), To: rune(659)},
+ &CodePointRange{From: rune(660), To: rune(660)},
+ &CodePointRange{From: rune(661), To: rune(687)},
+ &CodePointRange{From: rune(688), To: rune(696)},
+ &CodePointRange{From: rune(736), To: rune(740)},
+ &CodePointRange{From: rune(7424), To: rune(7461)},
+ &CodePointRange{From: rune(7468), To: rune(7516)},
+ &CodePointRange{From: rune(7522), To: rune(7525)},
+ &CodePointRange{From: rune(7531), To: rune(7543)},
+ &CodePointRange{From: rune(7545), To: rune(7578)},
+ &CodePointRange{From: rune(7579), To: rune(7614)},
+ &CodePointRange{From: rune(7680), To: rune(7935)},
+ &CodePointRange{From: rune(8305), To: rune(8305)},
+ &CodePointRange{From: rune(8319), To: rune(8319)},
+ &CodePointRange{From: rune(8336), To: rune(8348)},
+ &CodePointRange{From: rune(8490), To: rune(8491)},
+ &CodePointRange{From: rune(8498), To: rune(8498)},
+ &CodePointRange{From: rune(8526), To: rune(8526)},
+ &CodePointRange{From: rune(8544), To: rune(8578)},
+ &CodePointRange{From: rune(8579), To: rune(8580)},
+ &CodePointRange{From: rune(8581), To: rune(8584)},
+ &CodePointRange{From: rune(11360), To: rune(11387)},
+ &CodePointRange{From: rune(11388), To: rune(11389)},
+ &CodePointRange{From: rune(11390), To: rune(11391)},
+ &CodePointRange{From: rune(42786), To: rune(42863)},
+ &CodePointRange{From: rune(42864), To: rune(42864)},
+ &CodePointRange{From: rune(42865), To: rune(42887)},
+ &CodePointRange{From: rune(42891), To: rune(42894)},
+ &CodePointRange{From: rune(42895), To: rune(42895)},
+ &CodePointRange{From: rune(42896), To: rune(42943)},
+ &CodePointRange{From: rune(42946), To: rune(42954)},
+ &CodePointRange{From: rune(42997), To: rune(42998)},
+ &CodePointRange{From: rune(42999), To: rune(42999)},
+ &CodePointRange{From: rune(43000), To: rune(43001)},
+ &CodePointRange{From: rune(43002), To: rune(43002)},
+ &CodePointRange{From: rune(43003), To: rune(43007)},
+ &CodePointRange{From: rune(43824), To: rune(43866)},
+ &CodePointRange{From: rune(43868), To: rune(43871)},
+ &CodePointRange{From: rune(43872), To: rune(43876)},
+ &CodePointRange{From: rune(43878), To: rune(43880)},
+ &CodePointRange{From: rune(43881), To: rune(43881)},
+ &CodePointRange{From: rune(64256), To: rune(64262)},
+ &CodePointRange{From: rune(65313), To: rune(65338)},
+ &CodePointRange{From: rune(65345), To: rune(65370)},
+ },
+ "lepc": {
+ &CodePointRange{From: rune(7168), To: rune(7203)},
+ &CodePointRange{From: rune(7204), To: rune(7211)},
+ &CodePointRange{From: rune(7212), To: rune(7219)},
+ &CodePointRange{From: rune(7220), To: rune(7221)},
+ &CodePointRange{From: rune(7222), To: rune(7223)},
+ &CodePointRange{From: rune(7227), To: rune(7231)},
+ &CodePointRange{From: rune(7232), To: rune(7241)},
+ &CodePointRange{From: rune(7245), To: rune(7247)},
+ },
+ "limb": {
+ &CodePointRange{From: rune(6400), To: rune(6430)},
+ &CodePointRange{From: rune(6432), To: rune(6434)},
+ &CodePointRange{From: rune(6435), To: rune(6438)},
+ &CodePointRange{From: rune(6439), To: rune(6440)},
+ &CodePointRange{From: rune(6441), To: rune(6443)},
+ &CodePointRange{From: rune(6448), To: rune(6449)},
+ &CodePointRange{From: rune(6450), To: rune(6450)},
+ &CodePointRange{From: rune(6451), To: rune(6456)},
+ &CodePointRange{From: rune(6457), To: rune(6459)},
+ &CodePointRange{From: rune(6464), To: rune(6464)},
+ &CodePointRange{From: rune(6468), To: rune(6469)},
+ &CodePointRange{From: rune(6470), To: rune(6479)},
+ },
+ "lina": {
+ &CodePointRange{From: rune(67072), To: rune(67382)},
+ &CodePointRange{From: rune(67392), To: rune(67413)},
+ &CodePointRange{From: rune(67424), To: rune(67431)},
+ },
+ "linb": {
+ &CodePointRange{From: rune(65536), To: rune(65547)},
+ &CodePointRange{From: rune(65549), To: rune(65574)},
+ &CodePointRange{From: rune(65576), To: rune(65594)},
+ &CodePointRange{From: rune(65596), To: rune(65597)},
+ &CodePointRange{From: rune(65599), To: rune(65613)},
+ &CodePointRange{From: rune(65616), To: rune(65629)},
+ &CodePointRange{From: rune(65664), To: rune(65786)},
+ },
+ "lisu": {
+ &CodePointRange{From: rune(42192), To: rune(42231)},
+ &CodePointRange{From: rune(42232), To: rune(42237)},
+ &CodePointRange{From: rune(42238), To: rune(42239)},
+ &CodePointRange{From: rune(73648), To: rune(73648)},
+ },
+ "lyci": {
+ &CodePointRange{From: rune(66176), To: rune(66204)},
+ },
+ "lydi": {
+ &CodePointRange{From: rune(67872), To: rune(67897)},
+ &CodePointRange{From: rune(67903), To: rune(67903)},
+ },
+ "mahj": {
+ &CodePointRange{From: rune(69968), To: rune(70002)},
+ &CodePointRange{From: rune(70003), To: rune(70003)},
+ &CodePointRange{From: rune(70004), To: rune(70005)},
+ &CodePointRange{From: rune(70006), To: rune(70006)},
+ },
+ "maka": {
+ &CodePointRange{From: rune(73440), To: rune(73458)},
+ &CodePointRange{From: rune(73459), To: rune(73460)},
+ &CodePointRange{From: rune(73461), To: rune(73462)},
+ &CodePointRange{From: rune(73463), To: rune(73464)},
+ },
+ "mand": {
+ &CodePointRange{From: rune(2112), To: rune(2136)},
+ &CodePointRange{From: rune(2137), To: rune(2139)},
+ &CodePointRange{From: rune(2142), To: rune(2142)},
+ },
+ "mani": {
+ &CodePointRange{From: rune(68288), To: rune(68295)},
+ &CodePointRange{From: rune(68296), To: rune(68296)},
+ &CodePointRange{From: rune(68297), To: rune(68324)},
+ &CodePointRange{From: rune(68325), To: rune(68326)},
+ &CodePointRange{From: rune(68331), To: rune(68335)},
+ &CodePointRange{From: rune(68336), To: rune(68342)},
+ },
+ "marc": {
+ &CodePointRange{From: rune(72816), To: rune(72817)},
+ &CodePointRange{From: rune(72818), To: rune(72847)},
+ &CodePointRange{From: rune(72850), To: rune(72871)},
+ &CodePointRange{From: rune(72873), To: rune(72873)},
+ &CodePointRange{From: rune(72874), To: rune(72880)},
+ &CodePointRange{From: rune(72881), To: rune(72881)},
+ &CodePointRange{From: rune(72882), To: rune(72883)},
+ &CodePointRange{From: rune(72884), To: rune(72884)},
+ &CodePointRange{From: rune(72885), To: rune(72886)},
+ },
+ "medf": {
+ &CodePointRange{From: rune(93760), To: rune(93823)},
+ &CodePointRange{From: rune(93824), To: rune(93846)},
+ &CodePointRange{From: rune(93847), To: rune(93850)},
+ },
+ "mend": {
+ &CodePointRange{From: rune(124928), To: rune(125124)},
+ &CodePointRange{From: rune(125127), To: rune(125135)},
+ &CodePointRange{From: rune(125136), To: rune(125142)},
+ },
+ "merc": {
+ &CodePointRange{From: rune(68000), To: rune(68023)},
+ &CodePointRange{From: rune(68028), To: rune(68029)},
+ &CodePointRange{From: rune(68030), To: rune(68031)},
+ &CodePointRange{From: rune(68032), To: rune(68047)},
+ &CodePointRange{From: rune(68050), To: rune(68095)},
+ },
+ "mero": {
+ &CodePointRange{From: rune(67968), To: rune(67999)},
+ },
+ "mlym": {
+ &CodePointRange{From: rune(3328), To: rune(3329)},
+ &CodePointRange{From: rune(3330), To: rune(3331)},
+ &CodePointRange{From: rune(3332), To: rune(3340)},
+ &CodePointRange{From: rune(3342), To: rune(3344)},
+ &CodePointRange{From: rune(3346), To: rune(3386)},
+ &CodePointRange{From: rune(3387), To: rune(3388)},
+ &CodePointRange{From: rune(3389), To: rune(3389)},
+ &CodePointRange{From: rune(3390), To: rune(3392)},
+ &CodePointRange{From: rune(3393), To: rune(3396)},
+ &CodePointRange{From: rune(3398), To: rune(3400)},
+ &CodePointRange{From: rune(3402), To: rune(3404)},
+ &CodePointRange{From: rune(3405), To: rune(3405)},
+ &CodePointRange{From: rune(3406), To: rune(3406)},
+ &CodePointRange{From: rune(3407), To: rune(3407)},
+ &CodePointRange{From: rune(3412), To: rune(3414)},
+ &CodePointRange{From: rune(3415), To: rune(3415)},
+ &CodePointRange{From: rune(3416), To: rune(3422)},
+ &CodePointRange{From: rune(3423), To: rune(3425)},
+ &CodePointRange{From: rune(3426), To: rune(3427)},
+ &CodePointRange{From: rune(3430), To: rune(3439)},
+ &CodePointRange{From: rune(3440), To: rune(3448)},
+ &CodePointRange{From: rune(3449), To: rune(3449)},
+ &CodePointRange{From: rune(3450), To: rune(3455)},
+ },
+ "modi": {
+ &CodePointRange{From: rune(71168), To: rune(71215)},
+ &CodePointRange{From: rune(71216), To: rune(71218)},
+ &CodePointRange{From: rune(71219), To: rune(71226)},
+ &CodePointRange{From: rune(71227), To: rune(71228)},
+ &CodePointRange{From: rune(71229), To: rune(71229)},
+ &CodePointRange{From: rune(71230), To: rune(71230)},
+ &CodePointRange{From: rune(71231), To: rune(71232)},
+ &CodePointRange{From: rune(71233), To: rune(71235)},
+ &CodePointRange{From: rune(71236), To: rune(71236)},
+ &CodePointRange{From: rune(71248), To: rune(71257)},
+ },
+ "mong": {
+ &CodePointRange{From: rune(6144), To: rune(6145)},
+ &CodePointRange{From: rune(6148), To: rune(6148)},
+ &CodePointRange{From: rune(6150), To: rune(6150)},
+ &CodePointRange{From: rune(6151), To: rune(6154)},
+ &CodePointRange{From: rune(6155), To: rune(6157)},
+ &CodePointRange{From: rune(6158), To: rune(6158)},
+ &CodePointRange{From: rune(6160), To: rune(6169)},
+ &CodePointRange{From: rune(6176), To: rune(6210)},
+ &CodePointRange{From: rune(6211), To: rune(6211)},
+ &CodePointRange{From: rune(6212), To: rune(6264)},
+ &CodePointRange{From: rune(6272), To: rune(6276)},
+ &CodePointRange{From: rune(6277), To: rune(6278)},
+ &CodePointRange{From: rune(6279), To: rune(6312)},
+ &CodePointRange{From: rune(6313), To: rune(6313)},
+ &CodePointRange{From: rune(6314), To: rune(6314)},
+ &CodePointRange{From: rune(71264), To: rune(71276)},
+ },
+ "mroo": {
+ &CodePointRange{From: rune(92736), To: rune(92766)},
+ &CodePointRange{From: rune(92768), To: rune(92777)},
+ &CodePointRange{From: rune(92782), To: rune(92783)},
+ },
+ "mtei": {
+ &CodePointRange{From: rune(43744), To: rune(43754)},
+ &CodePointRange{From: rune(43755), To: rune(43755)},
+ &CodePointRange{From: rune(43756), To: rune(43757)},
+ &CodePointRange{From: rune(43758), To: rune(43759)},
+ &CodePointRange{From: rune(43760), To: rune(43761)},
+ &CodePointRange{From: rune(43762), To: rune(43762)},
+ &CodePointRange{From: rune(43763), To: rune(43764)},
+ &CodePointRange{From: rune(43765), To: rune(43765)},
+ &CodePointRange{From: rune(43766), To: rune(43766)},
+ &CodePointRange{From: rune(43968), To: rune(44002)},
+ &CodePointRange{From: rune(44003), To: rune(44004)},
+ &CodePointRange{From: rune(44005), To: rune(44005)},
+ &CodePointRange{From: rune(44006), To: rune(44007)},
+ &CodePointRange{From: rune(44008), To: rune(44008)},
+ &CodePointRange{From: rune(44009), To: rune(44010)},
+ &CodePointRange{From: rune(44011), To: rune(44011)},
+ &CodePointRange{From: rune(44012), To: rune(44012)},
+ &CodePointRange{From: rune(44013), To: rune(44013)},
+ &CodePointRange{From: rune(44016), To: rune(44025)},
+ },
+ "mult": {
+ &CodePointRange{From: rune(70272), To: rune(70278)},
+ &CodePointRange{From: rune(70280), To: rune(70280)},
+ &CodePointRange{From: rune(70282), To: rune(70285)},
+ &CodePointRange{From: rune(70287), To: rune(70301)},
+ &CodePointRange{From: rune(70303), To: rune(70312)},
+ &CodePointRange{From: rune(70313), To: rune(70313)},
+ },
+ "mymr": {
+ &CodePointRange{From: rune(4096), To: rune(4138)},
+ &CodePointRange{From: rune(4139), To: rune(4140)},
+ &CodePointRange{From: rune(4141), To: rune(4144)},
+ &CodePointRange{From: rune(4145), To: rune(4145)},
+ &CodePointRange{From: rune(4146), To: rune(4151)},
+ &CodePointRange{From: rune(4152), To: rune(4152)},
+ &CodePointRange{From: rune(4153), To: rune(4154)},
+ &CodePointRange{From: rune(4155), To: rune(4156)},
+ &CodePointRange{From: rune(4157), To: rune(4158)},
+ &CodePointRange{From: rune(4159), To: rune(4159)},
+ &CodePointRange{From: rune(4160), To: rune(4169)},
+ &CodePointRange{From: rune(4170), To: rune(4175)},
+ &CodePointRange{From: rune(4176), To: rune(4181)},
+ &CodePointRange{From: rune(4182), To: rune(4183)},
+ &CodePointRange{From: rune(4184), To: rune(4185)},
+ &CodePointRange{From: rune(4186), To: rune(4189)},
+ &CodePointRange{From: rune(4190), To: rune(4192)},
+ &CodePointRange{From: rune(4193), To: rune(4193)},
+ &CodePointRange{From: rune(4194), To: rune(4196)},
+ &CodePointRange{From: rune(4197), To: rune(4198)},
+ &CodePointRange{From: rune(4199), To: rune(4205)},
+ &CodePointRange{From: rune(4206), To: rune(4208)},
+ &CodePointRange{From: rune(4209), To: rune(4212)},
+ &CodePointRange{From: rune(4213), To: rune(4225)},
+ &CodePointRange{From: rune(4226), To: rune(4226)},
+ &CodePointRange{From: rune(4227), To: rune(4228)},
+ &CodePointRange{From: rune(4229), To: rune(4230)},
+ &CodePointRange{From: rune(4231), To: rune(4236)},
+ &CodePointRange{From: rune(4237), To: rune(4237)},
+ &CodePointRange{From: rune(4238), To: rune(4238)},
+ &CodePointRange{From: rune(4239), To: rune(4239)},
+ &CodePointRange{From: rune(4240), To: rune(4249)},
+ &CodePointRange{From: rune(4250), To: rune(4252)},
+ &CodePointRange{From: rune(4253), To: rune(4253)},
+ &CodePointRange{From: rune(4254), To: rune(4255)},
+ &CodePointRange{From: rune(43488), To: rune(43492)},
+ &CodePointRange{From: rune(43493), To: rune(43493)},
+ &CodePointRange{From: rune(43494), To: rune(43494)},
+ &CodePointRange{From: rune(43495), To: rune(43503)},
+ &CodePointRange{From: rune(43504), To: rune(43513)},
+ &CodePointRange{From: rune(43514), To: rune(43518)},
+ &CodePointRange{From: rune(43616), To: rune(43631)},
+ &CodePointRange{From: rune(43632), To: rune(43632)},
+ &CodePointRange{From: rune(43633), To: rune(43638)},
+ &CodePointRange{From: rune(43639), To: rune(43641)},
+ &CodePointRange{From: rune(43642), To: rune(43642)},
+ &CodePointRange{From: rune(43643), To: rune(43643)},
+ &CodePointRange{From: rune(43644), To: rune(43644)},
+ &CodePointRange{From: rune(43645), To: rune(43645)},
+ &CodePointRange{From: rune(43646), To: rune(43647)},
+ },
+ "nand": {
+ &CodePointRange{From: rune(72096), To: rune(72103)},
+ &CodePointRange{From: rune(72106), To: rune(72144)},
+ &CodePointRange{From: rune(72145), To: rune(72147)},
+ &CodePointRange{From: rune(72148), To: rune(72151)},
+ &CodePointRange{From: rune(72154), To: rune(72155)},
+ &CodePointRange{From: rune(72156), To: rune(72159)},
+ &CodePointRange{From: rune(72160), To: rune(72160)},
+ &CodePointRange{From: rune(72161), To: rune(72161)},
+ &CodePointRange{From: rune(72162), To: rune(72162)},
+ &CodePointRange{From: rune(72163), To: rune(72163)},
+ &CodePointRange{From: rune(72164), To: rune(72164)},
+ },
+ "narb": {
+ &CodePointRange{From: rune(68224), To: rune(68252)},
+ &CodePointRange{From: rune(68253), To: rune(68255)},
+ },
+ "nbat": {
+ &CodePointRange{From: rune(67712), To: rune(67742)},
+ &CodePointRange{From: rune(67751), To: rune(67759)},
+ },
+ "newa": {
+ &CodePointRange{From: rune(70656), To: rune(70708)},
+ &CodePointRange{From: rune(70709), To: rune(70711)},
+ &CodePointRange{From: rune(70712), To: rune(70719)},
+ &CodePointRange{From: rune(70720), To: rune(70721)},
+ &CodePointRange{From: rune(70722), To: rune(70724)},
+ &CodePointRange{From: rune(70725), To: rune(70725)},
+ &CodePointRange{From: rune(70726), To: rune(70726)},
+ &CodePointRange{From: rune(70727), To: rune(70730)},
+ &CodePointRange{From: rune(70731), To: rune(70735)},
+ &CodePointRange{From: rune(70736), To: rune(70745)},
+ &CodePointRange{From: rune(70746), To: rune(70747)},
+ &CodePointRange{From: rune(70749), To: rune(70749)},
+ &CodePointRange{From: rune(70750), To: rune(70750)},
+ &CodePointRange{From: rune(70751), To: rune(70753)},
+ },
+ "nkoo": {
+ &CodePointRange{From: rune(1984), To: rune(1993)},
+ &CodePointRange{From: rune(1994), To: rune(2026)},
+ &CodePointRange{From: rune(2027), To: rune(2035)},
+ &CodePointRange{From: rune(2036), To: rune(2037)},
+ &CodePointRange{From: rune(2038), To: rune(2038)},
+ &CodePointRange{From: rune(2039), To: rune(2041)},
+ &CodePointRange{From: rune(2042), To: rune(2042)},
+ &CodePointRange{From: rune(2045), To: rune(2045)},
+ &CodePointRange{From: rune(2046), To: rune(2047)},
+ },
+ "nshu": {
+ &CodePointRange{From: rune(94177), To: rune(94177)},
+ &CodePointRange{From: rune(110960), To: rune(111355)},
+ },
+ "ogam": {
+ &CodePointRange{From: rune(5760), To: rune(5760)},
+ &CodePointRange{From: rune(5761), To: rune(5786)},
+ &CodePointRange{From: rune(5787), To: rune(5787)},
+ &CodePointRange{From: rune(5788), To: rune(5788)},
+ },
+ "olck": {
+ &CodePointRange{From: rune(7248), To: rune(7257)},
+ &CodePointRange{From: rune(7258), To: rune(7287)},
+ &CodePointRange{From: rune(7288), To: rune(7293)},
+ &CodePointRange{From: rune(7294), To: rune(7295)},
+ },
+ "orkh": {
+ &CodePointRange{From: rune(68608), To: rune(68680)},
+ },
+ "orya": {
+ &CodePointRange{From: rune(2817), To: rune(2817)},
+ &CodePointRange{From: rune(2818), To: rune(2819)},
+ &CodePointRange{From: rune(2821), To: rune(2828)},
+ &CodePointRange{From: rune(2831), To: rune(2832)},
+ &CodePointRange{From: rune(2835), To: rune(2856)},
+ &CodePointRange{From: rune(2858), To: rune(2864)},
+ &CodePointRange{From: rune(2866), To: rune(2867)},
+ &CodePointRange{From: rune(2869), To: rune(2873)},
+ &CodePointRange{From: rune(2876), To: rune(2876)},
+ &CodePointRange{From: rune(2877), To: rune(2877)},
+ &CodePointRange{From: rune(2878), To: rune(2878)},
+ &CodePointRange{From: rune(2879), To: rune(2879)},
+ &CodePointRange{From: rune(2880), To: rune(2880)},
+ &CodePointRange{From: rune(2881), To: rune(2884)},
+ &CodePointRange{From: rune(2887), To: rune(2888)},
+ &CodePointRange{From: rune(2891), To: rune(2892)},
+ &CodePointRange{From: rune(2893), To: rune(2893)},
+ &CodePointRange{From: rune(2901), To: rune(2902)},
+ &CodePointRange{From: rune(2903), To: rune(2903)},
+ &CodePointRange{From: rune(2908), To: rune(2909)},
+ &CodePointRange{From: rune(2911), To: rune(2913)},
+ &CodePointRange{From: rune(2914), To: rune(2915)},
+ &CodePointRange{From: rune(2918), To: rune(2927)},
+ &CodePointRange{From: rune(2928), To: rune(2928)},
+ &CodePointRange{From: rune(2929), To: rune(2929)},
+ &CodePointRange{From: rune(2930), To: rune(2935)},
+ },
+ "osge": {
+ &CodePointRange{From: rune(66736), To: rune(66771)},
+ &CodePointRange{From: rune(66776), To: rune(66811)},
+ },
+ "osma": {
+ &CodePointRange{From: rune(66688), To: rune(66717)},
+ &CodePointRange{From: rune(66720), To: rune(66729)},
+ },
+ "palm": {
+ &CodePointRange{From: rune(67680), To: rune(67702)},
+ &CodePointRange{From: rune(67703), To: rune(67704)},
+ &CodePointRange{From: rune(67705), To: rune(67711)},
+ },
+ "pauc": {
+ &CodePointRange{From: rune(72384), To: rune(72440)},
+ },
+ "perm": {
+ &CodePointRange{From: rune(66384), To: rune(66421)},
+ &CodePointRange{From: rune(66422), To: rune(66426)},
+ },
+ "phag": {
+ &CodePointRange{From: rune(43072), To: rune(43123)},
+ &CodePointRange{From: rune(43124), To: rune(43127)},
+ },
+ "phli": {
+ &CodePointRange{From: rune(68448), To: rune(68466)},
+ &CodePointRange{From: rune(68472), To: rune(68479)},
+ },
+ "phlp": {
+ &CodePointRange{From: rune(68480), To: rune(68497)},
+ &CodePointRange{From: rune(68505), To: rune(68508)},
+ &CodePointRange{From: rune(68521), To: rune(68527)},
+ },
+ "phnx": {
+ &CodePointRange{From: rune(67840), To: rune(67861)},
+ &CodePointRange{From: rune(67862), To: rune(67867)},
+ &CodePointRange{From: rune(67871), To: rune(67871)},
+ },
+ "plrd": {
+ &CodePointRange{From: rune(93952), To: rune(94026)},
+ &CodePointRange{From: rune(94031), To: rune(94031)},
+ &CodePointRange{From: rune(94032), To: rune(94032)},
+ &CodePointRange{From: rune(94033), To: rune(94087)},
+ &CodePointRange{From: rune(94095), To: rune(94098)},
+ &CodePointRange{From: rune(94099), To: rune(94111)},
+ },
+ "prti": {
+ &CodePointRange{From: rune(68416), To: rune(68437)},
+ &CodePointRange{From: rune(68440), To: rune(68447)},
+ },
+ "rjng": {
+ &CodePointRange{From: rune(43312), To: rune(43334)},
+ &CodePointRange{From: rune(43335), To: rune(43345)},
+ &CodePointRange{From: rune(43346), To: rune(43347)},
+ &CodePointRange{From: rune(43359), To: rune(43359)},
+ },
+ "rohg": {
+ &CodePointRange{From: rune(68864), To: rune(68899)},
+ &CodePointRange{From: rune(68900), To: rune(68903)},
+ &CodePointRange{From: rune(68912), To: rune(68921)},
+ },
+ "runr": {
+ &CodePointRange{From: rune(5792), To: rune(5866)},
+ &CodePointRange{From: rune(5870), To: rune(5872)},
+ &CodePointRange{From: rune(5873), To: rune(5880)},
+ },
+ "samr": {
+ &CodePointRange{From: rune(2048), To: rune(2069)},
+ &CodePointRange{From: rune(2070), To: rune(2073)},
+ &CodePointRange{From: rune(2074), To: rune(2074)},
+ &CodePointRange{From: rune(2075), To: rune(2083)},
+ &CodePointRange{From: rune(2084), To: rune(2084)},
+ &CodePointRange{From: rune(2085), To: rune(2087)},
+ &CodePointRange{From: rune(2088), To: rune(2088)},
+ &CodePointRange{From: rune(2089), To: rune(2093)},
+ &CodePointRange{From: rune(2096), To: rune(2110)},
+ },
+ "sarb": {
+ &CodePointRange{From: rune(68192), To: rune(68220)},
+ &CodePointRange{From: rune(68221), To: rune(68222)},
+ &CodePointRange{From: rune(68223), To: rune(68223)},
+ },
+ "saur": {
+ &CodePointRange{From: rune(43136), To: rune(43137)},
+ &CodePointRange{From: rune(43138), To: rune(43187)},
+ &CodePointRange{From: rune(43188), To: rune(43203)},
+ &CodePointRange{From: rune(43204), To: rune(43205)},
+ &CodePointRange{From: rune(43214), To: rune(43215)},
+ &CodePointRange{From: rune(43216), To: rune(43225)},
+ },
+ "sgnw": {
+ &CodePointRange{From: rune(120832), To: rune(121343)},
+ &CodePointRange{From: rune(121344), To: rune(121398)},
+ &CodePointRange{From: rune(121399), To: rune(121402)},
+ &CodePointRange{From: rune(121403), To: rune(121452)},
+ &CodePointRange{From: rune(121453), To: rune(121460)},
+ &CodePointRange{From: rune(121461), To: rune(121461)},
+ &CodePointRange{From: rune(121462), To: rune(121475)},
+ &CodePointRange{From: rune(121476), To: rune(121476)},
+ &CodePointRange{From: rune(121477), To: rune(121478)},
+ &CodePointRange{From: rune(121479), To: rune(121483)},
+ &CodePointRange{From: rune(121499), To: rune(121503)},
+ &CodePointRange{From: rune(121505), To: rune(121519)},
+ },
+ "shaw": {
+ &CodePointRange{From: rune(66640), To: rune(66687)},
+ },
+ "shrd": {
+ &CodePointRange{From: rune(70016), To: rune(70017)},
+ &CodePointRange{From: rune(70018), To: rune(70018)},
+ &CodePointRange{From: rune(70019), To: rune(70066)},
+ &CodePointRange{From: rune(70067), To: rune(70069)},
+ &CodePointRange{From: rune(70070), To: rune(70078)},
+ &CodePointRange{From: rune(70079), To: rune(70080)},
+ &CodePointRange{From: rune(70081), To: rune(70084)},
+ &CodePointRange{From: rune(70085), To: rune(70088)},
+ &CodePointRange{From: rune(70089), To: rune(70092)},
+ &CodePointRange{From: rune(70093), To: rune(70093)},
+ &CodePointRange{From: rune(70094), To: rune(70094)},
+ &CodePointRange{From: rune(70095), To: rune(70095)},
+ &CodePointRange{From: rune(70096), To: rune(70105)},
+ &CodePointRange{From: rune(70106), To: rune(70106)},
+ &CodePointRange{From: rune(70107), To: rune(70107)},
+ &CodePointRange{From: rune(70108), To: rune(70108)},
+ &CodePointRange{From: rune(70109), To: rune(70111)},
+ },
+ "sidd": {
+ &CodePointRange{From: rune(71040), To: rune(71086)},
+ &CodePointRange{From: rune(71087), To: rune(71089)},
+ &CodePointRange{From: rune(71090), To: rune(71093)},
+ &CodePointRange{From: rune(71096), To: rune(71099)},
+ &CodePointRange{From: rune(71100), To: rune(71101)},
+ &CodePointRange{From: rune(71102), To: rune(71102)},
+ &CodePointRange{From: rune(71103), To: rune(71104)},
+ &CodePointRange{From: rune(71105), To: rune(71127)},
+ &CodePointRange{From: rune(71128), To: rune(71131)},
+ &CodePointRange{From: rune(71132), To: rune(71133)},
+ },
+ "sind": {
+ &CodePointRange{From: rune(70320), To: rune(70366)},
+ &CodePointRange{From: rune(70367), To: rune(70367)},
+ &CodePointRange{From: rune(70368), To: rune(70370)},
+ &CodePointRange{From: rune(70371), To: rune(70378)},
+ &CodePointRange{From: rune(70384), To: rune(70393)},
+ },
+ "sinh": {
+ &CodePointRange{From: rune(3457), To: rune(3457)},
+ &CodePointRange{From: rune(3458), To: rune(3459)},
+ &CodePointRange{From: rune(3461), To: rune(3478)},
+ &CodePointRange{From: rune(3482), To: rune(3505)},
+ &CodePointRange{From: rune(3507), To: rune(3515)},
+ &CodePointRange{From: rune(3517), To: rune(3517)},
+ &CodePointRange{From: rune(3520), To: rune(3526)},
+ &CodePointRange{From: rune(3530), To: rune(3530)},
+ &CodePointRange{From: rune(3535), To: rune(3537)},
+ &CodePointRange{From: rune(3538), To: rune(3540)},
+ &CodePointRange{From: rune(3542), To: rune(3542)},
+ &CodePointRange{From: rune(3544), To: rune(3551)},
+ &CodePointRange{From: rune(3558), To: rune(3567)},
+ &CodePointRange{From: rune(3570), To: rune(3571)},
+ &CodePointRange{From: rune(3572), To: rune(3572)},
+ &CodePointRange{From: rune(70113), To: rune(70132)},
+ },
+ "sogd": {
+ &CodePointRange{From: rune(69424), To: rune(69445)},
+ &CodePointRange{From: rune(69446), To: rune(69456)},
+ &CodePointRange{From: rune(69457), To: rune(69460)},
+ &CodePointRange{From: rune(69461), To: rune(69465)},
+ },
+ "sogo": {
+ &CodePointRange{From: rune(69376), To: rune(69404)},
+ &CodePointRange{From: rune(69405), To: rune(69414)},
+ &CodePointRange{From: rune(69415), To: rune(69415)},
+ },
+ "sora": {
+ &CodePointRange{From: rune(69840), To: rune(69864)},
+ &CodePointRange{From: rune(69872), To: rune(69881)},
+ },
+ "soyo": {
+ &CodePointRange{From: rune(72272), To: rune(72272)},
+ &CodePointRange{From: rune(72273), To: rune(72278)},
+ &CodePointRange{From: rune(72279), To: rune(72280)},
+ &CodePointRange{From: rune(72281), To: rune(72283)},
+ &CodePointRange{From: rune(72284), To: rune(72329)},
+ &CodePointRange{From: rune(72330), To: rune(72342)},
+ &CodePointRange{From: rune(72343), To: rune(72343)},
+ &CodePointRange{From: rune(72344), To: rune(72345)},
+ &CodePointRange{From: rune(72346), To: rune(72348)},
+ &CodePointRange{From: rune(72349), To: rune(72349)},
+ &CodePointRange{From: rune(72350), To: rune(72354)},
+ },
+ "sund": {
+ &CodePointRange{From: rune(7040), To: rune(7041)},
+ &CodePointRange{From: rune(7042), To: rune(7042)},
+ &CodePointRange{From: rune(7043), To: rune(7072)},
+ &CodePointRange{From: rune(7073), To: rune(7073)},
+ &CodePointRange{From: rune(7074), To: rune(7077)},
+ &CodePointRange{From: rune(7078), To: rune(7079)},
+ &CodePointRange{From: rune(7080), To: rune(7081)},
+ &CodePointRange{From: rune(7082), To: rune(7082)},
+ &CodePointRange{From: rune(7083), To: rune(7085)},
+ &CodePointRange{From: rune(7086), To: rune(7087)},
+ &CodePointRange{From: rune(7088), To: rune(7097)},
+ &CodePointRange{From: rune(7098), To: rune(7103)},
+ &CodePointRange{From: rune(7360), To: rune(7367)},
+ },
+ "sylo": {
+ &CodePointRange{From: rune(43008), To: rune(43009)},
+ &CodePointRange{From: rune(43010), To: rune(43010)},
+ &CodePointRange{From: rune(43011), To: rune(43013)},
+ &CodePointRange{From: rune(43014), To: rune(43014)},
+ &CodePointRange{From: rune(43015), To: rune(43018)},
+ &CodePointRange{From: rune(43019), To: rune(43019)},
+ &CodePointRange{From: rune(43020), To: rune(43042)},
+ &CodePointRange{From: rune(43043), To: rune(43044)},
+ &CodePointRange{From: rune(43045), To: rune(43046)},
+ &CodePointRange{From: rune(43047), To: rune(43047)},
+ &CodePointRange{From: rune(43048), To: rune(43051)},
+ &CodePointRange{From: rune(43052), To: rune(43052)},
+ },
+ "syrc": {
+ &CodePointRange{From: rune(1792), To: rune(1805)},
+ &CodePointRange{From: rune(1807), To: rune(1807)},
+ &CodePointRange{From: rune(1808), To: rune(1808)},
+ &CodePointRange{From: rune(1809), To: rune(1809)},
+ &CodePointRange{From: rune(1810), To: rune(1839)},
+ &CodePointRange{From: rune(1840), To: rune(1866)},
+ &CodePointRange{From: rune(1869), To: rune(1871)},
+ &CodePointRange{From: rune(2144), To: rune(2154)},
+ },
+ "tagb": {
+ &CodePointRange{From: rune(5984), To: rune(5996)},
+ &CodePointRange{From: rune(5998), To: rune(6000)},
+ &CodePointRange{From: rune(6002), To: rune(6003)},
+ },
+ "takr": {
+ &CodePointRange{From: rune(71296), To: rune(71338)},
+ &CodePointRange{From: rune(71339), To: rune(71339)},
+ &CodePointRange{From: rune(71340), To: rune(71340)},
+ &CodePointRange{From: rune(71341), To: rune(71341)},
+ &CodePointRange{From: rune(71342), To: rune(71343)},
+ &CodePointRange{From: rune(71344), To: rune(71349)},
+ &CodePointRange{From: rune(71350), To: rune(71350)},
+ &CodePointRange{From: rune(71351), To: rune(71351)},
+ &CodePointRange{From: rune(71352), To: rune(71352)},
+ &CodePointRange{From: rune(71360), To: rune(71369)},
+ },
+ "tale": {
+ &CodePointRange{From: rune(6480), To: rune(6509)},
+ &CodePointRange{From: rune(6512), To: rune(6516)},
+ },
+ "talu": {
+ &CodePointRange{From: rune(6528), To: rune(6571)},
+ &CodePointRange{From: rune(6576), To: rune(6601)},
+ &CodePointRange{From: rune(6608), To: rune(6617)},
+ &CodePointRange{From: rune(6618), To: rune(6618)},
+ &CodePointRange{From: rune(6622), To: rune(6623)},
+ },
+ "taml": {
+ &CodePointRange{From: rune(2946), To: rune(2946)},
+ &CodePointRange{From: rune(2947), To: rune(2947)},
+ &CodePointRange{From: rune(2949), To: rune(2954)},
+ &CodePointRange{From: rune(2958), To: rune(2960)},
+ &CodePointRange{From: rune(2962), To: rune(2965)},
+ &CodePointRange{From: rune(2969), To: rune(2970)},
+ &CodePointRange{From: rune(2972), To: rune(2972)},
+ &CodePointRange{From: rune(2974), To: rune(2975)},
+ &CodePointRange{From: rune(2979), To: rune(2980)},
+ &CodePointRange{From: rune(2984), To: rune(2986)},
+ &CodePointRange{From: rune(2990), To: rune(3001)},
+ &CodePointRange{From: rune(3006), To: rune(3007)},
+ &CodePointRange{From: rune(3008), To: rune(3008)},
+ &CodePointRange{From: rune(3009), To: rune(3010)},
+ &CodePointRange{From: rune(3014), To: rune(3016)},
+ &CodePointRange{From: rune(3018), To: rune(3020)},
+ &CodePointRange{From: rune(3021), To: rune(3021)},
+ &CodePointRange{From: rune(3024), To: rune(3024)},
+ &CodePointRange{From: rune(3031), To: rune(3031)},
+ &CodePointRange{From: rune(3046), To: rune(3055)},
+ &CodePointRange{From: rune(3056), To: rune(3058)},
+ &CodePointRange{From: rune(3059), To: rune(3064)},
+ &CodePointRange{From: rune(3065), To: rune(3065)},
+ &CodePointRange{From: rune(3066), To: rune(3066)},
+ &CodePointRange{From: rune(73664), To: rune(73684)},
+ &CodePointRange{From: rune(73685), To: rune(73692)},
+ &CodePointRange{From: rune(73693), To: rune(73696)},
+ &CodePointRange{From: rune(73697), To: rune(73713)},
+ &CodePointRange{From: rune(73727), To: rune(73727)},
+ },
+ "tang": {
+ &CodePointRange{From: rune(94176), To: rune(94176)},
+ &CodePointRange{From: rune(94208), To: rune(100343)},
+ &CodePointRange{From: rune(100352), To: rune(101119)},
+ &CodePointRange{From: rune(101632), To: rune(101640)},
+ },
+ "tavt": {
+ &CodePointRange{From: rune(43648), To: rune(43695)},
+ &CodePointRange{From: rune(43696), To: rune(43696)},
+ &CodePointRange{From: rune(43697), To: rune(43697)},
+ &CodePointRange{From: rune(43698), To: rune(43700)},
+ &CodePointRange{From: rune(43701), To: rune(43702)},
+ &CodePointRange{From: rune(43703), To: rune(43704)},
+ &CodePointRange{From: rune(43705), To: rune(43709)},
+ &CodePointRange{From: rune(43710), To: rune(43711)},
+ &CodePointRange{From: rune(43712), To: rune(43712)},
+ &CodePointRange{From: rune(43713), To: rune(43713)},
+ &CodePointRange{From: rune(43714), To: rune(43714)},
+ &CodePointRange{From: rune(43739), To: rune(43740)},
+ &CodePointRange{From: rune(43741), To: rune(43741)},
+ &CodePointRange{From: rune(43742), To: rune(43743)},
+ },
+ "telu": {
+ &CodePointRange{From: rune(3072), To: rune(3072)},
+ &CodePointRange{From: rune(3073), To: rune(3075)},
+ &CodePointRange{From: rune(3076), To: rune(3076)},
+ &CodePointRange{From: rune(3077), To: rune(3084)},
+ &CodePointRange{From: rune(3086), To: rune(3088)},
+ &CodePointRange{From: rune(3090), To: rune(3112)},
+ &CodePointRange{From: rune(3114), To: rune(3129)},
+ &CodePointRange{From: rune(3133), To: rune(3133)},
+ &CodePointRange{From: rune(3134), To: rune(3136)},
+ &CodePointRange{From: rune(3137), To: rune(3140)},
+ &CodePointRange{From: rune(3142), To: rune(3144)},
+ &CodePointRange{From: rune(3146), To: rune(3149)},
+ &CodePointRange{From: rune(3157), To: rune(3158)},
+ &CodePointRange{From: rune(3160), To: rune(3162)},
+ &CodePointRange{From: rune(3168), To: rune(3169)},
+ &CodePointRange{From: rune(3170), To: rune(3171)},
+ &CodePointRange{From: rune(3174), To: rune(3183)},
+ &CodePointRange{From: rune(3191), To: rune(3191)},
+ &CodePointRange{From: rune(3192), To: rune(3198)},
+ &CodePointRange{From: rune(3199), To: rune(3199)},
+ },
+ "tfng": {
+ &CodePointRange{From: rune(11568), To: rune(11623)},
+ &CodePointRange{From: rune(11631), To: rune(11631)},
+ &CodePointRange{From: rune(11632), To: rune(11632)},
+ &CodePointRange{From: rune(11647), To: rune(11647)},
+ },
+ "tglg": {
+ &CodePointRange{From: rune(5888), To: rune(5900)},
+ &CodePointRange{From: rune(5902), To: rune(5905)},
+ &CodePointRange{From: rune(5906), To: rune(5908)},
+ },
+ "thaa": {
+ &CodePointRange{From: rune(1920), To: rune(1957)},
+ &CodePointRange{From: rune(1958), To: rune(1968)},
+ &CodePointRange{From: rune(1969), To: rune(1969)},
+ },
+ "thai": {
+ &CodePointRange{From: rune(3585), To: rune(3632)},
+ &CodePointRange{From: rune(3633), To: rune(3633)},
+ &CodePointRange{From: rune(3634), To: rune(3635)},
+ &CodePointRange{From: rune(3636), To: rune(3642)},
+ &CodePointRange{From: rune(3648), To: rune(3653)},
+ &CodePointRange{From: rune(3654), To: rune(3654)},
+ &CodePointRange{From: rune(3655), To: rune(3662)},
+ &CodePointRange{From: rune(3663), To: rune(3663)},
+ &CodePointRange{From: rune(3664), To: rune(3673)},
+ &CodePointRange{From: rune(3674), To: rune(3675)},
+ },
+ "tibt": {
+ &CodePointRange{From: rune(3840), To: rune(3840)},
+ &CodePointRange{From: rune(3841), To: rune(3843)},
+ &CodePointRange{From: rune(3844), To: rune(3858)},
+ &CodePointRange{From: rune(3859), To: rune(3859)},
+ &CodePointRange{From: rune(3860), To: rune(3860)},
+ &CodePointRange{From: rune(3861), To: rune(3863)},
+ &CodePointRange{From: rune(3864), To: rune(3865)},
+ &CodePointRange{From: rune(3866), To: rune(3871)},
+ &CodePointRange{From: rune(3872), To: rune(3881)},
+ &CodePointRange{From: rune(3882), To: rune(3891)},
+ &CodePointRange{From: rune(3892), To: rune(3892)},
+ &CodePointRange{From: rune(3893), To: rune(3893)},
+ &CodePointRange{From: rune(3894), To: rune(3894)},
+ &CodePointRange{From: rune(3895), To: rune(3895)},
+ &CodePointRange{From: rune(3896), To: rune(3896)},
+ &CodePointRange{From: rune(3897), To: rune(3897)},
+ &CodePointRange{From: rune(3898), To: rune(3898)},
+ &CodePointRange{From: rune(3899), To: rune(3899)},
+ &CodePointRange{From: rune(3900), To: rune(3900)},
+ &CodePointRange{From: rune(3901), To: rune(3901)},
+ &CodePointRange{From: rune(3902), To: rune(3903)},
+ &CodePointRange{From: rune(3904), To: rune(3911)},
+ &CodePointRange{From: rune(3913), To: rune(3948)},
+ &CodePointRange{From: rune(3953), To: rune(3966)},
+ &CodePointRange{From: rune(3967), To: rune(3967)},
+ &CodePointRange{From: rune(3968), To: rune(3972)},
+ &CodePointRange{From: rune(3973), To: rune(3973)},
+ &CodePointRange{From: rune(3974), To: rune(3975)},
+ &CodePointRange{From: rune(3976), To: rune(3980)},
+ &CodePointRange{From: rune(3981), To: rune(3991)},
+ &CodePointRange{From: rune(3993), To: rune(4028)},
+ &CodePointRange{From: rune(4030), To: rune(4037)},
+ &CodePointRange{From: rune(4038), To: rune(4038)},
+ &CodePointRange{From: rune(4039), To: rune(4044)},
+ &CodePointRange{From: rune(4046), To: rune(4047)},
+ &CodePointRange{From: rune(4048), To: rune(4052)},
+ &CodePointRange{From: rune(4057), To: rune(4058)},
+ },
+ "tirh": {
+ &CodePointRange{From: rune(70784), To: rune(70831)},
+ &CodePointRange{From: rune(70832), To: rune(70834)},
+ &CodePointRange{From: rune(70835), To: rune(70840)},
+ &CodePointRange{From: rune(70841), To: rune(70841)},
+ &CodePointRange{From: rune(70842), To: rune(70842)},
+ &CodePointRange{From: rune(70843), To: rune(70846)},
+ &CodePointRange{From: rune(70847), To: rune(70848)},
+ &CodePointRange{From: rune(70849), To: rune(70849)},
+ &CodePointRange{From: rune(70850), To: rune(70851)},
+ &CodePointRange{From: rune(70852), To: rune(70853)},
+ &CodePointRange{From: rune(70854), To: rune(70854)},
+ &CodePointRange{From: rune(70855), To: rune(70855)},
+ &CodePointRange{From: rune(70864), To: rune(70873)},
+ },
+ "ugar": {
+ &CodePointRange{From: rune(66432), To: rune(66461)},
+ &CodePointRange{From: rune(66463), To: rune(66463)},
+ },
+ "vaii": {
+ &CodePointRange{From: rune(42240), To: rune(42507)},
+ &CodePointRange{From: rune(42508), To: rune(42508)},
+ &CodePointRange{From: rune(42509), To: rune(42511)},
+ &CodePointRange{From: rune(42512), To: rune(42527)},
+ &CodePointRange{From: rune(42528), To: rune(42537)},
+ &CodePointRange{From: rune(42538), To: rune(42539)},
+ },
+ "wara": {
+ &CodePointRange{From: rune(71840), To: rune(71903)},
+ &CodePointRange{From: rune(71904), To: rune(71913)},
+ &CodePointRange{From: rune(71914), To: rune(71922)},
+ &CodePointRange{From: rune(71935), To: rune(71935)},
+ },
+ "wcho": {
+ &CodePointRange{From: rune(123584), To: rune(123627)},
+ &CodePointRange{From: rune(123628), To: rune(123631)},
+ &CodePointRange{From: rune(123632), To: rune(123641)},
+ &CodePointRange{From: rune(123647), To: rune(123647)},
+ },
+ "xpeo": {
+ &CodePointRange{From: rune(66464), To: rune(66499)},
+ &CodePointRange{From: rune(66504), To: rune(66511)},
+ &CodePointRange{From: rune(66512), To: rune(66512)},
+ &CodePointRange{From: rune(66513), To: rune(66517)},
+ },
+ "xsux": {
+ &CodePointRange{From: rune(73728), To: rune(74649)},
+ &CodePointRange{From: rune(74752), To: rune(74862)},
+ &CodePointRange{From: rune(74864), To: rune(74868)},
+ &CodePointRange{From: rune(74880), To: rune(75075)},
+ },
+ "yezi": {
+ &CodePointRange{From: rune(69248), To: rune(69289)},
+ &CodePointRange{From: rune(69291), To: rune(69292)},
+ &CodePointRange{From: rune(69293), To: rune(69293)},
+ &CodePointRange{From: rune(69296), To: rune(69297)},
+ },
+ "yiii": {
+ &CodePointRange{From: rune(40960), To: rune(40980)},
+ &CodePointRange{From: rune(40981), To: rune(40981)},
+ &CodePointRange{From: rune(40982), To: rune(42124)},
+ &CodePointRange{From: rune(42128), To: rune(42182)},
+ },
+ "zanb": {
+ &CodePointRange{From: rune(72192), To: rune(72192)},
+ &CodePointRange{From: rune(72193), To: rune(72202)},
+ &CodePointRange{From: rune(72203), To: rune(72242)},
+ &CodePointRange{From: rune(72243), To: rune(72248)},
+ &CodePointRange{From: rune(72249), To: rune(72249)},
+ &CodePointRange{From: rune(72250), To: rune(72250)},
+ &CodePointRange{From: rune(72251), To: rune(72254)},
+ &CodePointRange{From: rune(72255), To: rune(72262)},
+ &CodePointRange{From: rune(72263), To: rune(72263)},
+ },
+ "zinh": {
+ &CodePointRange{From: rune(768), To: rune(879)},
+ &CodePointRange{From: rune(1157), To: rune(1158)},
+ &CodePointRange{From: rune(1611), To: rune(1621)},
+ &CodePointRange{From: rune(1648), To: rune(1648)},
+ &CodePointRange{From: rune(2385), To: rune(2388)},
+ &CodePointRange{From: rune(6832), To: rune(6845)},
+ &CodePointRange{From: rune(6846), To: rune(6846)},
+ &CodePointRange{From: rune(6847), To: rune(6848)},
+ &CodePointRange{From: rune(7376), To: rune(7378)},
+ &CodePointRange{From: rune(7380), To: rune(7392)},
+ &CodePointRange{From: rune(7394), To: rune(7400)},
+ &CodePointRange{From: rune(7405), To: rune(7405)},
+ &CodePointRange{From: rune(7412), To: rune(7412)},
+ &CodePointRange{From: rune(7416), To: rune(7417)},
+ &CodePointRange{From: rune(7616), To: rune(7673)},
+ &CodePointRange{From: rune(7675), To: rune(7679)},
+ &CodePointRange{From: rune(8204), To: rune(8205)},
+ &CodePointRange{From: rune(8400), To: rune(8412)},
+ &CodePointRange{From: rune(8413), To: rune(8416)},
+ &CodePointRange{From: rune(8417), To: rune(8417)},
+ &CodePointRange{From: rune(8418), To: rune(8420)},
+ &CodePointRange{From: rune(8421), To: rune(8432)},
+ &CodePointRange{From: rune(12330), To: rune(12333)},
+ &CodePointRange{From: rune(12441), To: rune(12442)},
+ &CodePointRange{From: rune(65024), To: rune(65039)},
+ &CodePointRange{From: rune(65056), To: rune(65069)},
+ &CodePointRange{From: rune(66045), To: rune(66045)},
+ &CodePointRange{From: rune(66272), To: rune(66272)},
+ &CodePointRange{From: rune(70459), To: rune(70459)},
+ &CodePointRange{From: rune(119143), To: rune(119145)},
+ &CodePointRange{From: rune(119163), To: rune(119170)},
+ &CodePointRange{From: rune(119173), To: rune(119179)},
+ &CodePointRange{From: rune(119210), To: rune(119213)},
+ &CodePointRange{From: rune(917760), To: rune(917999)},
+ },
+ "zyyy": {
+ &CodePointRange{From: rune(0), To: rune(31)},
+ &CodePointRange{From: rune(32), To: rune(32)},
+ &CodePointRange{From: rune(33), To: rune(35)},
+ &CodePointRange{From: rune(36), To: rune(36)},
+ &CodePointRange{From: rune(37), To: rune(39)},
+ &CodePointRange{From: rune(40), To: rune(40)},
+ &CodePointRange{From: rune(41), To: rune(41)},
+ &CodePointRange{From: rune(42), To: rune(42)},
+ &CodePointRange{From: rune(43), To: rune(43)},
+ &CodePointRange{From: rune(44), To: rune(44)},
+ &CodePointRange{From: rune(45), To: rune(45)},
+ &CodePointRange{From: rune(46), To: rune(47)},
+ &CodePointRange{From: rune(48), To: rune(57)},
+ &CodePointRange{From: rune(58), To: rune(59)},
+ &CodePointRange{From: rune(60), To: rune(62)},
+ &CodePointRange{From: rune(63), To: rune(64)},
+ &CodePointRange{From: rune(91), To: rune(91)},
+ &CodePointRange{From: rune(92), To: rune(92)},
+ &CodePointRange{From: rune(93), To: rune(93)},
+ &CodePointRange{From: rune(94), To: rune(94)},
+ &CodePointRange{From: rune(95), To: rune(95)},
+ &CodePointRange{From: rune(96), To: rune(96)},
+ &CodePointRange{From: rune(123), To: rune(123)},
+ &CodePointRange{From: rune(124), To: rune(124)},
+ &CodePointRange{From: rune(125), To: rune(125)},
+ &CodePointRange{From: rune(126), To: rune(126)},
+ &CodePointRange{From: rune(127), To: rune(159)},
+ &CodePointRange{From: rune(160), To: rune(160)},
+ &CodePointRange{From: rune(161), To: rune(161)},
+ &CodePointRange{From: rune(162), To: rune(165)},
+ &CodePointRange{From: rune(166), To: rune(166)},
+ &CodePointRange{From: rune(167), To: rune(167)},
+ &CodePointRange{From: rune(168), To: rune(168)},
+ &CodePointRange{From: rune(169), To: rune(169)},
+ &CodePointRange{From: rune(171), To: rune(171)},
+ &CodePointRange{From: rune(172), To: rune(172)},
+ &CodePointRange{From: rune(173), To: rune(173)},
+ &CodePointRange{From: rune(174), To: rune(174)},
+ &CodePointRange{From: rune(175), To: rune(175)},
+ &CodePointRange{From: rune(176), To: rune(176)},
+ &CodePointRange{From: rune(177), To: rune(177)},
+ &CodePointRange{From: rune(178), To: rune(179)},
+ &CodePointRange{From: rune(180), To: rune(180)},
+ &CodePointRange{From: rune(181), To: rune(181)},
+ &CodePointRange{From: rune(182), To: rune(183)},
+ &CodePointRange{From: rune(184), To: rune(184)},
+ &CodePointRange{From: rune(185), To: rune(185)},
+ &CodePointRange{From: rune(187), To: rune(187)},
+ &CodePointRange{From: rune(188), To: rune(190)},
+ &CodePointRange{From: rune(191), To: rune(191)},
+ &CodePointRange{From: rune(215), To: rune(215)},
+ &CodePointRange{From: rune(247), To: rune(247)},
+ &CodePointRange{From: rune(697), To: rune(705)},
+ &CodePointRange{From: rune(706), To: rune(709)},
+ &CodePointRange{From: rune(710), To: rune(721)},
+ &CodePointRange{From: rune(722), To: rune(735)},
+ &CodePointRange{From: rune(741), To: rune(745)},
+ &CodePointRange{From: rune(748), To: rune(748)},
+ &CodePointRange{From: rune(749), To: rune(749)},
+ &CodePointRange{From: rune(750), To: rune(750)},
+ &CodePointRange{From: rune(751), To: rune(767)},
+ &CodePointRange{From: rune(884), To: rune(884)},
+ &CodePointRange{From: rune(894), To: rune(894)},
+ &CodePointRange{From: rune(901), To: rune(901)},
+ &CodePointRange{From: rune(903), To: rune(903)},
+ &CodePointRange{From: rune(1541), To: rune(1541)},
+ &CodePointRange{From: rune(1548), To: rune(1548)},
+ &CodePointRange{From: rune(1563), To: rune(1563)},
+ &CodePointRange{From: rune(1567), To: rune(1567)},
+ &CodePointRange{From: rune(1600), To: rune(1600)},
+ &CodePointRange{From: rune(1757), To: rune(1757)},
+ &CodePointRange{From: rune(2274), To: rune(2274)},
+ &CodePointRange{From: rune(2404), To: rune(2405)},
+ &CodePointRange{From: rune(3647), To: rune(3647)},
+ &CodePointRange{From: rune(4053), To: rune(4056)},
+ &CodePointRange{From: rune(4347), To: rune(4347)},
+ &CodePointRange{From: rune(5867), To: rune(5869)},
+ &CodePointRange{From: rune(5941), To: rune(5942)},
+ &CodePointRange{From: rune(6146), To: rune(6147)},
+ &CodePointRange{From: rune(6149), To: rune(6149)},
+ &CodePointRange{From: rune(7379), To: rune(7379)},
+ &CodePointRange{From: rune(7393), To: rune(7393)},
+ &CodePointRange{From: rune(7401), To: rune(7404)},
+ &CodePointRange{From: rune(7406), To: rune(7411)},
+ &CodePointRange{From: rune(7413), To: rune(7414)},
+ &CodePointRange{From: rune(7415), To: rune(7415)},
+ &CodePointRange{From: rune(7418), To: rune(7418)},
+ &CodePointRange{From: rune(8192), To: rune(8202)},
+ &CodePointRange{From: rune(8203), To: rune(8203)},
+ &CodePointRange{From: rune(8206), To: rune(8207)},
+ &CodePointRange{From: rune(8208), To: rune(8213)},
+ &CodePointRange{From: rune(8214), To: rune(8215)},
+ &CodePointRange{From: rune(8216), To: rune(8216)},
+ &CodePointRange{From: rune(8217), To: rune(8217)},
+ &CodePointRange{From: rune(8218), To: rune(8218)},
+ &CodePointRange{From: rune(8219), To: rune(8220)},
+ &CodePointRange{From: rune(8221), To: rune(8221)},
+ &CodePointRange{From: rune(8222), To: rune(8222)},
+ &CodePointRange{From: rune(8223), To: rune(8223)},
+ &CodePointRange{From: rune(8224), To: rune(8231)},
+ &CodePointRange{From: rune(8232), To: rune(8232)},
+ &CodePointRange{From: rune(8233), To: rune(8233)},
+ &CodePointRange{From: rune(8234), To: rune(8238)},
+ &CodePointRange{From: rune(8239), To: rune(8239)},
+ &CodePointRange{From: rune(8240), To: rune(8248)},
+ &CodePointRange{From: rune(8249), To: rune(8249)},
+ &CodePointRange{From: rune(8250), To: rune(8250)},
+ &CodePointRange{From: rune(8251), To: rune(8254)},
+ &CodePointRange{From: rune(8255), To: rune(8256)},
+ &CodePointRange{From: rune(8257), To: rune(8259)},
+ &CodePointRange{From: rune(8260), To: rune(8260)},
+ &CodePointRange{From: rune(8261), To: rune(8261)},
+ &CodePointRange{From: rune(8262), To: rune(8262)},
+ &CodePointRange{From: rune(8263), To: rune(8273)},
+ &CodePointRange{From: rune(8274), To: rune(8274)},
+ &CodePointRange{From: rune(8275), To: rune(8275)},
+ &CodePointRange{From: rune(8276), To: rune(8276)},
+ &CodePointRange{From: rune(8277), To: rune(8286)},
+ &CodePointRange{From: rune(8287), To: rune(8287)},
+ &CodePointRange{From: rune(8288), To: rune(8292)},
+ &CodePointRange{From: rune(8294), To: rune(8303)},
+ &CodePointRange{From: rune(8304), To: rune(8304)},
+ &CodePointRange{From: rune(8308), To: rune(8313)},
+ &CodePointRange{From: rune(8314), To: rune(8316)},
+ &CodePointRange{From: rune(8317), To: rune(8317)},
+ &CodePointRange{From: rune(8318), To: rune(8318)},
+ &CodePointRange{From: rune(8320), To: rune(8329)},
+ &CodePointRange{From: rune(8330), To: rune(8332)},
+ &CodePointRange{From: rune(8333), To: rune(8333)},
+ &CodePointRange{From: rune(8334), To: rune(8334)},
+ &CodePointRange{From: rune(8352), To: rune(8383)},
+ &CodePointRange{From: rune(8448), To: rune(8449)},
+ &CodePointRange{From: rune(8450), To: rune(8450)},
+ &CodePointRange{From: rune(8451), To: rune(8454)},
+ &CodePointRange{From: rune(8455), To: rune(8455)},
+ &CodePointRange{From: rune(8456), To: rune(8457)},
+ &CodePointRange{From: rune(8458), To: rune(8467)},
+ &CodePointRange{From: rune(8468), To: rune(8468)},
+ &CodePointRange{From: rune(8469), To: rune(8469)},
+ &CodePointRange{From: rune(8470), To: rune(8471)},
+ &CodePointRange{From: rune(8472), To: rune(8472)},
+ &CodePointRange{From: rune(8473), To: rune(8477)},
+ &CodePointRange{From: rune(8478), To: rune(8483)},
+ &CodePointRange{From: rune(8484), To: rune(8484)},
+ &CodePointRange{From: rune(8485), To: rune(8485)},
+ &CodePointRange{From: rune(8487), To: rune(8487)},
+ &CodePointRange{From: rune(8488), To: rune(8488)},
+ &CodePointRange{From: rune(8489), To: rune(8489)},
+ &CodePointRange{From: rune(8492), To: rune(8493)},
+ &CodePointRange{From: rune(8494), To: rune(8494)},
+ &CodePointRange{From: rune(8495), To: rune(8497)},
+ &CodePointRange{From: rune(8499), To: rune(8500)},
+ &CodePointRange{From: rune(8501), To: rune(8504)},
+ &CodePointRange{From: rune(8505), To: rune(8505)},
+ &CodePointRange{From: rune(8506), To: rune(8507)},
+ &CodePointRange{From: rune(8508), To: rune(8511)},
+ &CodePointRange{From: rune(8512), To: rune(8516)},
+ &CodePointRange{From: rune(8517), To: rune(8521)},
+ &CodePointRange{From: rune(8522), To: rune(8522)},
+ &CodePointRange{From: rune(8523), To: rune(8523)},
+ &CodePointRange{From: rune(8524), To: rune(8525)},
+ &CodePointRange{From: rune(8527), To: rune(8527)},
+ &CodePointRange{From: rune(8528), To: rune(8543)},
+ &CodePointRange{From: rune(8585), To: rune(8585)},
+ &CodePointRange{From: rune(8586), To: rune(8587)},
+ &CodePointRange{From: rune(8592), To: rune(8596)},
+ &CodePointRange{From: rune(8597), To: rune(8601)},
+ &CodePointRange{From: rune(8602), To: rune(8603)},
+ &CodePointRange{From: rune(8604), To: rune(8607)},
+ &CodePointRange{From: rune(8608), To: rune(8608)},
+ &CodePointRange{From: rune(8609), To: rune(8610)},
+ &CodePointRange{From: rune(8611), To: rune(8611)},
+ &CodePointRange{From: rune(8612), To: rune(8613)},
+ &CodePointRange{From: rune(8614), To: rune(8614)},
+ &CodePointRange{From: rune(8615), To: rune(8621)},
+ &CodePointRange{From: rune(8622), To: rune(8622)},
+ &CodePointRange{From: rune(8623), To: rune(8653)},
+ &CodePointRange{From: rune(8654), To: rune(8655)},
+ &CodePointRange{From: rune(8656), To: rune(8657)},
+ &CodePointRange{From: rune(8658), To: rune(8658)},
+ &CodePointRange{From: rune(8659), To: rune(8659)},
+ &CodePointRange{From: rune(8660), To: rune(8660)},
+ &CodePointRange{From: rune(8661), To: rune(8691)},
+ &CodePointRange{From: rune(8692), To: rune(8959)},
+ &CodePointRange{From: rune(8960), To: rune(8967)},
+ &CodePointRange{From: rune(8968), To: rune(8968)},
+ &CodePointRange{From: rune(8969), To: rune(8969)},
+ &CodePointRange{From: rune(8970), To: rune(8970)},
+ &CodePointRange{From: rune(8971), To: rune(8971)},
+ &CodePointRange{From: rune(8972), To: rune(8991)},
+ &CodePointRange{From: rune(8992), To: rune(8993)},
+ &CodePointRange{From: rune(8994), To: rune(9000)},
+ &CodePointRange{From: rune(9001), To: rune(9001)},
+ &CodePointRange{From: rune(9002), To: rune(9002)},
+ &CodePointRange{From: rune(9003), To: rune(9083)},
+ &CodePointRange{From: rune(9084), To: rune(9084)},
+ &CodePointRange{From: rune(9085), To: rune(9114)},
+ &CodePointRange{From: rune(9115), To: rune(9139)},
+ &CodePointRange{From: rune(9140), To: rune(9179)},
+ &CodePointRange{From: rune(9180), To: rune(9185)},
+ &CodePointRange{From: rune(9186), To: rune(9254)},
+ &CodePointRange{From: rune(9280), To: rune(9290)},
+ &CodePointRange{From: rune(9312), To: rune(9371)},
+ &CodePointRange{From: rune(9372), To: rune(9449)},
+ &CodePointRange{From: rune(9450), To: rune(9471)},
+ &CodePointRange{From: rune(9472), To: rune(9654)},
+ &CodePointRange{From: rune(9655), To: rune(9655)},
+ &CodePointRange{From: rune(9656), To: rune(9664)},
+ &CodePointRange{From: rune(9665), To: rune(9665)},
+ &CodePointRange{From: rune(9666), To: rune(9719)},
+ &CodePointRange{From: rune(9720), To: rune(9727)},
+ &CodePointRange{From: rune(9728), To: rune(9838)},
+ &CodePointRange{From: rune(9839), To: rune(9839)},
+ &CodePointRange{From: rune(9840), To: rune(10087)},
+ &CodePointRange{From: rune(10088), To: rune(10088)},
+ &CodePointRange{From: rune(10089), To: rune(10089)},
+ &CodePointRange{From: rune(10090), To: rune(10090)},
+ &CodePointRange{From: rune(10091), To: rune(10091)},
+ &CodePointRange{From: rune(10092), To: rune(10092)},
+ &CodePointRange{From: rune(10093), To: rune(10093)},
+ &CodePointRange{From: rune(10094), To: rune(10094)},
+ &CodePointRange{From: rune(10095), To: rune(10095)},
+ &CodePointRange{From: rune(10096), To: rune(10096)},
+ &CodePointRange{From: rune(10097), To: rune(10097)},
+ &CodePointRange{From: rune(10098), To: rune(10098)},
+ &CodePointRange{From: rune(10099), To: rune(10099)},
+ &CodePointRange{From: rune(10100), To: rune(10100)},
+ &CodePointRange{From: rune(10101), To: rune(10101)},
+ &CodePointRange{From: rune(10102), To: rune(10131)},
+ &CodePointRange{From: rune(10132), To: rune(10175)},
+ &CodePointRange{From: rune(10176), To: rune(10180)},
+ &CodePointRange{From: rune(10181), To: rune(10181)},
+ &CodePointRange{From: rune(10182), To: rune(10182)},
+ &CodePointRange{From: rune(10183), To: rune(10213)},
+ &CodePointRange{From: rune(10214), To: rune(10214)},
+ &CodePointRange{From: rune(10215), To: rune(10215)},
+ &CodePointRange{From: rune(10216), To: rune(10216)},
+ &CodePointRange{From: rune(10217), To: rune(10217)},
+ &CodePointRange{From: rune(10218), To: rune(10218)},
+ &CodePointRange{From: rune(10219), To: rune(10219)},
+ &CodePointRange{From: rune(10220), To: rune(10220)},
+ &CodePointRange{From: rune(10221), To: rune(10221)},
+ &CodePointRange{From: rune(10222), To: rune(10222)},
+ &CodePointRange{From: rune(10223), To: rune(10223)},
+ &CodePointRange{From: rune(10224), To: rune(10239)},
+ &CodePointRange{From: rune(10496), To: rune(10626)},
+ &CodePointRange{From: rune(10627), To: rune(10627)},
+ &CodePointRange{From: rune(10628), To: rune(10628)},
+ &CodePointRange{From: rune(10629), To: rune(10629)},
+ &CodePointRange{From: rune(10630), To: rune(10630)},
+ &CodePointRange{From: rune(10631), To: rune(10631)},
+ &CodePointRange{From: rune(10632), To: rune(10632)},
+ &CodePointRange{From: rune(10633), To: rune(10633)},
+ &CodePointRange{From: rune(10634), To: rune(10634)},
+ &CodePointRange{From: rune(10635), To: rune(10635)},
+ &CodePointRange{From: rune(10636), To: rune(10636)},
+ &CodePointRange{From: rune(10637), To: rune(10637)},
+ &CodePointRange{From: rune(10638), To: rune(10638)},
+ &CodePointRange{From: rune(10639), To: rune(10639)},
+ &CodePointRange{From: rune(10640), To: rune(10640)},
+ &CodePointRange{From: rune(10641), To: rune(10641)},
+ &CodePointRange{From: rune(10642), To: rune(10642)},
+ &CodePointRange{From: rune(10643), To: rune(10643)},
+ &CodePointRange{From: rune(10644), To: rune(10644)},
+ &CodePointRange{From: rune(10645), To: rune(10645)},
+ &CodePointRange{From: rune(10646), To: rune(10646)},
+ &CodePointRange{From: rune(10647), To: rune(10647)},
+ &CodePointRange{From: rune(10648), To: rune(10648)},
+ &CodePointRange{From: rune(10649), To: rune(10711)},
+ &CodePointRange{From: rune(10712), To: rune(10712)},
+ &CodePointRange{From: rune(10713), To: rune(10713)},
+ &CodePointRange{From: rune(10714), To: rune(10714)},
+ &CodePointRange{From: rune(10715), To: rune(10715)},
+ &CodePointRange{From: rune(10716), To: rune(10747)},
+ &CodePointRange{From: rune(10748), To: rune(10748)},
+ &CodePointRange{From: rune(10749), To: rune(10749)},
+ &CodePointRange{From: rune(10750), To: rune(11007)},
+ &CodePointRange{From: rune(11008), To: rune(11055)},
+ &CodePointRange{From: rune(11056), To: rune(11076)},
+ &CodePointRange{From: rune(11077), To: rune(11078)},
+ &CodePointRange{From: rune(11079), To: rune(11084)},
+ &CodePointRange{From: rune(11085), To: rune(11123)},
+ &CodePointRange{From: rune(11126), To: rune(11157)},
+ &CodePointRange{From: rune(11159), To: rune(11263)},
+ &CodePointRange{From: rune(11776), To: rune(11777)},
+ &CodePointRange{From: rune(11778), To: rune(11778)},
+ &CodePointRange{From: rune(11779), To: rune(11779)},
+ &CodePointRange{From: rune(11780), To: rune(11780)},
+ &CodePointRange{From: rune(11781), To: rune(11781)},
+ &CodePointRange{From: rune(11782), To: rune(11784)},
+ &CodePointRange{From: rune(11785), To: rune(11785)},
+ &CodePointRange{From: rune(11786), To: rune(11786)},
+ &CodePointRange{From: rune(11787), To: rune(11787)},
+ &CodePointRange{From: rune(11788), To: rune(11788)},
+ &CodePointRange{From: rune(11789), To: rune(11789)},
+ &CodePointRange{From: rune(11790), To: rune(11798)},
+ &CodePointRange{From: rune(11799), To: rune(11799)},
+ &CodePointRange{From: rune(11800), To: rune(11801)},
+ &CodePointRange{From: rune(11802), To: rune(11802)},
+ &CodePointRange{From: rune(11803), To: rune(11803)},
+ &CodePointRange{From: rune(11804), To: rune(11804)},
+ &CodePointRange{From: rune(11805), To: rune(11805)},
+ &CodePointRange{From: rune(11806), To: rune(11807)},
+ &CodePointRange{From: rune(11808), To: rune(11808)},
+ &CodePointRange{From: rune(11809), To: rune(11809)},
+ &CodePointRange{From: rune(11810), To: rune(11810)},
+ &CodePointRange{From: rune(11811), To: rune(11811)},
+ &CodePointRange{From: rune(11812), To: rune(11812)},
+ &CodePointRange{From: rune(11813), To: rune(11813)},
+ &CodePointRange{From: rune(11814), To: rune(11814)},
+ &CodePointRange{From: rune(11815), To: rune(11815)},
+ &CodePointRange{From: rune(11816), To: rune(11816)},
+ &CodePointRange{From: rune(11817), To: rune(11817)},
+ &CodePointRange{From: rune(11818), To: rune(11822)},
+ &CodePointRange{From: rune(11823), To: rune(11823)},
+ &CodePointRange{From: rune(11824), To: rune(11833)},
+ &CodePointRange{From: rune(11834), To: rune(11835)},
+ &CodePointRange{From: rune(11836), To: rune(11839)},
+ &CodePointRange{From: rune(11840), To: rune(11840)},
+ &CodePointRange{From: rune(11841), To: rune(11841)},
+ &CodePointRange{From: rune(11842), To: rune(11842)},
+ &CodePointRange{From: rune(11843), To: rune(11855)},
+ &CodePointRange{From: rune(11856), To: rune(11857)},
+ &CodePointRange{From: rune(11858), To: rune(11858)},
+ &CodePointRange{From: rune(12272), To: rune(12283)},
+ &CodePointRange{From: rune(12288), To: rune(12288)},
+ &CodePointRange{From: rune(12289), To: rune(12291)},
+ &CodePointRange{From: rune(12292), To: rune(12292)},
+ &CodePointRange{From: rune(12294), To: rune(12294)},
+ &CodePointRange{From: rune(12296), To: rune(12296)},
+ &CodePointRange{From: rune(12297), To: rune(12297)},
+ &CodePointRange{From: rune(12298), To: rune(12298)},
+ &CodePointRange{From: rune(12299), To: rune(12299)},
+ &CodePointRange{From: rune(12300), To: rune(12300)},
+ &CodePointRange{From: rune(12301), To: rune(12301)},
+ &CodePointRange{From: rune(12302), To: rune(12302)},
+ &CodePointRange{From: rune(12303), To: rune(12303)},
+ &CodePointRange{From: rune(12304), To: rune(12304)},
+ &CodePointRange{From: rune(12305), To: rune(12305)},
+ &CodePointRange{From: rune(12306), To: rune(12307)},
+ &CodePointRange{From: rune(12308), To: rune(12308)},
+ &CodePointRange{From: rune(12309), To: rune(12309)},
+ &CodePointRange{From: rune(12310), To: rune(12310)},
+ &CodePointRange{From: rune(12311), To: rune(12311)},
+ &CodePointRange{From: rune(12312), To: rune(12312)},
+ &CodePointRange{From: rune(12313), To: rune(12313)},
+ &CodePointRange{From: rune(12314), To: rune(12314)},
+ &CodePointRange{From: rune(12315), To: rune(12315)},
+ &CodePointRange{From: rune(12316), To: rune(12316)},
+ &CodePointRange{From: rune(12317), To: rune(12317)},
+ &CodePointRange{From: rune(12318), To: rune(12319)},
+ &CodePointRange{From: rune(12320), To: rune(12320)},
+ &CodePointRange{From: rune(12336), To: rune(12336)},
+ &CodePointRange{From: rune(12337), To: rune(12341)},
+ &CodePointRange{From: rune(12342), To: rune(12343)},
+ &CodePointRange{From: rune(12348), To: rune(12348)},
+ &CodePointRange{From: rune(12349), To: rune(12349)},
+ &CodePointRange{From: rune(12350), To: rune(12351)},
+ &CodePointRange{From: rune(12443), To: rune(12444)},
+ &CodePointRange{From: rune(12448), To: rune(12448)},
+ &CodePointRange{From: rune(12539), To: rune(12539)},
+ &CodePointRange{From: rune(12540), To: rune(12540)},
+ &CodePointRange{From: rune(12688), To: rune(12689)},
+ &CodePointRange{From: rune(12690), To: rune(12693)},
+ &CodePointRange{From: rune(12694), To: rune(12703)},
+ &CodePointRange{From: rune(12736), To: rune(12771)},
+ &CodePointRange{From: rune(12832), To: rune(12841)},
+ &CodePointRange{From: rune(12842), To: rune(12871)},
+ &CodePointRange{From: rune(12872), To: rune(12879)},
+ &CodePointRange{From: rune(12880), To: rune(12880)},
+ &CodePointRange{From: rune(12881), To: rune(12895)},
+ &CodePointRange{From: rune(12927), To: rune(12927)},
+ &CodePointRange{From: rune(12928), To: rune(12937)},
+ &CodePointRange{From: rune(12938), To: rune(12976)},
+ &CodePointRange{From: rune(12977), To: rune(12991)},
+ &CodePointRange{From: rune(12992), To: rune(13007)},
+ &CodePointRange{From: rune(13055), To: rune(13055)},
+ &CodePointRange{From: rune(13144), To: rune(13311)},
+ &CodePointRange{From: rune(19904), To: rune(19967)},
+ &CodePointRange{From: rune(42752), To: rune(42774)},
+ &CodePointRange{From: rune(42775), To: rune(42783)},
+ &CodePointRange{From: rune(42784), To: rune(42785)},
+ &CodePointRange{From: rune(42888), To: rune(42888)},
+ &CodePointRange{From: rune(42889), To: rune(42890)},
+ &CodePointRange{From: rune(43056), To: rune(43061)},
+ &CodePointRange{From: rune(43062), To: rune(43063)},
+ &CodePointRange{From: rune(43064), To: rune(43064)},
+ &CodePointRange{From: rune(43065), To: rune(43065)},
+ &CodePointRange{From: rune(43310), To: rune(43310)},
+ &CodePointRange{From: rune(43471), To: rune(43471)},
+ &CodePointRange{From: rune(43867), To: rune(43867)},
+ &CodePointRange{From: rune(43882), To: rune(43883)},
+ &CodePointRange{From: rune(64830), To: rune(64830)},
+ &CodePointRange{From: rune(64831), To: rune(64831)},
+ &CodePointRange{From: rune(65040), To: rune(65046)},
+ &CodePointRange{From: rune(65047), To: rune(65047)},
+ &CodePointRange{From: rune(65048), To: rune(65048)},
+ &CodePointRange{From: rune(65049), To: rune(65049)},
+ &CodePointRange{From: rune(65072), To: rune(65072)},
+ &CodePointRange{From: rune(65073), To: rune(65074)},
+ &CodePointRange{From: rune(65075), To: rune(65076)},
+ &CodePointRange{From: rune(65077), To: rune(65077)},
+ &CodePointRange{From: rune(65078), To: rune(65078)},
+ &CodePointRange{From: rune(65079), To: rune(65079)},
+ &CodePointRange{From: rune(65080), To: rune(65080)},
+ &CodePointRange{From: rune(65081), To: rune(65081)},
+ &CodePointRange{From: rune(65082), To: rune(65082)},
+ &CodePointRange{From: rune(65083), To: rune(65083)},
+ &CodePointRange{From: rune(65084), To: rune(65084)},
+ &CodePointRange{From: rune(65085), To: rune(65085)},
+ &CodePointRange{From: rune(65086), To: rune(65086)},
+ &CodePointRange{From: rune(65087), To: rune(65087)},
+ &CodePointRange{From: rune(65088), To: rune(65088)},
+ &CodePointRange{From: rune(65089), To: rune(65089)},
+ &CodePointRange{From: rune(65090), To: rune(65090)},
+ &CodePointRange{From: rune(65091), To: rune(65091)},
+ &CodePointRange{From: rune(65092), To: rune(65092)},
+ &CodePointRange{From: rune(65093), To: rune(65094)},
+ &CodePointRange{From: rune(65095), To: rune(65095)},
+ &CodePointRange{From: rune(65096), To: rune(65096)},
+ &CodePointRange{From: rune(65097), To: rune(65100)},
+ &CodePointRange{From: rune(65101), To: rune(65103)},
+ &CodePointRange{From: rune(65104), To: rune(65106)},
+ &CodePointRange{From: rune(65108), To: rune(65111)},
+ &CodePointRange{From: rune(65112), To: rune(65112)},
+ &CodePointRange{From: rune(65113), To: rune(65113)},
+ &CodePointRange{From: rune(65114), To: rune(65114)},
+ &CodePointRange{From: rune(65115), To: rune(65115)},
+ &CodePointRange{From: rune(65116), To: rune(65116)},
+ &CodePointRange{From: rune(65117), To: rune(65117)},
+ &CodePointRange{From: rune(65118), To: rune(65118)},
+ &CodePointRange{From: rune(65119), To: rune(65121)},
+ &CodePointRange{From: rune(65122), To: rune(65122)},
+ &CodePointRange{From: rune(65123), To: rune(65123)},
+ &CodePointRange{From: rune(65124), To: rune(65126)},
+ &CodePointRange{From: rune(65128), To: rune(65128)},
+ &CodePointRange{From: rune(65129), To: rune(65129)},
+ &CodePointRange{From: rune(65130), To: rune(65131)},
+ &CodePointRange{From: rune(65279), To: rune(65279)},
+ &CodePointRange{From: rune(65281), To: rune(65283)},
+ &CodePointRange{From: rune(65284), To: rune(65284)},
+ &CodePointRange{From: rune(65285), To: rune(65287)},
+ &CodePointRange{From: rune(65288), To: rune(65288)},
+ &CodePointRange{From: rune(65289), To: rune(65289)},
+ &CodePointRange{From: rune(65290), To: rune(65290)},
+ &CodePointRange{From: rune(65291), To: rune(65291)},
+ &CodePointRange{From: rune(65292), To: rune(65292)},
+ &CodePointRange{From: rune(65293), To: rune(65293)},
+ &CodePointRange{From: rune(65294), To: rune(65295)},
+ &CodePointRange{From: rune(65296), To: rune(65305)},
+ &CodePointRange{From: rune(65306), To: rune(65307)},
+ &CodePointRange{From: rune(65308), To: rune(65310)},
+ &CodePointRange{From: rune(65311), To: rune(65312)},
+ &CodePointRange{From: rune(65339), To: rune(65339)},
+ &CodePointRange{From: rune(65340), To: rune(65340)},
+ &CodePointRange{From: rune(65341), To: rune(65341)},
+ &CodePointRange{From: rune(65342), To: rune(65342)},
+ &CodePointRange{From: rune(65343), To: rune(65343)},
+ &CodePointRange{From: rune(65344), To: rune(65344)},
+ &CodePointRange{From: rune(65371), To: rune(65371)},
+ &CodePointRange{From: rune(65372), To: rune(65372)},
+ &CodePointRange{From: rune(65373), To: rune(65373)},
+ &CodePointRange{From: rune(65374), To: rune(65374)},
+ &CodePointRange{From: rune(65375), To: rune(65375)},
+ &CodePointRange{From: rune(65376), To: rune(65376)},
+ &CodePointRange{From: rune(65377), To: rune(65377)},
+ &CodePointRange{From: rune(65378), To: rune(65378)},
+ &CodePointRange{From: rune(65379), To: rune(65379)},
+ &CodePointRange{From: rune(65380), To: rune(65381)},
+ &CodePointRange{From: rune(65392), To: rune(65392)},
+ &CodePointRange{From: rune(65438), To: rune(65439)},
+ &CodePointRange{From: rune(65504), To: rune(65505)},
+ &CodePointRange{From: rune(65506), To: rune(65506)},
+ &CodePointRange{From: rune(65507), To: rune(65507)},
+ &CodePointRange{From: rune(65508), To: rune(65508)},
+ &CodePointRange{From: rune(65509), To: rune(65510)},
+ &CodePointRange{From: rune(65512), To: rune(65512)},
+ &CodePointRange{From: rune(65513), To: rune(65516)},
+ &CodePointRange{From: rune(65517), To: rune(65518)},
+ &CodePointRange{From: rune(65529), To: rune(65531)},
+ &CodePointRange{From: rune(65532), To: rune(65533)},
+ &CodePointRange{From: rune(65792), To: rune(65794)},
+ &CodePointRange{From: rune(65799), To: rune(65843)},
+ &CodePointRange{From: rune(65847), To: rune(65855)},
+ &CodePointRange{From: rune(65936), To: rune(65948)},
+ &CodePointRange{From: rune(66000), To: rune(66044)},
+ &CodePointRange{From: rune(66273), To: rune(66299)},
+ &CodePointRange{From: rune(94178), To: rune(94178)},
+ &CodePointRange{From: rune(94179), To: rune(94179)},
+ &CodePointRange{From: rune(113824), To: rune(113827)},
+ &CodePointRange{From: rune(118784), To: rune(119029)},
+ &CodePointRange{From: rune(119040), To: rune(119078)},
+ &CodePointRange{From: rune(119081), To: rune(119140)},
+ &CodePointRange{From: rune(119141), To: rune(119142)},
+ &CodePointRange{From: rune(119146), To: rune(119148)},
+ &CodePointRange{From: rune(119149), To: rune(119154)},
+ &CodePointRange{From: rune(119155), To: rune(119162)},
+ &CodePointRange{From: rune(119171), To: rune(119172)},
+ &CodePointRange{From: rune(119180), To: rune(119209)},
+ &CodePointRange{From: rune(119214), To: rune(119272)},
+ &CodePointRange{From: rune(119520), To: rune(119539)},
+ &CodePointRange{From: rune(119552), To: rune(119638)},
+ &CodePointRange{From: rune(119648), To: rune(119672)},
+ &CodePointRange{From: rune(119808), To: rune(119892)},
+ &CodePointRange{From: rune(119894), To: rune(119964)},
+ &CodePointRange{From: rune(119966), To: rune(119967)},
+ &CodePointRange{From: rune(119970), To: rune(119970)},
+ &CodePointRange{From: rune(119973), To: rune(119974)},
+ &CodePointRange{From: rune(119977), To: rune(119980)},
+ &CodePointRange{From: rune(119982), To: rune(119993)},
+ &CodePointRange{From: rune(119995), To: rune(119995)},
+ &CodePointRange{From: rune(119997), To: rune(120003)},
+ &CodePointRange{From: rune(120005), To: rune(120069)},
+ &CodePointRange{From: rune(120071), To: rune(120074)},
+ &CodePointRange{From: rune(120077), To: rune(120084)},
+ &CodePointRange{From: rune(120086), To: rune(120092)},
+ &CodePointRange{From: rune(120094), To: rune(120121)},
+ &CodePointRange{From: rune(120123), To: rune(120126)},
+ &CodePointRange{From: rune(120128), To: rune(120132)},
+ &CodePointRange{From: rune(120134), To: rune(120134)},
+ &CodePointRange{From: rune(120138), To: rune(120144)},
+ &CodePointRange{From: rune(120146), To: rune(120485)},
+ &CodePointRange{From: rune(120488), To: rune(120512)},
+ &CodePointRange{From: rune(120513), To: rune(120513)},
+ &CodePointRange{From: rune(120514), To: rune(120538)},
+ &CodePointRange{From: rune(120539), To: rune(120539)},
+ &CodePointRange{From: rune(120540), To: rune(120570)},
+ &CodePointRange{From: rune(120571), To: rune(120571)},
+ &CodePointRange{From: rune(120572), To: rune(120596)},
+ &CodePointRange{From: rune(120597), To: rune(120597)},
+ &CodePointRange{From: rune(120598), To: rune(120628)},
+ &CodePointRange{From: rune(120629), To: rune(120629)},
+ &CodePointRange{From: rune(120630), To: rune(120654)},
+ &CodePointRange{From: rune(120655), To: rune(120655)},
+ &CodePointRange{From: rune(120656), To: rune(120686)},
+ &CodePointRange{From: rune(120687), To: rune(120687)},
+ &CodePointRange{From: rune(120688), To: rune(120712)},
+ &CodePointRange{From: rune(120713), To: rune(120713)},
+ &CodePointRange{From: rune(120714), To: rune(120744)},
+ &CodePointRange{From: rune(120745), To: rune(120745)},
+ &CodePointRange{From: rune(120746), To: rune(120770)},
+ &CodePointRange{From: rune(120771), To: rune(120771)},
+ &CodePointRange{From: rune(120772), To: rune(120779)},
+ &CodePointRange{From: rune(120782), To: rune(120831)},
+ &CodePointRange{From: rune(126065), To: rune(126123)},
+ &CodePointRange{From: rune(126124), To: rune(126124)},
+ &CodePointRange{From: rune(126125), To: rune(126127)},
+ &CodePointRange{From: rune(126128), To: rune(126128)},
+ &CodePointRange{From: rune(126129), To: rune(126132)},
+ &CodePointRange{From: rune(126209), To: rune(126253)},
+ &CodePointRange{From: rune(126254), To: rune(126254)},
+ &CodePointRange{From: rune(126255), To: rune(126269)},
+ &CodePointRange{From: rune(126976), To: rune(127019)},
+ &CodePointRange{From: rune(127024), To: rune(127123)},
+ &CodePointRange{From: rune(127136), To: rune(127150)},
+ &CodePointRange{From: rune(127153), To: rune(127167)},
+ &CodePointRange{From: rune(127169), To: rune(127183)},
+ &CodePointRange{From: rune(127185), To: rune(127221)},
+ &CodePointRange{From: rune(127232), To: rune(127244)},
+ &CodePointRange{From: rune(127245), To: rune(127405)},
+ &CodePointRange{From: rune(127462), To: rune(127487)},
+ &CodePointRange{From: rune(127489), To: rune(127490)},
+ &CodePointRange{From: rune(127504), To: rune(127547)},
+ &CodePointRange{From: rune(127552), To: rune(127560)},
+ &CodePointRange{From: rune(127568), To: rune(127569)},
+ &CodePointRange{From: rune(127584), To: rune(127589)},
+ &CodePointRange{From: rune(127744), To: rune(127994)},
+ &CodePointRange{From: rune(127995), To: rune(127999)},
+ &CodePointRange{From: rune(128000), To: rune(128727)},
+ &CodePointRange{From: rune(128736), To: rune(128748)},
+ &CodePointRange{From: rune(128752), To: rune(128764)},
+ &CodePointRange{From: rune(128768), To: rune(128883)},
+ &CodePointRange{From: rune(128896), To: rune(128984)},
+ &CodePointRange{From: rune(128992), To: rune(129003)},
+ &CodePointRange{From: rune(129024), To: rune(129035)},
+ &CodePointRange{From: rune(129040), To: rune(129095)},
+ &CodePointRange{From: rune(129104), To: rune(129113)},
+ &CodePointRange{From: rune(129120), To: rune(129159)},
+ &CodePointRange{From: rune(129168), To: rune(129197)},
+ &CodePointRange{From: rune(129200), To: rune(129201)},
+ &CodePointRange{From: rune(129280), To: rune(129400)},
+ &CodePointRange{From: rune(129402), To: rune(129483)},
+ &CodePointRange{From: rune(129485), To: rune(129619)},
+ &CodePointRange{From: rune(129632), To: rune(129645)},
+ &CodePointRange{From: rune(129648), To: rune(129652)},
+ &CodePointRange{From: rune(129656), To: rune(129658)},
+ &CodePointRange{From: rune(129664), To: rune(129670)},
+ &CodePointRange{From: rune(129680), To: rune(129704)},
+ &CodePointRange{From: rune(129712), To: rune(129718)},
+ &CodePointRange{From: rune(129728), To: rune(129730)},
+ &CodePointRange{From: rune(129744), To: rune(129750)},
+ &CodePointRange{From: rune(129792), To: rune(129938)},
+ &CodePointRange{From: rune(129940), To: rune(129994)},
+ &CodePointRange{From: rune(130032), To: rune(130041)},
+ &CodePointRange{From: rune(917505), To: rune(917505)},
+ &CodePointRange{From: rune(917536), To: rune(917631)},
+ },
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherAlphabeticCodePoints = []*CodePointRange{
+ &CodePointRange{From: rune(837), To: rune(837)},
+ &CodePointRange{From: rune(1456), To: rune(1469)},
+ &CodePointRange{From: rune(1471), To: rune(1471)},
+ &CodePointRange{From: rune(1473), To: rune(1474)},
+ &CodePointRange{From: rune(1476), To: rune(1477)},
+ &CodePointRange{From: rune(1479), To: rune(1479)},
+ &CodePointRange{From: rune(1552), To: rune(1562)},
+ &CodePointRange{From: rune(1611), To: rune(1623)},
+ &CodePointRange{From: rune(1625), To: rune(1631)},
+ &CodePointRange{From: rune(1648), To: rune(1648)},
+ &CodePointRange{From: rune(1750), To: rune(1756)},
+ &CodePointRange{From: rune(1761), To: rune(1764)},
+ &CodePointRange{From: rune(1767), To: rune(1768)},
+ &CodePointRange{From: rune(1773), To: rune(1773)},
+ &CodePointRange{From: rune(1809), To: rune(1809)},
+ &CodePointRange{From: rune(1840), To: rune(1855)},
+ &CodePointRange{From: rune(1958), To: rune(1968)},
+ &CodePointRange{From: rune(2070), To: rune(2071)},
+ &CodePointRange{From: rune(2075), To: rune(2083)},
+ &CodePointRange{From: rune(2085), To: rune(2087)},
+ &CodePointRange{From: rune(2089), To: rune(2092)},
+ &CodePointRange{From: rune(2260), To: rune(2271)},
+ &CodePointRange{From: rune(2275), To: rune(2281)},
+ &CodePointRange{From: rune(2288), To: rune(2306)},
+ &CodePointRange{From: rune(2307), To: rune(2307)},
+ &CodePointRange{From: rune(2362), To: rune(2362)},
+ &CodePointRange{From: rune(2363), To: rune(2363)},
+ &CodePointRange{From: rune(2366), To: rune(2368)},
+ &CodePointRange{From: rune(2369), To: rune(2376)},
+ &CodePointRange{From: rune(2377), To: rune(2380)},
+ &CodePointRange{From: rune(2382), To: rune(2383)},
+ &CodePointRange{From: rune(2389), To: rune(2391)},
+ &CodePointRange{From: rune(2402), To: rune(2403)},
+ &CodePointRange{From: rune(2433), To: rune(2433)},
+ &CodePointRange{From: rune(2434), To: rune(2435)},
+ &CodePointRange{From: rune(2494), To: rune(2496)},
+ &CodePointRange{From: rune(2497), To: rune(2500)},
+ &CodePointRange{From: rune(2503), To: rune(2504)},
+ &CodePointRange{From: rune(2507), To: rune(2508)},
+ &CodePointRange{From: rune(2519), To: rune(2519)},
+ &CodePointRange{From: rune(2530), To: rune(2531)},
+ &CodePointRange{From: rune(2561), To: rune(2562)},
+ &CodePointRange{From: rune(2563), To: rune(2563)},
+ &CodePointRange{From: rune(2622), To: rune(2624)},
+ &CodePointRange{From: rune(2625), To: rune(2626)},
+ &CodePointRange{From: rune(2631), To: rune(2632)},
+ &CodePointRange{From: rune(2635), To: rune(2636)},
+ &CodePointRange{From: rune(2641), To: rune(2641)},
+ &CodePointRange{From: rune(2672), To: rune(2673)},
+ &CodePointRange{From: rune(2677), To: rune(2677)},
+ &CodePointRange{From: rune(2689), To: rune(2690)},
+ &CodePointRange{From: rune(2691), To: rune(2691)},
+ &CodePointRange{From: rune(2750), To: rune(2752)},
+ &CodePointRange{From: rune(2753), To: rune(2757)},
+ &CodePointRange{From: rune(2759), To: rune(2760)},
+ &CodePointRange{From: rune(2761), To: rune(2761)},
+ &CodePointRange{From: rune(2763), To: rune(2764)},
+ &CodePointRange{From: rune(2786), To: rune(2787)},
+ &CodePointRange{From: rune(2810), To: rune(2812)},
+ &CodePointRange{From: rune(2817), To: rune(2817)},
+ &CodePointRange{From: rune(2818), To: rune(2819)},
+ &CodePointRange{From: rune(2878), To: rune(2878)},
+ &CodePointRange{From: rune(2879), To: rune(2879)},
+ &CodePointRange{From: rune(2880), To: rune(2880)},
+ &CodePointRange{From: rune(2881), To: rune(2884)},
+ &CodePointRange{From: rune(2887), To: rune(2888)},
+ &CodePointRange{From: rune(2891), To: rune(2892)},
+ &CodePointRange{From: rune(2902), To: rune(2902)},
+ &CodePointRange{From: rune(2903), To: rune(2903)},
+ &CodePointRange{From: rune(2914), To: rune(2915)},
+ &CodePointRange{From: rune(2946), To: rune(2946)},
+ &CodePointRange{From: rune(3006), To: rune(3007)},
+ &CodePointRange{From: rune(3008), To: rune(3008)},
+ &CodePointRange{From: rune(3009), To: rune(3010)},
+ &CodePointRange{From: rune(3014), To: rune(3016)},
+ &CodePointRange{From: rune(3018), To: rune(3020)},
+ &CodePointRange{From: rune(3031), To: rune(3031)},
+ &CodePointRange{From: rune(3072), To: rune(3072)},
+ &CodePointRange{From: rune(3073), To: rune(3075)},
+ &CodePointRange{From: rune(3134), To: rune(3136)},
+ &CodePointRange{From: rune(3137), To: rune(3140)},
+ &CodePointRange{From: rune(3142), To: rune(3144)},
+ &CodePointRange{From: rune(3146), To: rune(3148)},
+ &CodePointRange{From: rune(3157), To: rune(3158)},
+ &CodePointRange{From: rune(3170), To: rune(3171)},
+ &CodePointRange{From: rune(3201), To: rune(3201)},
+ &CodePointRange{From: rune(3202), To: rune(3203)},
+ &CodePointRange{From: rune(3262), To: rune(3262)},
+ &CodePointRange{From: rune(3263), To: rune(3263)},
+ &CodePointRange{From: rune(3264), To: rune(3268)},
+ &CodePointRange{From: rune(3270), To: rune(3270)},
+ &CodePointRange{From: rune(3271), To: rune(3272)},
+ &CodePointRange{From: rune(3274), To: rune(3275)},
+ &CodePointRange{From: rune(3276), To: rune(3276)},
+ &CodePointRange{From: rune(3285), To: rune(3286)},
+ &CodePointRange{From: rune(3298), To: rune(3299)},
+ &CodePointRange{From: rune(3328), To: rune(3329)},
+ &CodePointRange{From: rune(3330), To: rune(3331)},
+ &CodePointRange{From: rune(3390), To: rune(3392)},
+ &CodePointRange{From: rune(3393), To: rune(3396)},
+ &CodePointRange{From: rune(3398), To: rune(3400)},
+ &CodePointRange{From: rune(3402), To: rune(3404)},
+ &CodePointRange{From: rune(3415), To: rune(3415)},
+ &CodePointRange{From: rune(3426), To: rune(3427)},
+ &CodePointRange{From: rune(3457), To: rune(3457)},
+ &CodePointRange{From: rune(3458), To: rune(3459)},
+ &CodePointRange{From: rune(3535), To: rune(3537)},
+ &CodePointRange{From: rune(3538), To: rune(3540)},
+ &CodePointRange{From: rune(3542), To: rune(3542)},
+ &CodePointRange{From: rune(3544), To: rune(3551)},
+ &CodePointRange{From: rune(3570), To: rune(3571)},
+ &CodePointRange{From: rune(3633), To: rune(3633)},
+ &CodePointRange{From: rune(3636), To: rune(3642)},
+ &CodePointRange{From: rune(3661), To: rune(3661)},
+ &CodePointRange{From: rune(3761), To: rune(3761)},
+ &CodePointRange{From: rune(3764), To: rune(3769)},
+ &CodePointRange{From: rune(3771), To: rune(3772)},
+ &CodePointRange{From: rune(3789), To: rune(3789)},
+ &CodePointRange{From: rune(3953), To: rune(3966)},
+ &CodePointRange{From: rune(3967), To: rune(3967)},
+ &CodePointRange{From: rune(3968), To: rune(3969)},
+ &CodePointRange{From: rune(3981), To: rune(3991)},
+ &CodePointRange{From: rune(3993), To: rune(4028)},
+ &CodePointRange{From: rune(4139), To: rune(4140)},
+ &CodePointRange{From: rune(4141), To: rune(4144)},
+ &CodePointRange{From: rune(4145), To: rune(4145)},
+ &CodePointRange{From: rune(4146), To: rune(4150)},
+ &CodePointRange{From: rune(4152), To: rune(4152)},
+ &CodePointRange{From: rune(4155), To: rune(4156)},
+ &CodePointRange{From: rune(4157), To: rune(4158)},
+ &CodePointRange{From: rune(4182), To: rune(4183)},
+ &CodePointRange{From: rune(4184), To: rune(4185)},
+ &CodePointRange{From: rune(4190), To: rune(4192)},
+ &CodePointRange{From: rune(4194), To: rune(4196)},
+ &CodePointRange{From: rune(4199), To: rune(4205)},
+ &CodePointRange{From: rune(4209), To: rune(4212)},
+ &CodePointRange{From: rune(4226), To: rune(4226)},
+ &CodePointRange{From: rune(4227), To: rune(4228)},
+ &CodePointRange{From: rune(4229), To: rune(4230)},
+ &CodePointRange{From: rune(4231), To: rune(4236)},
+ &CodePointRange{From: rune(4237), To: rune(4237)},
+ &CodePointRange{From: rune(4239), To: rune(4239)},
+ &CodePointRange{From: rune(4250), To: rune(4252)},
+ &CodePointRange{From: rune(4253), To: rune(4253)},
+ &CodePointRange{From: rune(5906), To: rune(5907)},
+ &CodePointRange{From: rune(5938), To: rune(5939)},
+ &CodePointRange{From: rune(5970), To: rune(5971)},
+ &CodePointRange{From: rune(6002), To: rune(6003)},
+ &CodePointRange{From: rune(6070), To: rune(6070)},
+ &CodePointRange{From: rune(6071), To: rune(6077)},
+ &CodePointRange{From: rune(6078), To: rune(6085)},
+ &CodePointRange{From: rune(6086), To: rune(6086)},
+ &CodePointRange{From: rune(6087), To: rune(6088)},
+ &CodePointRange{From: rune(6277), To: rune(6278)},
+ &CodePointRange{From: rune(6313), To: rune(6313)},
+ &CodePointRange{From: rune(6432), To: rune(6434)},
+ &CodePointRange{From: rune(6435), To: rune(6438)},
+ &CodePointRange{From: rune(6439), To: rune(6440)},
+ &CodePointRange{From: rune(6441), To: rune(6443)},
+ &CodePointRange{From: rune(6448), To: rune(6449)},
+ &CodePointRange{From: rune(6450), To: rune(6450)},
+ &CodePointRange{From: rune(6451), To: rune(6456)},
+ &CodePointRange{From: rune(6679), To: rune(6680)},
+ &CodePointRange{From: rune(6681), To: rune(6682)},
+ &CodePointRange{From: rune(6683), To: rune(6683)},
+ &CodePointRange{From: rune(6741), To: rune(6741)},
+ &CodePointRange{From: rune(6742), To: rune(6742)},
+ &CodePointRange{From: rune(6743), To: rune(6743)},
+ &CodePointRange{From: rune(6744), To: rune(6750)},
+ &CodePointRange{From: rune(6753), To: rune(6753)},
+ &CodePointRange{From: rune(6754), To: rune(6754)},
+ &CodePointRange{From: rune(6755), To: rune(6756)},
+ &CodePointRange{From: rune(6757), To: rune(6764)},
+ &CodePointRange{From: rune(6765), To: rune(6770)},
+ &CodePointRange{From: rune(6771), To: rune(6772)},
+ &CodePointRange{From: rune(6847), To: rune(6848)},
+ &CodePointRange{From: rune(6912), To: rune(6915)},
+ &CodePointRange{From: rune(6916), To: rune(6916)},
+ &CodePointRange{From: rune(6965), To: rune(6965)},
+ &CodePointRange{From: rune(6966), To: rune(6970)},
+ &CodePointRange{From: rune(6971), To: rune(6971)},
+ &CodePointRange{From: rune(6972), To: rune(6972)},
+ &CodePointRange{From: rune(6973), To: rune(6977)},
+ &CodePointRange{From: rune(6978), To: rune(6978)},
+ &CodePointRange{From: rune(6979), To: rune(6979)},
+ &CodePointRange{From: rune(7040), To: rune(7041)},
+ &CodePointRange{From: rune(7042), To: rune(7042)},
+ &CodePointRange{From: rune(7073), To: rune(7073)},
+ &CodePointRange{From: rune(7074), To: rune(7077)},
+ &CodePointRange{From: rune(7078), To: rune(7079)},
+ &CodePointRange{From: rune(7080), To: rune(7081)},
+ &CodePointRange{From: rune(7084), To: rune(7085)},
+ &CodePointRange{From: rune(7143), To: rune(7143)},
+ &CodePointRange{From: rune(7144), To: rune(7145)},
+ &CodePointRange{From: rune(7146), To: rune(7148)},
+ &CodePointRange{From: rune(7149), To: rune(7149)},
+ &CodePointRange{From: rune(7150), To: rune(7150)},
+ &CodePointRange{From: rune(7151), To: rune(7153)},
+ &CodePointRange{From: rune(7204), To: rune(7211)},
+ &CodePointRange{From: rune(7212), To: rune(7219)},
+ &CodePointRange{From: rune(7220), To: rune(7221)},
+ &CodePointRange{From: rune(7222), To: rune(7222)},
+ &CodePointRange{From: rune(7655), To: rune(7668)},
+ &CodePointRange{From: rune(9398), To: rune(9449)},
+ &CodePointRange{From: rune(11744), To: rune(11775)},
+ &CodePointRange{From: rune(42612), To: rune(42619)},
+ &CodePointRange{From: rune(42654), To: rune(42655)},
+ &CodePointRange{From: rune(43010), To: rune(43010)},
+ &CodePointRange{From: rune(43019), To: rune(43019)},
+ &CodePointRange{From: rune(43043), To: rune(43044)},
+ &CodePointRange{From: rune(43045), To: rune(43046)},
+ &CodePointRange{From: rune(43047), To: rune(43047)},
+ &CodePointRange{From: rune(43136), To: rune(43137)},
+ &CodePointRange{From: rune(43188), To: rune(43203)},
+ &CodePointRange{From: rune(43205), To: rune(43205)},
+ &CodePointRange{From: rune(43263), To: rune(43263)},
+ &CodePointRange{From: rune(43302), To: rune(43306)},
+ &CodePointRange{From: rune(43335), To: rune(43345)},
+ &CodePointRange{From: rune(43346), To: rune(43346)},
+ &CodePointRange{From: rune(43392), To: rune(43394)},
+ &CodePointRange{From: rune(43395), To: rune(43395)},
+ &CodePointRange{From: rune(43444), To: rune(43445)},
+ &CodePointRange{From: rune(43446), To: rune(43449)},
+ &CodePointRange{From: rune(43450), To: rune(43451)},
+ &CodePointRange{From: rune(43452), To: rune(43453)},
+ &CodePointRange{From: rune(43454), To: rune(43455)},
+ &CodePointRange{From: rune(43493), To: rune(43493)},
+ &CodePointRange{From: rune(43561), To: rune(43566)},
+ &CodePointRange{From: rune(43567), To: rune(43568)},
+ &CodePointRange{From: rune(43569), To: rune(43570)},
+ &CodePointRange{From: rune(43571), To: rune(43572)},
+ &CodePointRange{From: rune(43573), To: rune(43574)},
+ &CodePointRange{From: rune(43587), To: rune(43587)},
+ &CodePointRange{From: rune(43596), To: rune(43596)},
+ &CodePointRange{From: rune(43597), To: rune(43597)},
+ &CodePointRange{From: rune(43643), To: rune(43643)},
+ &CodePointRange{From: rune(43644), To: rune(43644)},
+ &CodePointRange{From: rune(43645), To: rune(43645)},
+ &CodePointRange{From: rune(43696), To: rune(43696)},
+ &CodePointRange{From: rune(43698), To: rune(43700)},
+ &CodePointRange{From: rune(43703), To: rune(43704)},
+ &CodePointRange{From: rune(43710), To: rune(43710)},
+ &CodePointRange{From: rune(43755), To: rune(43755)},
+ &CodePointRange{From: rune(43756), To: rune(43757)},
+ &CodePointRange{From: rune(43758), To: rune(43759)},
+ &CodePointRange{From: rune(43765), To: rune(43765)},
+ &CodePointRange{From: rune(44003), To: rune(44004)},
+ &CodePointRange{From: rune(44005), To: rune(44005)},
+ &CodePointRange{From: rune(44006), To: rune(44007)},
+ &CodePointRange{From: rune(44008), To: rune(44008)},
+ &CodePointRange{From: rune(44009), To: rune(44010)},
+ &CodePointRange{From: rune(64286), To: rune(64286)},
+ &CodePointRange{From: rune(66422), To: rune(66426)},
+ &CodePointRange{From: rune(68097), To: rune(68099)},
+ &CodePointRange{From: rune(68101), To: rune(68102)},
+ &CodePointRange{From: rune(68108), To: rune(68111)},
+ &CodePointRange{From: rune(68900), To: rune(68903)},
+ &CodePointRange{From: rune(69291), To: rune(69292)},
+ &CodePointRange{From: rune(69632), To: rune(69632)},
+ &CodePointRange{From: rune(69633), To: rune(69633)},
+ &CodePointRange{From: rune(69634), To: rune(69634)},
+ &CodePointRange{From: rune(69688), To: rune(69701)},
+ &CodePointRange{From: rune(69762), To: rune(69762)},
+ &CodePointRange{From: rune(69808), To: rune(69810)},
+ &CodePointRange{From: rune(69811), To: rune(69814)},
+ &CodePointRange{From: rune(69815), To: rune(69816)},
+ &CodePointRange{From: rune(69888), To: rune(69890)},
+ &CodePointRange{From: rune(69927), To: rune(69931)},
+ &CodePointRange{From: rune(69932), To: rune(69932)},
+ &CodePointRange{From: rune(69933), To: rune(69938)},
+ &CodePointRange{From: rune(69957), To: rune(69958)},
+ &CodePointRange{From: rune(70016), To: rune(70017)},
+ &CodePointRange{From: rune(70018), To: rune(70018)},
+ &CodePointRange{From: rune(70067), To: rune(70069)},
+ &CodePointRange{From: rune(70070), To: rune(70078)},
+ &CodePointRange{From: rune(70079), To: rune(70079)},
+ &CodePointRange{From: rune(70094), To: rune(70094)},
+ &CodePointRange{From: rune(70095), To: rune(70095)},
+ &CodePointRange{From: rune(70188), To: rune(70190)},
+ &CodePointRange{From: rune(70191), To: rune(70193)},
+ &CodePointRange{From: rune(70194), To: rune(70195)},
+ &CodePointRange{From: rune(70196), To: rune(70196)},
+ &CodePointRange{From: rune(70199), To: rune(70199)},
+ &CodePointRange{From: rune(70206), To: rune(70206)},
+ &CodePointRange{From: rune(70367), To: rune(70367)},
+ &CodePointRange{From: rune(70368), To: rune(70370)},
+ &CodePointRange{From: rune(70371), To: rune(70376)},
+ &CodePointRange{From: rune(70400), To: rune(70401)},
+ &CodePointRange{From: rune(70402), To: rune(70403)},
+ &CodePointRange{From: rune(70462), To: rune(70463)},
+ &CodePointRange{From: rune(70464), To: rune(70464)},
+ &CodePointRange{From: rune(70465), To: rune(70468)},
+ &CodePointRange{From: rune(70471), To: rune(70472)},
+ &CodePointRange{From: rune(70475), To: rune(70476)},
+ &CodePointRange{From: rune(70487), To: rune(70487)},
+ &CodePointRange{From: rune(70498), To: rune(70499)},
+ &CodePointRange{From: rune(70709), To: rune(70711)},
+ &CodePointRange{From: rune(70712), To: rune(70719)},
+ &CodePointRange{From: rune(70720), To: rune(70721)},
+ &CodePointRange{From: rune(70723), To: rune(70724)},
+ &CodePointRange{From: rune(70725), To: rune(70725)},
+ &CodePointRange{From: rune(70832), To: rune(70834)},
+ &CodePointRange{From: rune(70835), To: rune(70840)},
+ &CodePointRange{From: rune(70841), To: rune(70841)},
+ &CodePointRange{From: rune(70842), To: rune(70842)},
+ &CodePointRange{From: rune(70843), To: rune(70846)},
+ &CodePointRange{From: rune(70847), To: rune(70848)},
+ &CodePointRange{From: rune(70849), To: rune(70849)},
+ &CodePointRange{From: rune(71087), To: rune(71089)},
+ &CodePointRange{From: rune(71090), To: rune(71093)},
+ &CodePointRange{From: rune(71096), To: rune(71099)},
+ &CodePointRange{From: rune(71100), To: rune(71101)},
+ &CodePointRange{From: rune(71102), To: rune(71102)},
+ &CodePointRange{From: rune(71132), To: rune(71133)},
+ &CodePointRange{From: rune(71216), To: rune(71218)},
+ &CodePointRange{From: rune(71219), To: rune(71226)},
+ &CodePointRange{From: rune(71227), To: rune(71228)},
+ &CodePointRange{From: rune(71229), To: rune(71229)},
+ &CodePointRange{From: rune(71230), To: rune(71230)},
+ &CodePointRange{From: rune(71232), To: rune(71232)},
+ &CodePointRange{From: rune(71339), To: rune(71339)},
+ &CodePointRange{From: rune(71340), To: rune(71340)},
+ &CodePointRange{From: rune(71341), To: rune(71341)},
+ &CodePointRange{From: rune(71342), To: rune(71343)},
+ &CodePointRange{From: rune(71344), To: rune(71349)},
+ &CodePointRange{From: rune(71453), To: rune(71455)},
+ &CodePointRange{From: rune(71456), To: rune(71457)},
+ &CodePointRange{From: rune(71458), To: rune(71461)},
+ &CodePointRange{From: rune(71462), To: rune(71462)},
+ &CodePointRange{From: rune(71463), To: rune(71466)},
+ &CodePointRange{From: rune(71724), To: rune(71726)},
+ &CodePointRange{From: rune(71727), To: rune(71735)},
+ &CodePointRange{From: rune(71736), To: rune(71736)},
+ &CodePointRange{From: rune(71984), To: rune(71989)},
+ &CodePointRange{From: rune(71991), To: rune(71992)},
+ &CodePointRange{From: rune(71995), To: rune(71996)},
+ &CodePointRange{From: rune(72000), To: rune(72000)},
+ &CodePointRange{From: rune(72002), To: rune(72002)},
+ &CodePointRange{From: rune(72145), To: rune(72147)},
+ &CodePointRange{From: rune(72148), To: rune(72151)},
+ &CodePointRange{From: rune(72154), To: rune(72155)},
+ &CodePointRange{From: rune(72156), To: rune(72159)},
+ &CodePointRange{From: rune(72164), To: rune(72164)},
+ &CodePointRange{From: rune(72193), To: rune(72202)},
+ &CodePointRange{From: rune(72245), To: rune(72248)},
+ &CodePointRange{From: rune(72249), To: rune(72249)},
+ &CodePointRange{From: rune(72251), To: rune(72254)},
+ &CodePointRange{From: rune(72273), To: rune(72278)},
+ &CodePointRange{From: rune(72279), To: rune(72280)},
+ &CodePointRange{From: rune(72281), To: rune(72283)},
+ &CodePointRange{From: rune(72330), To: rune(72342)},
+ &CodePointRange{From: rune(72343), To: rune(72343)},
+ &CodePointRange{From: rune(72751), To: rune(72751)},
+ &CodePointRange{From: rune(72752), To: rune(72758)},
+ &CodePointRange{From: rune(72760), To: rune(72765)},
+ &CodePointRange{From: rune(72766), To: rune(72766)},
+ &CodePointRange{From: rune(72850), To: rune(72871)},
+ &CodePointRange{From: rune(72873), To: rune(72873)},
+ &CodePointRange{From: rune(72874), To: rune(72880)},
+ &CodePointRange{From: rune(72881), To: rune(72881)},
+ &CodePointRange{From: rune(72882), To: rune(72883)},
+ &CodePointRange{From: rune(72884), To: rune(72884)},
+ &CodePointRange{From: rune(72885), To: rune(72886)},
+ &CodePointRange{From: rune(73009), To: rune(73014)},
+ &CodePointRange{From: rune(73018), To: rune(73018)},
+ &CodePointRange{From: rune(73020), To: rune(73021)},
+ &CodePointRange{From: rune(73023), To: rune(73025)},
+ &CodePointRange{From: rune(73027), To: rune(73027)},
+ &CodePointRange{From: rune(73031), To: rune(73031)},
+ &CodePointRange{From: rune(73098), To: rune(73102)},
+ &CodePointRange{From: rune(73104), To: rune(73105)},
+ &CodePointRange{From: rune(73107), To: rune(73108)},
+ &CodePointRange{From: rune(73109), To: rune(73109)},
+ &CodePointRange{From: rune(73110), To: rune(73110)},
+ &CodePointRange{From: rune(73459), To: rune(73460)},
+ &CodePointRange{From: rune(73461), To: rune(73462)},
+ &CodePointRange{From: rune(94031), To: rune(94031)},
+ &CodePointRange{From: rune(94033), To: rune(94087)},
+ &CodePointRange{From: rune(94095), To: rune(94098)},
+ &CodePointRange{From: rune(94192), To: rune(94193)},
+ &CodePointRange{From: rune(113822), To: rune(113822)},
+ &CodePointRange{From: rune(122880), To: rune(122886)},
+ &CodePointRange{From: rune(122888), To: rune(122904)},
+ &CodePointRange{From: rune(122907), To: rune(122913)},
+ &CodePointRange{From: rune(122915), To: rune(122916)},
+ &CodePointRange{From: rune(122918), To: rune(122922)},
+ &CodePointRange{From: rune(125255), To: rune(125255)},
+ &CodePointRange{From: rune(127280), To: rune(127305)},
+ &CodePointRange{From: rune(127312), To: rune(127337)},
+ &CodePointRange{From: rune(127344), To: rune(127369)},
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherLowercaseCodePoints = []*CodePointRange{
+ &CodePointRange{From: rune(170), To: rune(170)},
+ &CodePointRange{From: rune(186), To: rune(186)},
+ &CodePointRange{From: rune(688), To: rune(696)},
+ &CodePointRange{From: rune(704), To: rune(705)},
+ &CodePointRange{From: rune(736), To: rune(740)},
+ &CodePointRange{From: rune(837), To: rune(837)},
+ &CodePointRange{From: rune(890), To: rune(890)},
+ &CodePointRange{From: rune(7468), To: rune(7530)},
+ &CodePointRange{From: rune(7544), To: rune(7544)},
+ &CodePointRange{From: rune(7579), To: rune(7615)},
+ &CodePointRange{From: rune(8305), To: rune(8305)},
+ &CodePointRange{From: rune(8319), To: rune(8319)},
+ &CodePointRange{From: rune(8336), To: rune(8348)},
+ &CodePointRange{From: rune(8560), To: rune(8575)},
+ &CodePointRange{From: rune(9424), To: rune(9449)},
+ &CodePointRange{From: rune(11388), To: rune(11389)},
+ &CodePointRange{From: rune(42652), To: rune(42653)},
+ &CodePointRange{From: rune(42864), To: rune(42864)},
+ &CodePointRange{From: rune(43000), To: rune(43001)},
+ &CodePointRange{From: rune(43868), To: rune(43871)},
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherUppercaseCodePoints = []*CodePointRange{
+ &CodePointRange{From: rune(8544), To: rune(8559)},
+ &CodePointRange{From: rune(9398), To: rune(9423)},
+ &CodePointRange{From: rune(127280), To: rune(127305)},
+ &CodePointRange{From: rune(127312), To: rune(127337)},
+ &CodePointRange{From: rune(127344), To: rune(127369)},
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var whiteSpaceCodePoints = []*CodePointRange{
+ &CodePointRange{From: rune(9), To: rune(13)},
+ &CodePointRange{From: rune(32), To: rune(32)},
+ &CodePointRange{From: rune(133), To: rune(133)},
+ &CodePointRange{From: rune(160), To: rune(160)},
+ &CodePointRange{From: rune(5760), To: rune(5760)},
+ &CodePointRange{From: rune(8192), To: rune(8202)},
+ &CodePointRange{From: rune(8232), To: rune(8232)},
+ &CodePointRange{From: rune(8233), To: rune(8233)},
+ &CodePointRange{From: rune(8239), To: rune(8239)},
+ &CodePointRange{From: rune(8287), To: rune(8287)},
+ &CodePointRange{From: rune(12288), To: rune(12288)},
+}
diff --git a/src/urubu/ucd/codepoint.go.tmpl b/src/urubu/ucd/codepoint.go.tmpl
new file mode 100644
index 0000000..cc0d48e
--- /dev/null
+++ b/src/urubu/ucd/codepoint.go.tmpl
@@ -0,0 +1,65 @@
+// Code generated by {{ .GeneratorName }}; DO NOT EDIT.
+
+package ucd
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var generalCategoryValueAbbs = map[string]string{ {{ range $long, $abb := .PropertyValueAliases.GeneralCategory }}
+ "{{ $long }}": "{{ $abb }}",{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var scriptValueAbbs = map[string]string{ {{ range $long, $abb := .PropertyValueAliases.Script }}
+ "{{ $long }}": "{{ $abb }}",{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyValueAliases.txt
+var (
+ generalCategoryDefaultRange = &CodePointRange{
+ From: rune({{ .PropertyValueAliases.GeneralCategoryDefaultRange.From }}),
+ To: rune({{ .PropertyValueAliases.GeneralCategoryDefaultRange.To }}),
+ }
+ generalCategoryDefaultValue = "{{ .PropertyValueAliases.GeneralCategoryDefaultValue }}"
+)
+
+// https://www.unicode.org/Public/13.0.0/ucd/UnicodeData.txt
+var generalCategoryCodePoints = map[string][]*CodePointRange{ {{ range $propName, $codePoints := .UnicodeData.GeneralCategory }}
+ "{{ $propName }}": { {{ range $codePoints }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+ },{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/Scripts.txt
+var (
+ scriptDefaultRange = &CodePointRange{
+ From: rune({{ .Scripts.ScriptDefaultRange.From }}),
+ To: rune({{ .Scripts.ScriptDefaultRange.To }}),
+ }
+ scriptDefaultValue = "{{ .Scripts.ScriptDefaultValue }}"
+)
+
+// https://www.unicode.org/Public/13.0.0/ucd/Scripts.txt
+var scriptCodepoints = map[string][]*CodePointRange{ {{ range $script, $codePoints := .Scripts.Script }}
+ "{{ $script }}": { {{ range $codePoints }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+ },{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherAlphabeticCodePoints = []*CodePointRange{ {{ range .PropList.OtherAlphabetic }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherLowercaseCodePoints = []*CodePointRange{ {{ range .PropList.OtherLowercase }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var otherUppercaseCodePoints = []*CodePointRange{ {{ range .PropList.OtherUppercase }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropList.txt
+var whiteSpaceCodePoints = []*CodePointRange{ {{ range .PropList.WhiteSpace }}
+ &CodePointRange{From: rune({{ .From }}), To: rune({{ .To }})},{{ end }}
+}
diff --git a/src/urubu/ucd/parser.go b/src/urubu/ucd/parser.go
new file mode 100644
index 0000000..88d7134
--- /dev/null
+++ b/src/urubu/ucd/parser.go
@@ -0,0 +1,155 @@
+package ucd
+
+import (
+ "bufio"
+ "encoding/binary"
+ "encoding/hex"
+ "io"
+ "regexp"
+ "strings"
+)
+
+type CodePointRange struct {
+ From rune
+ To rune
+}
+
+var codePointRangeNil = &CodePointRange{
+ From: 0,
+ To: 0,
+}
+
+type field string
+
+func (f field) codePointRange() (*CodePointRange, error) {
+ var from, to rune
+ var err error
+ cp := reCodePointRange.FindStringSubmatch(string(f))
+ from, err = decodeHexToRune(cp[1])
+ if err != nil {
+ return codePointRangeNil, err
+ }
+ if cp[2] != "" {
+ to, err = decodeHexToRune(cp[2])
+ if err != nil {
+ return codePointRangeNil, err
+ }
+ } else {
+ to = from
+ }
+ return &CodePointRange{
+ From: from,
+ To: to,
+ }, nil
+}
+
+func decodeHexToRune(hexCodePoint string) (rune, error) {
+ h := hexCodePoint
+ if len(h)%2 != 0 {
+ h = "0" + h
+ }
+ b, err := hex.DecodeString(h)
+ if err != nil {
+ return 0, err
+ }
+ l := len(b)
+ for i := 0; i < 4-l; i++ {
+ b = append([]byte{0}, b...)
+ }
+ n := binary.BigEndian.Uint32(b)
+ return rune(n), nil
+}
+
+func (f field) symbol() string {
+ return string(f)
+}
+
+func (f field) normalizedSymbol() string {
+ return normalizeSymbolicValue(string(f))
+}
+
+var symValReplacer = strings.NewReplacer("_", "", "-", "", "\x20", "")
+
+// normalizeSymbolicValue normalizes a symbolic value. The normalized value meets UAX44-LM3.
+//
+// https://www.unicode.org/reports/tr44/#UAX44-LM3
+func normalizeSymbolicValue(s string) string {
+ v := strings.ToLower(symValReplacer.Replace(s))
+ if strings.HasPrefix(v, "is") && v != "is" {
+ return v[2:]
+ }
+ return v
+}
+
+var (
+ reLine = regexp.MustCompile(`^\s*(.*?)\s*(#.*)?$`)
+ reCodePointRange = regexp.MustCompile(`^([[:xdigit:]]+)(?:..([[:xdigit:]]+))?$`)
+
+ specialCommentPrefix = "# @missing:"
+)
+
+// This parser can parse data files of Unicode Character Database (UCD).
+// Specifically, it has the following two functions:
+// - Converts each line of the data files into a slice of fields.
+// - Recognizes specially-formatted comments starting `@missing` and generates a slice of fields.
+//
+// However, for practical purposes, each field needs to be analyzed more specifically.
+// For instance, in UnicodeData.txt, the first field represents a range of code points,
+// so it needs to be recognized as a hexadecimal string.
+// You can perform more specific parsing for each file by implementing a dedicated parser that wraps this parser.
+//
+// https://www.unicode.org/reports/tr44/#Format_Conventions
+type parser struct {
+ scanner *bufio.Scanner
+ fields []field
+ defaultFields []field
+ err error
+
+ fieldBuf []field
+ defaultFieldBuf []field
+}
+
+func newParser(r io.Reader) *parser {
+ return &parser{
+ scanner: bufio.NewScanner(r),
+ fieldBuf: make([]field, 50),
+ defaultFieldBuf: make([]field, 50),
+ }
+}
+
+func (p *parser) parse() bool {
+ for p.scanner.Scan() {
+ p.parseRecord(p.scanner.Text())
+ if p.fields != nil || p.defaultFields != nil {
+ return true
+ }
+ }
+ p.err = p.scanner.Err()
+ return false
+}
+
+func (p *parser) parseRecord(src string) {
+ ms := reLine.FindStringSubmatch(src)
+ mFields := ms[1]
+ mComment := ms[2]
+ if mFields != "" {
+ p.fields = parseFields(p.fieldBuf, mFields)
+ } else {
+ p.fields = nil
+ }
+ if strings.HasPrefix(mComment, specialCommentPrefix) {
+ p.defaultFields = parseFields(p.defaultFieldBuf, strings.Replace(mComment, specialCommentPrefix, "", -1))
+ } else {
+ p.defaultFields = nil
+ }
+}
+
+func parseFields(buf []field, src string) []field {
+ n := 0
+ for _, f := range strings.Split(src, ";") {
+ buf[n] = field(strings.TrimSpace(f))
+ n++
+ }
+
+ return buf[:n]
+}
diff --git a/src/urubu/ucd/prop_list.go b/src/urubu/ucd/prop_list.go
new file mode 100644
index 0000000..31db70c
--- /dev/null
+++ b/src/urubu/ucd/prop_list.go
@@ -0,0 +1,50 @@
+package ucd
+
+import "io"
+
+type PropList struct {
+ OtherAlphabetic []*CodePointRange
+ OtherLowercase []*CodePointRange
+ OtherUppercase []*CodePointRange
+ WhiteSpace []*CodePointRange
+}
+
+// ParsePropList parses the PropList.txt.
+func ParsePropList(r io.Reader) (*PropList, error) {
+ var oa []*CodePointRange
+ var ol []*CodePointRange
+ var ou []*CodePointRange
+ var ws []*CodePointRange
+ p := newParser(r)
+ for p.parse() {
+ if len(p.fields) == 0 {
+ continue
+ }
+
+ cp, err := p.fields[0].codePointRange()
+ if err != nil {
+ return nil, err
+ }
+
+ switch p.fields[1].symbol() {
+ case "Other_Alphabetic":
+ oa = append(oa, cp)
+ case "Other_Lowercase":
+ ol = append(ol, cp)
+ case "Other_Uppercase":
+ ou = append(ou, cp)
+ case "White_Space":
+ ws = append(ws, cp)
+ }
+ }
+ if p.err != nil {
+ return nil, p.err
+ }
+
+ return &PropList{
+ OtherAlphabetic: oa,
+ OtherLowercase: ol,
+ OtherUppercase: ou,
+ WhiteSpace: ws,
+ }, nil
+}
diff --git a/src/urubu/ucd/property.go b/src/urubu/ucd/property.go
new file mode 100644
index 0000000..ba60e80
--- /dev/null
+++ b/src/urubu/ucd/property.go
@@ -0,0 +1,95 @@
+package ucd
+
+// contributoryProperties is a set of contributory properties vartan uses internally.
+// Property statuses are defined in the following table.
+//
+// https://unicode.org/reports/tr44/#Property_List_Table
+var contributoryProperties = []string{
+ "oalpha",
+ "olower",
+ "oupper",
+}
+
+func ContributoryProperties() []string {
+ return contributoryProperties
+}
+
+// https://www.unicode.org/reports/tr44/#GC_Values_Table
+var compositGeneralCategories = map[string][]string{
+ // Cased_Letter
+ "lc": {"lu", "ll", "lt"},
+ // Letter
+ "l": {"lu", "ll", "lt", "lm", "lo"},
+ // Mark
+ "m": {"mm", "mc", "me"},
+ // Number
+ "n": {"nd", "nl", "no"},
+ // Punctuation
+ "p": {"pc", "pd", "ps", "pi", "pe", "pf", "po"},
+ // Symbol
+ "s": {"sm", "sc", "sk", "so"},
+ // Separator
+ "z": {"zs", "zl", "zp"},
+ // Other
+ "c": {"cc", "cf", "cs", "co", "cn"},
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txt
+var derivedCoreProperties = map[string][]string{
+ // Alphabetic
+ "alpha": {
+ `\p{Lowercase=yes}`,
+ `\p{Uppercase=yes}`,
+ `\p{Lt}`,
+ `\p{Lm}`,
+ `\p{Lo}`,
+ `\p{Nl}`,
+ `\p{Other_Alphabetic=yes}`,
+ },
+ // Lowercase
+ "lower": {
+ `\p{Ll}`,
+ `\p{Other_Lowercase=yes}`,
+ },
+ // Uppercase
+ "upper": {
+ `\p{Lu}`,
+ `\p{Other_Uppercase=yes}`,
+ },
+}
+
+// https://www.unicode.org/Public/13.0.0/ucd/PropertyAliases.txt
+var propertyNameAbbs = map[string]string{
+ "generalcategory": "gc",
+ "gc": "gc",
+ "script": "sc",
+ "sc": "sc",
+ "alphabetic": "alpha",
+ "alpha": "alpha",
+ "otheralphabetic": "oalpha",
+ "oalpha": "oalpha",
+ "lowercase": "lower",
+ "lower": "lower",
+ "uppercase": "upper",
+ "upper": "upper",
+ "otherlowercase": "olower",
+ "olower": "olower",
+ "otheruppercase": "oupper",
+ "oupper": "oupper",
+ "whitespace": "wspace",
+ "wspace": "wspace",
+ "space": "wspace",
+}
+
+// https://www.unicode.org/reports/tr44/#Type_Key_Table
+// https://www.unicode.org/reports/tr44/#Binary_Values_Table
+var binaryValues = map[string]bool{
+ "yes": true,
+ "y": true,
+ "true": true,
+ "t": true,
+ "no": false,
+ "n": false,
+ "false": false,
+ "f": false,
+}
diff --git a/src/urubu/ucd/property_value_aliases.go b/src/urubu/ucd/property_value_aliases.go
new file mode 100644
index 0000000..4bc69db
--- /dev/null
+++ b/src/urubu/ucd/property_value_aliases.go
@@ -0,0 +1,82 @@
+package ucd
+
+import "io"
+
+type PropertyValueAliases struct {
+ GeneralCategory map[string]string
+ GeneralCategoryDefaultRange *CodePointRange
+ GeneralCategoryDefaultValue string
+
+ Script map[string]string
+}
+
+// ParsePropertyValueAliases parses the PropertyValueAliases.txt.
+func ParsePropertyValueAliases(r io.Reader) (*PropertyValueAliases, error) {
+ gcAbbs := map[string]string{}
+ var defaultGCCPRange *CodePointRange
+ var defaultGCVal string
+ scAbbs := map[string]string{}
+ p := newParser(r)
+ for p.parse() {
+ // https://www.unicode.org/reports/tr44/#Property_Value_Aliases
+ // > In PropertyValueAliases.txt, the first field contains the abbreviated alias for a Unicode property,
+ // > the second field specifies an abbreviated symbolic name for a value of that property, and the third
+ // > field specifies the long symbolic name for that value of that property. These are the preferred
+ // > aliases. Additional aliases for some property values may be specified in the fourth or subsequent
+ // > fields.
+ if len(p.fields) > 0 {
+ switch p.fields[0].symbol() {
+ case "gc":
+ gcShort := p.fields[1].normalizedSymbol()
+ gcLong := p.fields[2].normalizedSymbol()
+ gcAbbs[gcShort] = gcShort
+ gcAbbs[gcLong] = gcShort
+ for _, f := range p.fields[3:] {
+ gcShortOther := f.normalizedSymbol()
+ gcAbbs[gcShortOther] = gcShort
+ }
+ case "sc":
+ scShort := p.fields[1].normalizedSymbol()
+ scLong := p.fields[2].normalizedSymbol()
+ scAbbs[scShort] = scShort
+ scAbbs[scLong] = scShort
+ for _, f := range p.fields[3:] {
+ scShortOther := f.normalizedSymbol()
+ scAbbs[scShortOther] = scShort
+ }
+ }
+ }
+
+ // https://www.unicode.org/reports/tr44/#Missing_Conventions
+ // > @missing lines are also supplied for many properties in the file PropertyValueAliases.txt.
+ // > ...
+ // > there are currently two syntactic patterns used for @missing lines, as summarized schematically below:
+ // > 1. code_point_range; default_prop_val
+ // > 2. code_point_range; property_name; default_prop_val
+ // > ...
+ // > Pattern #2 is used in PropertyValueAliases.txt and in DerivedNormalizationProps.txt, both of which
+ // > contain values associated with many properties. For example:
+ // > # @missing: 0000..10FFFF; NFD_QC; Yes
+ if len(p.defaultFields) > 0 && p.defaultFields[1].symbol() == "General_Category" {
+ var err error
+ defaultGCCPRange, err = p.defaultFields[0].codePointRange()
+ if err != nil {
+ return nil, err
+ }
+ defaultGCVal = p.defaultFields[2].normalizedSymbol()
+ }
+ }
+ if p.err != nil {
+ return nil, p.err
+ }
+ return &PropertyValueAliases{
+ GeneralCategory: gcAbbs,
+ GeneralCategoryDefaultRange: defaultGCCPRange,
+ GeneralCategoryDefaultValue: defaultGCVal,
+ Script: scAbbs,
+ }, nil
+}
+
+func (a *PropertyValueAliases) gcAbb(gc string) string {
+ return a.GeneralCategory[gc]
+}
diff --git a/src/urubu/ucd/scripts.go b/src/urubu/ucd/scripts.go
new file mode 100644
index 0000000..5040283
--- /dev/null
+++ b/src/urubu/ucd/scripts.go
@@ -0,0 +1,52 @@
+package ucd
+
+import (
+ "fmt"
+ "io"
+)
+
+type Scripts struct {
+ Script map[string][]*CodePointRange
+ ScriptDefaultRange *CodePointRange
+ ScriptDefaultValue string
+}
+
+// ParseScripts parses the Scripts.txt.
+func ParseScripts(r io.Reader, propValAliases *PropertyValueAliases) (*Scripts, error) {
+ ss := map[string][]*CodePointRange{}
+ var defaultRange *CodePointRange
+ var defaultValue string
+ p := newParser(r)
+ for p.parse() {
+ if len(p.fields) > 0 {
+ cp, err := p.fields[0].codePointRange()
+ if err != nil {
+ return nil, err
+ }
+
+ name, ok := propValAliases.Script[p.fields[1].normalizedSymbol()]
+ if !ok {
+ return nil, fmt.Errorf("unknown property: %v", p.fields[1].symbol())
+ }
+ ss[name] = append(ss[name], cp)
+ }
+
+ if len(p.defaultFields) > 0 {
+ var err error
+ defaultRange, err = p.defaultFields[0].codePointRange()
+ if err != nil {
+ return nil, err
+ }
+ defaultValue = p.defaultFields[1].normalizedSymbol()
+ }
+ }
+ if p.err != nil {
+ return nil, p.err
+ }
+
+ return &Scripts{
+ Script: ss,
+ ScriptDefaultRange: defaultRange,
+ ScriptDefaultValue: defaultValue,
+ }, nil
+}
diff --git a/src/urubu/ucd/unicode_data.go b/src/urubu/ucd/unicode_data.go
new file mode 100644
index 0000000..e2a8e87
--- /dev/null
+++ b/src/urubu/ucd/unicode_data.go
@@ -0,0 +1,56 @@
+package ucd
+
+import "io"
+
+type UnicodeData struct {
+ GeneralCategory map[string][]*CodePointRange
+
+ propValAliases *PropertyValueAliases
+}
+
+// ParseUnicodeData parses the UnicodeData.txt.
+func ParseUnicodeData(r io.Reader, propValAliases *PropertyValueAliases) (*UnicodeData, error) {
+ unicodeData := &UnicodeData{
+ GeneralCategory: map[string][]*CodePointRange{},
+ propValAliases: propValAliases,
+ }
+
+ p := newParser(r)
+ for p.parse() {
+ if len(p.fields) == 0 {
+ continue
+ }
+ cp, err := p.fields[0].codePointRange()
+ if err != nil {
+ return nil, err
+ }
+ gc := p.fields[2].normalizedSymbol()
+ unicodeData.addGC(gc, cp)
+ }
+ if p.err != nil {
+ return nil, p.err
+ }
+
+ return unicodeData, nil
+}
+
+func (u *UnicodeData) addGC(gc string, cp *CodePointRange) {
+ // https://www.unicode.org/reports/tr44/#Empty_Fields
+ // > The data file UnicodeData.txt defines many property values in each record. When a field in a data line
+ // > for a code point is empty, that indicates that the property takes the default value for that code point.
+ if gc == "" {
+ return
+ }
+
+ cps, ok := u.GeneralCategory[u.propValAliases.gcAbb(gc)]
+ if ok {
+ c := cps[len(cps)-1]
+ if cp.From-c.To == 1 {
+ c.To = cp.To
+ } else {
+ u.GeneralCategory[u.propValAliases.gcAbb(gc)] = append(cps, cp)
+ }
+ } else {
+ u.GeneralCategory[u.propValAliases.gcAbb(gc)] = []*CodePointRange{cp}
+ }
+}
diff --git a/src/urubu/utf8/utf8.go b/src/urubu/utf8/utf8.go
new file mode 100644
index 0000000..4f52bd4
--- /dev/null
+++ b/src/urubu/utf8/utf8.go
@@ -0,0 +1,112 @@
+package utf8
+
+import (
+ "fmt"
+ "strings"
+)
+
+type CharBlock struct {
+ From []byte
+ To []byte
+}
+
+func (b *CharBlock) String() string {
+ var s strings.Builder
+ fmt.Fprint(&s, "<")
+ fmt.Fprintf(&s, "%X", b.From[0])
+ for i := 1; i < len(b.From); i++ {
+ fmt.Fprintf(&s, " %X", b.From[i])
+ }
+ fmt.Fprint(&s, "..")
+ fmt.Fprintf(&s, "%X", b.To[0])
+ for i := 1; i < len(b.To); i++ {
+ fmt.Fprintf(&s, " %X", b.To[i])
+ }
+ fmt.Fprint(&s, ">")
+ return s.String()
+}
+
+func GenCharBlocks(from, to rune) ([]*CharBlock, error) {
+ rs, err := splitCodePoint(from, to)
+ if err != nil {
+ return nil, err
+ }
+
+ blks := make([]*CharBlock, len(rs))
+ for i, r := range rs {
+ blks[i] = &CharBlock{
+ From: []byte(string(r.from)),
+ To: []byte(string(r.to)),
+ }
+ }
+
+ return blks, nil
+}
+
+type cpRange struct {
+ from rune
+ to rune
+}
+
+// splitCodePoint splits a code point range represented by <from..to> into some blocks. The code points that
+// the block contains will be a continuous byte sequence when encoded into UTF-8. For instance, this function
+// splits <U+0000..U+07FF> into <U+0000..U+007F> and <U+0080..U+07FF> because <U+0000..U+07FF> is continuous on
+// the code point but non-continuous in the UTF-8 byte sequence (In UTF-8, <U+0000..U+007F> is encoded <00..7F>,
+// and <U+0080..U+07FF> is encoded <C2 80..DF BF>).
+//
+// The blocks don't contain surrogate code points <U+D800..U+DFFF> because byte sequences encoding them are
+// ill-formed in UTF-8. For instance, <U+D000..U+FFFF> is split into <U+D000..U+D7FF> and <U+E000..U+FFFF>.
+// However, when `from` or `to` itself is the surrogate code point, this function returns an error.
+func splitCodePoint(from, to rune) ([]*cpRange, error) {
+ if from > to {
+ return nil, fmt.Errorf("code point range must be from <= to: U+%X..U+%X", from, to)
+ }
+ if from < 0x0000 || from > 0x10ffff || to < 0x0000 || to > 0x10ffff {
+ return nil, fmt.Errorf("code point must be >=U+0000 and <=U+10FFFF: U+%X..U+%X", from, to)
+ }
+ // https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf > 3.9 Unicode Encoding Forms > UTF-8 D92
+ // > Because surrogate code points are not Unicode scalar values, any UTF-8 byte sequence that would otherwise
+ // > map to code points U+D800..U+DFFF is ill-formed.
+ if from >= 0xd800 && from <= 0xdfff || to >= 0xd800 && to <= 0xdfff {
+ return nil, fmt.Errorf("surrogate code points U+D800..U+DFFF are not allowed in UTF-8: U+%X..U+%X", from, to)
+ }
+
+ in := &cpRange{
+ from: from,
+ to: to,
+ }
+ var rs []*cpRange
+ for in.from <= in.to {
+ r := &cpRange{
+ from: in.from,
+ to: in.to,
+ }
+ // https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf > 3.9 Unicode Encoding Forms > UTF-8 Table 3-7. Well-Formed UTF-8 Byte Sequences
+ switch {
+ case in.from <= 0x007f && in.to > 0x007f:
+ r.to = 0x007f
+ case in.from <= 0x07ff && in.to > 0x07ff:
+ r.to = 0x07ff
+ case in.from <= 0x0fff && in.to > 0x0fff:
+ r.to = 0x0fff
+ case in.from <= 0xcfff && in.to > 0xcfff:
+ r.to = 0xcfff
+ case in.from <= 0xd7ff && in.to > 0xd7ff:
+ r.to = 0xd7ff
+ case in.from <= 0xffff && in.to > 0xffff:
+ r.to = 0xffff
+ case in.from <= 0x3ffff && in.to > 0x3ffff:
+ r.to = 0x3ffff
+ case in.from <= 0xfffff && in.to > 0xfffff:
+ r.to = 0xfffff
+ }
+ rs = append(rs, r)
+ in.from = r.to + 1
+
+ // Skip surrogate code points U+D800..U+DFFF.
+ if in.from >= 0xd800 && in.from <= 0xdfff {
+ in.from = 0xe000
+ }
+ }
+ return rs, nil
+}