Compare commits
4 Commits
5f9467e851
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 73fd1dd90d | |||
| dc87bef1c2 | |||
| 11fcbeb31a | |||
| 1fd09335cd |
149
schema/ast/ast.go
Normal file
149
schema/ast/ast.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"azalea/schema/token"
|
||||
"azalea/schema/util"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Schema ExprList
|
||||
type ExprList []Expr
|
||||
type Expr struct {
|
||||
Name string
|
||||
Left *Val
|
||||
Right *Val
|
||||
}
|
||||
type ValList []Val
|
||||
type Val struct {
|
||||
string *string
|
||||
rune *rune
|
||||
int *int64
|
||||
float *float64
|
||||
imaginary *complex128
|
||||
name *string
|
||||
*Expr
|
||||
}
|
||||
|
||||
func NewStringVal(val *token.Token) (Val, error) {
|
||||
s, err := strconv.Unquote(string(val.Lit))
|
||||
return Val{string: &s}, err
|
||||
}
|
||||
func NewIStringVal(val *token.Token) (Val, error) {
|
||||
s, err := util.InterpretString(string(val.Lit))
|
||||
return Val{string: &s}, err
|
||||
}
|
||||
func NewRuneVal(val *token.Token) (Val, error) {
|
||||
r := util.RuneValue(val.Lit)
|
||||
return Val{rune: &r}, nil
|
||||
}
|
||||
func NewIntVal(val *token.Token) (Val, error) {
|
||||
i, err := strconv.ParseInt(string(val.Lit), 0, 64)
|
||||
return Val{int: &i}, err
|
||||
}
|
||||
|
||||
func NewFloatVal(val *token.Token) (Val, error) {
|
||||
f, err := strconv.ParseFloat(string(val.Lit), 64)
|
||||
return Val{float: &f}, err
|
||||
}
|
||||
|
||||
func NewComplexVal(val *token.Token) (Val, error) {
|
||||
c, err := strconv.ParseComplex(string(val.Lit), 128)
|
||||
return Val{imaginary: &c}, err
|
||||
}
|
||||
|
||||
func NewNameVal(val *token.Token) (Val, error) {
|
||||
name := string(val.Lit)
|
||||
return Val{name: &name}, nil
|
||||
}
|
||||
|
||||
func NewExprVal(val any) (Val, error) {
|
||||
expr := val.(Expr)
|
||||
return Val{Expr: &expr}, nil
|
||||
}
|
||||
|
||||
func NewExprList(expr any) (ExprList, error) {
|
||||
return ExprList{expr.(Expr)}, nil
|
||||
}
|
||||
|
||||
func AppendExpr(exprList, expr any) (ExprList, error) {
|
||||
return append(exprList.(ExprList), expr.(Expr)), nil
|
||||
}
|
||||
|
||||
func NewValList(val any) (ValList, error) {
|
||||
return ValList{val.(Val)}, nil
|
||||
}
|
||||
|
||||
func AppendVal(valList, val any) (ValList, error) {
|
||||
return append(valList.(ValList), val.(Val)), nil
|
||||
}
|
||||
func NewExpr(name *token.Token, left any, right any) (Expr, error) {
|
||||
var l Val
|
||||
var r Val
|
||||
if left != nil {
|
||||
l = left.(Val)
|
||||
}
|
||||
if right != nil {
|
||||
r = right.(Val)
|
||||
}
|
||||
|
||||
return Expr{string(name.Lit), &l, &r}, nil
|
||||
}
|
||||
func ListExpr(val any) (Expr, error) {
|
||||
vals := val.(ValList)
|
||||
root := Expr{
|
||||
Name: ".",
|
||||
}
|
||||
current := &root
|
||||
for _, val := range vals[:len(vals)-2] {
|
||||
current.Left = &val
|
||||
current.Right = &Val{
|
||||
Expr: &Expr{
|
||||
Name: ".",
|
||||
}}
|
||||
current = current.Right.Expr
|
||||
}
|
||||
current.Left = &vals[len(vals)-2]
|
||||
current.Right = &vals[len(vals)-1]
|
||||
return root, nil
|
||||
}
|
||||
|
||||
func (e Expr) String() string {
|
||||
sb := new(strings.Builder)
|
||||
sb.WriteRune('(')
|
||||
sb.WriteString(e.Name)
|
||||
sb.WriteRune(' ')
|
||||
if e.Left != nil {
|
||||
sb.WriteString(e.Left.String())
|
||||
}
|
||||
sb.WriteRune(' ')
|
||||
if e.Left != nil {
|
||||
sb.WriteString(e.Right.String())
|
||||
}
|
||||
sb.WriteRune(')')
|
||||
return sb.String()
|
||||
}
|
||||
func (v *Val) String() string {
|
||||
if v.string != nil {
|
||||
return *v.string
|
||||
}
|
||||
if v.rune != nil {
|
||||
return string(*v.rune)
|
||||
}
|
||||
if v.int != nil {
|
||||
return strconv.FormatInt(*v.int, 10)
|
||||
}
|
||||
if v.float != nil {
|
||||
return strconv.FormatFloat(*v.float, 'g', -1, 64)
|
||||
}
|
||||
if v.imaginary != nil {
|
||||
return strconv.FormatComplex(*v.imaginary, 'g', -1, 128)
|
||||
}
|
||||
if v.name != nil {
|
||||
return *v.name
|
||||
}
|
||||
if v.Expr != nil {
|
||||
return v.Expr.String()
|
||||
}
|
||||
return "<nil>"
|
||||
}
|
||||
@@ -1,40 +1,76 @@
|
||||
string: '`' {.} '`' | '"' {.} '"';
|
||||
raw_string: '`' {.} '`';
|
||||
interpreted_string: '"' {_byte_value | _little_u_value | _big_u_value | _escaped_char | ' ' - '!' | '#' - '[' | ']' - '\U0010FFFF'} '"';
|
||||
|
||||
_unicode_value: . | _little_u_value | _big_u_value | _escaped_char;
|
||||
_byte_value: _octal_byte_value | _hex_byte_value;
|
||||
_little_u_value: '\\' 'u' _hex_digit _hex_digit _hex_digit _hex_digit;
|
||||
_big_u_value: '\\' 'U' _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit;
|
||||
_escaped_char: '\\' ('a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '\\' | '\'' | '"');
|
||||
_octal_byte_value: '\\' _oct_digit _oct_digit _oct_digit;
|
||||
_hex_byte_value: '\\' 'x' _hex_digit _hex_digit;
|
||||
rune: '\'' (_unicode_value | _byte_value) '\'';
|
||||
|
||||
_bin_digit: '0' - '1';
|
||||
_bin_digits: _bin_digit {_bin_digit | '_'};
|
||||
_oct_digit: _bin_digit | '2' - '7';
|
||||
_oct_digits: _oct_digit {_oct_digit | '_'};
|
||||
_dec_digit: _oct_digit | '8' - '9';
|
||||
_dec_digits: _dec_digit {_dec_digit | '_'};
|
||||
_hex_digit: _dec_digit | 'A' - 'F' | 'a' - 'f';
|
||||
number: ['-' | '+'] '0' 'b' _bin_digit {_bin_digit | '_'}
|
||||
| ['-' | '+'] '0' 'o' _oct_digit {_oct_digit | '_'}
|
||||
| ['-' | '+'] _dec_digit {_dec_digit | '_'}
|
||||
| ['-' | '+'] '0' 'x' _hex_digit {_hex_digit | '_'};
|
||||
_hex_digits: _hex_digit {_hex_digit | '_'};
|
||||
|
||||
_name_initial: 'A' - 'Z' | 'a' - 'z' | '_' | '~' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '-' | '_' | '+' | '=' | '?' | '/' | '.' | '\'';
|
||||
_int: ['-' | '+'] '0' ('b' | 'B') _bin_digits
|
||||
| ['-' | '+'] '0' ('o' | 'O') _oct_digits
|
||||
| ['-' | '+'] _dec_digits
|
||||
| ['-' | '+'] '0' ('x' | 'X') _hex_digits;
|
||||
int: _int;
|
||||
_dec_exponent: ('e' | 'E') ['+' | '-'] _dec_digits;
|
||||
_dec_float: ['-' | '+'] _dec_digits '.' [_dec_digits] [_dec_exponent]
|
||||
| _dec_digits _dec_exponent
|
||||
| '.' _dec_digits [_dec_exponent];
|
||||
|
||||
_hex_exponent: ('p' | 'P') ['+' | '-'] _dec_digits;
|
||||
_hex_mantissa: ['_'] _hex_digits '.' _hex_digits | ['_'] _hex_digits | '.' _hex_digits;
|
||||
_hex_float: ['-' | '+'] '0' ('x' | 'X') _hex_mantissa _hex_exponent;
|
||||
_float: _dec_float | _hex_float;
|
||||
float: _float;
|
||||
imaginary: (_dec_digits | _int | _float) 'i';
|
||||
|
||||
_name_initial: 'A' - 'Z' | 'a' - 'z' | '_' | '~' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '-' | '_' | '+' | '=' | '?' | '/' | '.';
|
||||
_name_char: _name_initial | _dec_digit;
|
||||
name: _name_initial {_name_char};
|
||||
|
||||
!whitespace: ' ' | '\t' | '\n' | '\r';
|
||||
!comment: ';' {.} '\n';
|
||||
|
||||
<<>>
|
||||
<<
|
||||
import (
|
||||
"azalea/schema/ast"
|
||||
"azalea/schema/token"
|
||||
)
|
||||
>>
|
||||
Schema: ExprList;
|
||||
ExprList
|
||||
: Expr
|
||||
| ExprList Expr
|
||||
: Expr <<ast.NewExprList($0)>>
|
||||
| ExprList Expr <<ast.AppendExpr($0, $1)>>
|
||||
;
|
||||
ValList
|
||||
: Val
|
||||
| ValList Val
|
||||
: Val <<ast.NewValList($0)>>
|
||||
| ValList Val <<ast.AppendVal($0, $1)>>
|
||||
;
|
||||
Val
|
||||
: string
|
||||
| number
|
||||
| name
|
||||
| Expr
|
||||
: raw_string <<ast.NewStringVal($T0)>>
|
||||
| interpreted_string <<ast.NewIStringVal($T0)>>
|
||||
| rune <<ast.NewRuneVal($T0)>>
|
||||
| int <<ast.NewIntVal($T0)>>
|
||||
| float <<ast.NewFloatVal($T0)>>
|
||||
| imaginary <<ast.NewComplexVal($T0)>>
|
||||
| name <<ast.NewNameVal($T0)>>
|
||||
| Expr <<ast.NewExprVal($0)>>
|
||||
;
|
||||
Expr
|
||||
: "(" name Val Val ")"
|
||||
| "(" name Val ")"
|
||||
| "(" name ")"
|
||||
| "(" "." ValList ")"
|
||||
: "(" name Val Val ")" <<ast.NewExpr($T1, $2, $3)>>
|
||||
| "(" name Val ")" <<ast.NewExpr($T1, $2, nil)>>
|
||||
| "(" name ")" <<ast.NewExpr($T1, nil, nil)>>
|
||||
| "(" "." ValList ")" <<ast.ListExpr($2)>>
|
||||
;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
const (
|
||||
NoState = -1
|
||||
NumStates = 52
|
||||
NumSymbols = 57
|
||||
NumStates = 278
|
||||
NumSymbols = 104
|
||||
)
|
||||
|
||||
type Lexer struct {
|
||||
@@ -133,57 +133,104 @@ Lexer symbols:
|
||||
1: '`'
|
||||
2: '"'
|
||||
3: '"'
|
||||
4: '-'
|
||||
5: '+'
|
||||
6: '0'
|
||||
7: 'b'
|
||||
8: '_'
|
||||
9: '-'
|
||||
10: '+'
|
||||
11: '0'
|
||||
12: 'o'
|
||||
13: '_'
|
||||
14: '-'
|
||||
15: '+'
|
||||
16: '_'
|
||||
17: '-'
|
||||
18: '+'
|
||||
19: '0'
|
||||
20: 'x'
|
||||
21: '_'
|
||||
22: '('
|
||||
23: ')'
|
||||
24: '.'
|
||||
25: '_'
|
||||
26: '~'
|
||||
27: '!'
|
||||
28: '@'
|
||||
29: '#'
|
||||
30: '$'
|
||||
31: '%'
|
||||
32: '^'
|
||||
33: '&'
|
||||
34: '*'
|
||||
35: '-'
|
||||
36: '_'
|
||||
37: '+'
|
||||
38: '='
|
||||
39: '?'
|
||||
40: '/'
|
||||
41: '.'
|
||||
42: '''
|
||||
43: ' '
|
||||
44: '\t'
|
||||
45: '\n'
|
||||
46: '\r'
|
||||
47: ';'
|
||||
48: '\n'
|
||||
49: '0'-'1'
|
||||
50: '2'-'7'
|
||||
51: '8'-'9'
|
||||
52: 'A'-'F'
|
||||
53: 'a'-'f'
|
||||
54: 'A'-'Z'
|
||||
55: 'a'-'z'
|
||||
56: .
|
||||
4: '''
|
||||
5: '''
|
||||
6: 'i'
|
||||
7: '('
|
||||
8: ')'
|
||||
9: '.'
|
||||
10: '\'
|
||||
11: 'u'
|
||||
12: '\'
|
||||
13: 'U'
|
||||
14: '\'
|
||||
15: 'a'
|
||||
16: 'b'
|
||||
17: 'f'
|
||||
18: 'n'
|
||||
19: 'r'
|
||||
20: 't'
|
||||
21: 'v'
|
||||
22: '\'
|
||||
23: '''
|
||||
24: '"'
|
||||
25: '\'
|
||||
26: '\'
|
||||
27: 'x'
|
||||
28: '_'
|
||||
29: '_'
|
||||
30: '_'
|
||||
31: '_'
|
||||
32: '-'
|
||||
33: '+'
|
||||
34: '0'
|
||||
35: 'b'
|
||||
36: 'B'
|
||||
37: '-'
|
||||
38: '+'
|
||||
39: '0'
|
||||
40: 'o'
|
||||
41: 'O'
|
||||
42: '-'
|
||||
43: '+'
|
||||
44: '-'
|
||||
45: '+'
|
||||
46: '0'
|
||||
47: 'x'
|
||||
48: 'X'
|
||||
49: 'e'
|
||||
50: 'E'
|
||||
51: '+'
|
||||
52: '-'
|
||||
53: '-'
|
||||
54: '+'
|
||||
55: '.'
|
||||
56: '.'
|
||||
57: 'p'
|
||||
58: 'P'
|
||||
59: '+'
|
||||
60: '-'
|
||||
61: '_'
|
||||
62: '.'
|
||||
63: '_'
|
||||
64: '.'
|
||||
65: '-'
|
||||
66: '+'
|
||||
67: '0'
|
||||
68: 'x'
|
||||
69: 'X'
|
||||
70: '_'
|
||||
71: '~'
|
||||
72: '!'
|
||||
73: '@'
|
||||
74: '#'
|
||||
75: '$'
|
||||
76: '%'
|
||||
77: '^'
|
||||
78: '&'
|
||||
79: '*'
|
||||
80: '-'
|
||||
81: '_'
|
||||
82: '+'
|
||||
83: '='
|
||||
84: '?'
|
||||
85: '/'
|
||||
86: '.'
|
||||
87: ' '
|
||||
88: '\t'
|
||||
89: '\n'
|
||||
90: '\r'
|
||||
91: ';'
|
||||
92: '\n'
|
||||
93: ' '-'!'
|
||||
94: '#'-'['
|
||||
95: ']'-\U0010ffff
|
||||
96: '0'-'1'
|
||||
97: '2'-'7'
|
||||
98: '8'-'9'
|
||||
99: 'A'-'F'
|
||||
100: 'a'-'f'
|
||||
101: 'A'-'Z'
|
||||
102: 'a'-'z'
|
||||
103: .
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,18 @@
|
||||
//go:generate gocc -a azschema.bnf
|
||||
package schema
|
||||
|
||||
import (
|
||||
"azalea/schema/ast"
|
||||
"azalea/schema/lexer"
|
||||
"azalea/schema/parser"
|
||||
)
|
||||
|
||||
func CreateSchema(in string) (schema ast.Schema, err error) {
|
||||
s := lexer.NewLexer([]byte(in))
|
||||
p := parser.NewParser()
|
||||
a, err := p.Parse(s)
|
||||
if err == nil {
|
||||
schema = ast.Schema(a.(ast.ExprList))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
135
schema/parse.go
135
schema/parse.go
@@ -1,135 +0,0 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
Function string
|
||||
Left, Right *Node
|
||||
*Token
|
||||
}
|
||||
type RawArgument struct {
|
||||
Index uintptr
|
||||
Size uintptr
|
||||
}
|
||||
|
||||
func (n *Node) String() string {
|
||||
if n.Token != nil {
|
||||
return n.Token.String()
|
||||
}
|
||||
return fmt.Sprintf("(%s %s %s)", n.Function, n.Left, n.Right)
|
||||
}
|
||||
|
||||
func Parse(tokens [][]*Token) ([]*Node, error) {
|
||||
trees := make([]*Node, len(tokens))
|
||||
for i, statement := range tokens {
|
||||
node, err := parse(statement, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
trees[i] = node
|
||||
}
|
||||
return trees, nil
|
||||
}
|
||||
func parse(statement []*Token, depth uintptr) (*Node, error) {
|
||||
if len(statement) == 0 || (len(statement) == 2 && statement[0].Type == OpenParenTokenType && statement[1].Type == CloseParenTokenType) {
|
||||
return &Node{
|
||||
Function: "",
|
||||
Left: nil,
|
||||
Right: nil,
|
||||
Token: nil,
|
||||
}, nil
|
||||
}
|
||||
if len(statement) < 3 {
|
||||
return nil, fmt.Errorf("statement too short")
|
||||
}
|
||||
if statement[0].Type != OpenParenTokenType || statement[len(statement)-1].Type != CloseParenTokenType {
|
||||
return nil, fmt.Errorf("malformed statement")
|
||||
}
|
||||
statement = statement[1 : len(statement)-1]
|
||||
expressions := make([]*Node, len(statement))
|
||||
exprCounter := 0
|
||||
lastBegin := -1
|
||||
for i := 0; i < len(statement); i++ {
|
||||
if lastBegin == -1 {
|
||||
switch statement[i].Type {
|
||||
case OpenParenTokenType:
|
||||
if statement[i].Number == int64(depth)+1 {
|
||||
lastBegin = i
|
||||
}
|
||||
break
|
||||
case CloseParenTokenType:
|
||||
return nil, fmt.Errorf("unexpected end of statement")
|
||||
default:
|
||||
expressions[exprCounter] = &Node{
|
||||
Function: "",
|
||||
Left: nil,
|
||||
Right: nil,
|
||||
Token: statement[i],
|
||||
}
|
||||
exprCounter++
|
||||
break
|
||||
}
|
||||
}
|
||||
if statement[i].Type == CloseParenTokenType && statement[i].Number == int64(depth)+1 {
|
||||
res, err := parse(statement[lastBegin:i+1], depth+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expressions[exprCounter] = res
|
||||
exprCounter++
|
||||
lastBegin = -1
|
||||
}
|
||||
}
|
||||
for i, expr := range expressions {
|
||||
if expr == nil {
|
||||
expressions = expressions[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
switch len(expressions) {
|
||||
case 1:
|
||||
node := expressions[0]
|
||||
if node.Token != nil && node.Type == NameTokenType {
|
||||
return &Node{
|
||||
Function: node.Value,
|
||||
Left: nil,
|
||||
Right: nil,
|
||||
Token: nil,
|
||||
}, nil
|
||||
}
|
||||
return node, nil
|
||||
case 2, 3:
|
||||
first := expressions[0]
|
||||
if first.Token != nil && first.Type == NameTokenType {
|
||||
var right *Node = nil
|
||||
if len(expressions) == 3 {
|
||||
right = expressions[2]
|
||||
}
|
||||
return &Node{
|
||||
Function: first.Value,
|
||||
Left: expressions[1],
|
||||
Right: right,
|
||||
Token: nil,
|
||||
}, nil
|
||||
}
|
||||
//fallthrough
|
||||
default:
|
||||
root := &Node{
|
||||
Function: ".",
|
||||
}
|
||||
current := root
|
||||
for _, expr := range expressions[:len(expressions)-2] {
|
||||
current.Left = expr
|
||||
current.Right = &Node{
|
||||
Function: ".",
|
||||
}
|
||||
current = current.Right
|
||||
}
|
||||
current.Left = expressions[len(expressions)-2]
|
||||
current.Right = expressions[len(expressions)-1]
|
||||
return root, nil
|
||||
}
|
||||
return nil, fmt.Errorf("parsing error")
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
gv "github.com/dominikbraun/graph"
|
||||
"github.com/dominikbraun/graph/draw"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
in := "()" +
|
||||
"(test)" +
|
||||
"(test a)" +
|
||||
"(test a b)" +
|
||||
"(test a b c)" +
|
||||
"(test (a b c))" +
|
||||
"(test (a b c d))" +
|
||||
"(\"hello world\")" +
|
||||
"(concat \"hello\" \"world\")" +
|
||||
"(+ 1 2)"
|
||||
want := "( <nil> <nil>)\n" +
|
||||
"(test <nil> <nil>)\n" +
|
||||
"(test [n'a'] <nil>)\n" +
|
||||
"(test [n'a'] [n'b'])\n" +
|
||||
"(. [n'test'] (. [n'a'] (. [n'b'] [n'c'])))\n" +
|
||||
"(test (a [n'b'] [n'c']) <nil>)\n" +
|
||||
"(test (. [n'a'] (. [n'b'] (. [n'c'] [n'd']))) <nil>)\n" +
|
||||
"[l'hello world']\n" +
|
||||
"(concat [l'hello'] [l'world'])\n" +
|
||||
"(+ [l1] [l2])\n"
|
||||
tokens, err := Tokenize([]byte(in))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
parse, err := Parse(tokens)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
test := strings.Builder{}
|
||||
for _, line := range parse {
|
||||
test.Write([]byte(fmt.Sprintf("%s\n", line)))
|
||||
}
|
||||
if test.String() != want {
|
||||
t.Errorf("\ngot:\n%s\nwant:\n%s", test.String(), want)
|
||||
}
|
||||
if os.Getenv("AZALEA_TEST_VISUALIZE") == "1" {
|
||||
Visualize(parse)
|
||||
}
|
||||
}
|
||||
func hash(n *Node) uintptr {
|
||||
return uintptr(unsafe.Pointer(n))
|
||||
}
|
||||
func Visualize(nodes []*Node) {
|
||||
g := gv.New(hash, gv.Tree(), gv.Directed())
|
||||
for _, node := range nodes {
|
||||
addNode(node, g)
|
||||
}
|
||||
dot, _ := os.CreateTemp("", "azalea-graph-*.gv")
|
||||
_ = draw.DOT(g, dot)
|
||||
_ = exec.Command("dot", "-Tsvg", "-O", dot.Name()).Run()
|
||||
_ = exec.Command("qimgv", dot.Name()+".svg").Run()
|
||||
_ = os.Remove(dot.Name())
|
||||
_ = os.Remove(dot.Name() + ".svg")
|
||||
}
|
||||
func addNode(node *Node, g gv.Graph[uintptr, *Node]) *Node {
|
||||
str := ""
|
||||
if node.Function != "" {
|
||||
str = node.Function
|
||||
} else {
|
||||
if node.Token != nil {
|
||||
str = node.Token.String()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
_ = g.AddVertex(node, gv.VertexAttribute("label", str))
|
||||
if node.Left != nil {
|
||||
left := addNode(node.Left, g)
|
||||
_ = g.AddEdge(hash(node), hash(left), gv.EdgeAttribute("splines", "line"))
|
||||
}
|
||||
if node.Right != nil {
|
||||
right := addNode(node.Right, g)
|
||||
_ = g.AddEdge(hash(node), hash(right), gv.EdgeAttribute("splines", "line"))
|
||||
}
|
||||
return node
|
||||
}
|
||||
@@ -16,8 +16,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
shift(4), // (
|
||||
nil, // )
|
||||
@@ -29,8 +33,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
accept(true), // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
nil, // )
|
||||
@@ -42,8 +50,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(1), // ␚, reduce: Schema
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
shift(4), // (
|
||||
nil, // )
|
||||
@@ -55,8 +67,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(2), // ␚, reduce: ExprList
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(2), // (, reduce: ExprList
|
||||
nil, // )
|
||||
@@ -68,8 +84,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
shift(6), // name
|
||||
nil, // (
|
||||
nil, // )
|
||||
@@ -81,8 +101,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(3), // ␚, reduce: ExprList
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(3), // (, reduce: ExprList
|
||||
nil, // )
|
||||
@@ -94,11 +118,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(14), // )
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(18), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -107,10 +135,14 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
@@ -120,11 +152,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(9), // string, reduce: Val
|
||||
reduce(9), // number, reduce: Val
|
||||
reduce(9), // name, reduce: Val
|
||||
reduce(9), // (, reduce: Val
|
||||
reduce(9), // ), reduce: Val
|
||||
reduce(13), // raw_string, reduce: Val
|
||||
reduce(13), // interpreted_string, reduce: Val
|
||||
reduce(13), // rune, reduce: Val
|
||||
reduce(13), // int, reduce: Val
|
||||
reduce(13), // float, reduce: Val
|
||||
reduce(13), // imaginary, reduce: Val
|
||||
reduce(13), // name, reduce: Val
|
||||
reduce(13), // (, reduce: Val
|
||||
reduce(13), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -133,11 +169,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(19), // string
|
||||
shift(20), // number
|
||||
shift(21), // name
|
||||
shift(22), // (
|
||||
shift(23), // )
|
||||
shift(23), // raw_string
|
||||
shift(24), // interpreted_string
|
||||
shift(25), // rune
|
||||
shift(26), // int
|
||||
shift(27), // float
|
||||
shift(28), // imaginary
|
||||
shift(29), // name
|
||||
shift(30), // (
|
||||
shift(31), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -146,8 +186,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(6), // string, reduce: Val
|
||||
reduce(6), // number, reduce: Val
|
||||
reduce(6), // raw_string, reduce: Val
|
||||
reduce(6), // interpreted_string, reduce: Val
|
||||
reduce(6), // rune, reduce: Val
|
||||
reduce(6), // int, reduce: Val
|
||||
reduce(6), // float, reduce: Val
|
||||
reduce(6), // imaginary, reduce: Val
|
||||
reduce(6), // name, reduce: Val
|
||||
reduce(6), // (, reduce: Val
|
||||
reduce(6), // ), reduce: Val
|
||||
@@ -159,8 +203,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(7), // string, reduce: Val
|
||||
reduce(7), // number, reduce: Val
|
||||
reduce(7), // raw_string, reduce: Val
|
||||
reduce(7), // interpreted_string, reduce: Val
|
||||
reduce(7), // rune, reduce: Val
|
||||
reduce(7), // int, reduce: Val
|
||||
reduce(7), // float, reduce: Val
|
||||
reduce(7), // imaginary, reduce: Val
|
||||
reduce(7), // name, reduce: Val
|
||||
reduce(7), // (, reduce: Val
|
||||
reduce(7), // ), reduce: Val
|
||||
@@ -172,8 +220,12 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(8), // string, reduce: Val
|
||||
reduce(8), // number, reduce: Val
|
||||
reduce(8), // raw_string, reduce: Val
|
||||
reduce(8), // interpreted_string, reduce: Val
|
||||
reduce(8), // rune, reduce: Val
|
||||
reduce(8), // int, reduce: Val
|
||||
reduce(8), // float, reduce: Val
|
||||
reduce(8), // imaginary, reduce: Val
|
||||
reduce(8), // name, reduce: Val
|
||||
reduce(8), // (, reduce: Val
|
||||
reduce(8), // ), reduce: Val
|
||||
@@ -185,24 +237,32 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
shift(24), // name
|
||||
nil, // (
|
||||
nil, // )
|
||||
shift(25), // .
|
||||
reduce(9), // raw_string, reduce: Val
|
||||
reduce(9), // interpreted_string, reduce: Val
|
||||
reduce(9), // rune, reduce: Val
|
||||
reduce(9), // int, reduce: Val
|
||||
reduce(9), // float, reduce: Val
|
||||
reduce(9), // imaginary, reduce: Val
|
||||
reduce(9), // name, reduce: Val
|
||||
reduce(9), // (, reduce: Val
|
||||
reduce(9), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S14
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(12), // ␚, reduce: Expr
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
reduce(12), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // ␚
|
||||
reduce(10), // raw_string, reduce: Val
|
||||
reduce(10), // interpreted_string, reduce: Val
|
||||
reduce(10), // rune, reduce: Val
|
||||
reduce(10), // int, reduce: Val
|
||||
reduce(10), // float, reduce: Val
|
||||
reduce(10), // imaginary, reduce: Val
|
||||
reduce(10), // name, reduce: Val
|
||||
reduce(10), // (, reduce: Val
|
||||
reduce(10), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -211,11 +271,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(27), // )
|
||||
reduce(11), // raw_string, reduce: Val
|
||||
reduce(11), // interpreted_string, reduce: Val
|
||||
reduce(11), // rune, reduce: Val
|
||||
reduce(11), // int, reduce: Val
|
||||
reduce(11), // float, reduce: Val
|
||||
reduce(11), // imaginary, reduce: Val
|
||||
reduce(11), // name, reduce: Val
|
||||
reduce(11), // (, reduce: Val
|
||||
reduce(11), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -224,11 +288,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(4), // string, reduce: ValList
|
||||
reduce(4), // number, reduce: ValList
|
||||
reduce(4), // name, reduce: ValList
|
||||
reduce(4), // (, reduce: ValList
|
||||
reduce(4), // ), reduce: ValList
|
||||
reduce(12), // raw_string, reduce: Val
|
||||
reduce(12), // interpreted_string, reduce: Val
|
||||
reduce(12), // rune, reduce: Val
|
||||
reduce(12), // int, reduce: Val
|
||||
reduce(12), // float, reduce: Val
|
||||
reduce(12), // imaginary, reduce: Val
|
||||
reduce(12), // name, reduce: Val
|
||||
reduce(12), // (, reduce: Val
|
||||
reduce(12), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -237,24 +305,32 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
shift(32), // name
|
||||
nil, // (
|
||||
reduce(9), // ), reduce: Val
|
||||
nil, // .
|
||||
nil, // )
|
||||
shift(33), // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S18
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
reduce(16), // ␚, reduce: Expr
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
shift(28), // )
|
||||
reduce(16), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -263,11 +339,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(6), // ), reduce: Val
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(35), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -276,11 +356,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(7), // ), reduce: Val
|
||||
reduce(4), // raw_string, reduce: ValList
|
||||
reduce(4), // interpreted_string, reduce: ValList
|
||||
reduce(4), // rune, reduce: ValList
|
||||
reduce(4), // int, reduce: ValList
|
||||
reduce(4), // float, reduce: ValList
|
||||
reduce(4), // imaginary, reduce: ValList
|
||||
reduce(4), // name, reduce: ValList
|
||||
reduce(4), // (, reduce: ValList
|
||||
reduce(4), // ), reduce: ValList
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -289,11 +373,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(8), // ), reduce: Val
|
||||
reduce(13), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -302,24 +390,32 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
shift(29), // name
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
nil, // )
|
||||
shift(30), // .
|
||||
shift(36), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S23
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(11), // ␚, reduce: Expr
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(11), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // (
|
||||
reduce(6), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -328,11 +424,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(32), // )
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(7), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -341,11 +441,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
nil, // )
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(8), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -354,11 +458,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(5), // string, reduce: ValList
|
||||
reduce(5), // number, reduce: ValList
|
||||
reduce(5), // name, reduce: ValList
|
||||
reduce(5), // (, reduce: ValList
|
||||
reduce(5), // ), reduce: ValList
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(9), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -366,12 +474,16 @@ var actionTab = actionTable{
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(13), // ␚, reduce: Expr
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(13), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // (
|
||||
reduce(10), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -379,12 +491,16 @@ var actionTab = actionTable{
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
reduce(10), // ␚, reduce: Expr
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(10), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // (
|
||||
reduce(11), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -393,11 +509,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(35), // )
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(12), // ), reduce: Val
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -406,24 +526,32 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
shift(37), // name
|
||||
nil, // (
|
||||
nil, // )
|
||||
nil, // .
|
||||
shift(38), // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S31
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(19), // string
|
||||
shift(20), // number
|
||||
shift(21), // name
|
||||
shift(22), // (
|
||||
shift(38), // )
|
||||
reduce(15), // ␚, reduce: Expr
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(15), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -432,11 +560,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(12), // string, reduce: Expr
|
||||
reduce(12), // number, reduce: Expr
|
||||
reduce(12), // name, reduce: Expr
|
||||
reduce(12), // (, reduce: Expr
|
||||
reduce(12), // ), reduce: Expr
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(40), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -445,11 +577,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(39), // )
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -458,11 +594,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(19), // string
|
||||
shift(20), // number
|
||||
shift(21), // name
|
||||
shift(22), // (
|
||||
shift(41), // )
|
||||
reduce(5), // raw_string, reduce: ValList
|
||||
reduce(5), // interpreted_string, reduce: ValList
|
||||
reduce(5), // rune, reduce: ValList
|
||||
reduce(5), // int, reduce: ValList
|
||||
reduce(5), // float, reduce: ValList
|
||||
reduce(5), // imaginary, reduce: ValList
|
||||
reduce(5), // name, reduce: ValList
|
||||
reduce(5), // (, reduce: ValList
|
||||
reduce(5), // ), reduce: ValList
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -470,12 +610,16 @@ var actionTab = actionTable{
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
reduce(17), // ␚, reduce: Expr
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(12), // ), reduce: Expr
|
||||
reduce(17), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -483,12 +627,16 @@ var actionTab = actionTable{
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
shift(10), // string
|
||||
shift(11), // number
|
||||
shift(12), // name
|
||||
shift(13), // (
|
||||
shift(42), // )
|
||||
reduce(14), // ␚, reduce: Expr
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
reduce(14), // (, reduce: Expr
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -497,10 +645,14 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(43), // )
|
||||
nil, // .
|
||||
},
|
||||
@@ -510,11 +662,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(11), // string, reduce: Expr
|
||||
reduce(11), // number, reduce: Expr
|
||||
reduce(11), // name, reduce: Expr
|
||||
reduce(11), // (, reduce: Expr
|
||||
reduce(11), // ), reduce: Expr
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
nil, // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -523,11 +679,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(13), // string, reduce: Expr
|
||||
reduce(13), // number, reduce: Expr
|
||||
reduce(13), // name, reduce: Expr
|
||||
reduce(13), // (, reduce: Expr
|
||||
reduce(13), // ), reduce: Expr
|
||||
shift(23), // raw_string
|
||||
shift(24), // interpreted_string
|
||||
shift(25), // rune
|
||||
shift(26), // int
|
||||
shift(27), // float
|
||||
shift(28), // imaginary
|
||||
shift(29), // name
|
||||
shift(30), // (
|
||||
shift(46), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -536,11 +696,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
shift(44), // )
|
||||
reduce(16), // raw_string, reduce: Expr
|
||||
reduce(16), // interpreted_string, reduce: Expr
|
||||
reduce(16), // rune, reduce: Expr
|
||||
reduce(16), // int, reduce: Expr
|
||||
reduce(16), // float, reduce: Expr
|
||||
reduce(16), // imaginary, reduce: Expr
|
||||
reduce(16), // name, reduce: Expr
|
||||
reduce(16), // (, reduce: Expr
|
||||
reduce(16), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -549,11 +713,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(11), // ), reduce: Expr
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(47), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -562,11 +730,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(13), // ), reduce: Expr
|
||||
shift(23), // raw_string
|
||||
shift(24), // interpreted_string
|
||||
shift(25), // rune
|
||||
shift(26), // int
|
||||
shift(27), // float
|
||||
shift(28), // imaginary
|
||||
shift(29), // name
|
||||
shift(30), // (
|
||||
shift(49), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -575,11 +747,15 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(10), // string, reduce: Expr
|
||||
reduce(10), // number, reduce: Expr
|
||||
reduce(10), // name, reduce: Expr
|
||||
reduce(10), // (, reduce: Expr
|
||||
reduce(10), // ), reduce: Expr
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(16), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
@@ -588,11 +764,151 @@ var actionTab = actionTable{
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // string
|
||||
nil, // number
|
||||
shift(10), // raw_string
|
||||
shift(11), // interpreted_string
|
||||
shift(12), // rune
|
||||
shift(13), // int
|
||||
shift(14), // float
|
||||
shift(15), // imaginary
|
||||
shift(16), // name
|
||||
shift(17), // (
|
||||
shift(50), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S45
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(10), // ), reduce: Expr
|
||||
shift(51), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S46
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(15), // raw_string, reduce: Expr
|
||||
reduce(15), // interpreted_string, reduce: Expr
|
||||
reduce(15), // rune, reduce: Expr
|
||||
reduce(15), // int, reduce: Expr
|
||||
reduce(15), // float, reduce: Expr
|
||||
reduce(15), // imaginary, reduce: Expr
|
||||
reduce(15), // name, reduce: Expr
|
||||
reduce(15), // (, reduce: Expr
|
||||
reduce(15), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S47
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(17), // raw_string, reduce: Expr
|
||||
reduce(17), // interpreted_string, reduce: Expr
|
||||
reduce(17), // rune, reduce: Expr
|
||||
reduce(17), // int, reduce: Expr
|
||||
reduce(17), // float, reduce: Expr
|
||||
reduce(17), // imaginary, reduce: Expr
|
||||
reduce(17), // name, reduce: Expr
|
||||
reduce(17), // (, reduce: Expr
|
||||
reduce(17), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S48
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
shift(52), // )
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S49
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(15), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S50
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(17), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S51
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
reduce(14), // raw_string, reduce: Expr
|
||||
reduce(14), // interpreted_string, reduce: Expr
|
||||
reduce(14), // rune, reduce: Expr
|
||||
reduce(14), // int, reduce: Expr
|
||||
reduce(14), // float, reduce: Expr
|
||||
reduce(14), // imaginary, reduce: Expr
|
||||
reduce(14), // name, reduce: Expr
|
||||
reduce(14), // (, reduce: Expr
|
||||
reduce(14), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
actionRow{ // S52
|
||||
canRecover: false,
|
||||
actions: [numSymbols]action{
|
||||
nil, // INVALID
|
||||
nil, // ␚
|
||||
nil, // raw_string
|
||||
nil, // interpreted_string
|
||||
nil, // rune
|
||||
nil, // int
|
||||
nil, // float
|
||||
nil, // imaginary
|
||||
nil, // name
|
||||
nil, // (
|
||||
reduce(14), // ), reduce: Expr
|
||||
nil, // .
|
||||
},
|
||||
},
|
||||
|
||||
@@ -70,8 +70,8 @@ var gotoTab = gotoTable{
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
15, // ValList
|
||||
16, // Val
|
||||
19, // ValList
|
||||
20, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S8
|
||||
@@ -87,8 +87,8 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
18, // Val
|
||||
17, // Expr
|
||||
22, // Val
|
||||
21, // Expr
|
||||
},
|
||||
gotoRow{ // S10
|
||||
-1, // S'
|
||||
@@ -135,8 +135,8 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
26, // Val
|
||||
8, // Expr
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S16
|
||||
-1, // S'
|
||||
@@ -167,8 +167,8 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
34, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S20
|
||||
-1, // S'
|
||||
@@ -207,16 +207,16 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
31, // Val
|
||||
8, // Expr
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S25
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
33, // ValList
|
||||
16, // Val
|
||||
8, // Expr
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S26
|
||||
-1, // S'
|
||||
@@ -247,26 +247,10 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
34, // Val
|
||||
8, // Expr
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S30
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
36, // ValList
|
||||
16, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S31
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
37, // Val
|
||||
17, // Expr
|
||||
},
|
||||
gotoRow{ // S32
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
@@ -274,12 +258,28 @@ var gotoTab = gotoTable{
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S33
|
||||
gotoRow{ // S31
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
26, // Val
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S32
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
39, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S33
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
41, // ValList
|
||||
20, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S34
|
||||
@@ -287,8 +287,8 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
40, // Val
|
||||
17, // Expr
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S35
|
||||
-1, // S'
|
||||
@@ -303,32 +303,32 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
26, // Val
|
||||
8, // Expr
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S37
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
42, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S38
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
44, // ValList
|
||||
20, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S39
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
45, // Val
|
||||
21, // Expr
|
||||
},
|
||||
gotoRow{ // S40
|
||||
-1, // S'
|
||||
@@ -343,16 +343,16 @@ var gotoTab = gotoTable{
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
34, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S42
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
48, // Val
|
||||
21, // Expr
|
||||
},
|
||||
gotoRow{ // S43
|
||||
-1, // S'
|
||||
@@ -363,6 +363,70 @@ var gotoTab = gotoTable{
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S44
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
34, // Val
|
||||
8, // Expr
|
||||
},
|
||||
gotoRow{ // S45
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S46
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S47
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S48
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S49
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S50
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S51
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
-1, // ValList
|
||||
-1, // Val
|
||||
-1, // Expr
|
||||
},
|
||||
gotoRow{ // S52
|
||||
-1, // S'
|
||||
-1, // Schema
|
||||
-1, // ExprList
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
numProductions = 14
|
||||
numStates = 45
|
||||
numSymbols = 14
|
||||
numProductions = 18
|
||||
numStates = 53
|
||||
numSymbols = 18
|
||||
)
|
||||
|
||||
// Stack
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
package parser
|
||||
|
||||
import (
|
||||
"azalea/schema/ast"
|
||||
"azalea/schema/token"
|
||||
)
|
||||
|
||||
type (
|
||||
ProdTab [numProductions]ProdTabEntry
|
||||
ProdTabEntry struct {
|
||||
@@ -38,123 +43,163 @@ var productionsTable = ProdTab{
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `ExprList : Expr << >>`,
|
||||
String: `ExprList : Expr << ast.NewExprList(X[0]) >>`,
|
||||
Id: "ExprList",
|
||||
NTType: 2,
|
||||
Index: 2,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewExprList(X[0])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `ExprList : ExprList Expr << >>`,
|
||||
String: `ExprList : ExprList Expr << ast.AppendExpr(X[0], X[1]) >>`,
|
||||
Id: "ExprList",
|
||||
NTType: 2,
|
||||
Index: 3,
|
||||
NumSymbols: 2,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.AppendExpr(X[0], X[1])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `ValList : Val << >>`,
|
||||
String: `ValList : Val << ast.NewValList(X[0]) >>`,
|
||||
Id: "ValList",
|
||||
NTType: 3,
|
||||
Index: 4,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewValList(X[0])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `ValList : ValList Val << >>`,
|
||||
String: `ValList : ValList Val << ast.AppendVal(X[0], X[1]) >>`,
|
||||
Id: "ValList",
|
||||
NTType: 3,
|
||||
Index: 5,
|
||||
NumSymbols: 2,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.AppendVal(X[0], X[1])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : string << >>`,
|
||||
String: `Val : raw_string << ast.NewStringVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 6,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewStringVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : number << >>`,
|
||||
String: `Val : interpreted_string << ast.NewIStringVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 7,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewIStringVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : name << >>`,
|
||||
String: `Val : rune << ast.NewRuneVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 8,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewRuneVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : Expr << >>`,
|
||||
String: `Val : int << ast.NewIntVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 9,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewIntVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Expr : "(" name Val Val ")" << >>`,
|
||||
String: `Val : float << ast.NewFloatVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 10,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return ast.NewFloatVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : imaginary << ast.NewComplexVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 11,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return ast.NewComplexVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : name << ast.NewNameVal(X[0].(*token.Token)) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 12,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return ast.NewNameVal(X[0].(*token.Token))
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Val : Expr << ast.NewExprVal(X[0]) >>`,
|
||||
Id: "Val",
|
||||
NTType: 4,
|
||||
Index: 13,
|
||||
NumSymbols: 1,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return ast.NewExprVal(X[0])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Expr : "(" name Val Val ")" << ast.NewExpr(X[1].(*token.Token), X[2], X[3]) >>`,
|
||||
Id: "Expr",
|
||||
NTType: 5,
|
||||
Index: 10,
|
||||
Index: 14,
|
||||
NumSymbols: 5,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewExpr(X[1].(*token.Token), X[2], X[3])
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Expr : "(" name Val ")" << >>`,
|
||||
String: `Expr : "(" name Val ")" << ast.NewExpr(X[1].(*token.Token), X[2], nil) >>`,
|
||||
Id: "Expr",
|
||||
NTType: 5,
|
||||
Index: 11,
|
||||
Index: 15,
|
||||
NumSymbols: 4,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewExpr(X[1].(*token.Token), X[2], nil)
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Expr : "(" name ")" << >>`,
|
||||
String: `Expr : "(" name ")" << ast.NewExpr(X[1].(*token.Token), nil, nil) >>`,
|
||||
Id: "Expr",
|
||||
NTType: 5,
|
||||
Index: 12,
|
||||
Index: 16,
|
||||
NumSymbols: 3,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.NewExpr(X[1].(*token.Token), nil, nil)
|
||||
},
|
||||
},
|
||||
ProdTabEntry{
|
||||
String: `Expr : "(" "." ValList ")" << >>`,
|
||||
String: `Expr : "(" "." ValList ")" << ast.ListExpr(X[2]) >>`,
|
||||
Id: "Expr",
|
||||
NTType: 5,
|
||||
Index: 13,
|
||||
Index: 17,
|
||||
NumSymbols: 4,
|
||||
ReduceFunc: func(X []Attrib, C interface{}) (Attrib, error) {
|
||||
return X[0], nil
|
||||
return ast.ListExpr(X[2])
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
29
schema/schema_test.go
Normal file
29
schema/schema_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
testSchema(t, "(test)\n ; test comment"+
|
||||
"(test a)\n"+
|
||||
"(test a b)\n"+
|
||||
"(test \"a\" \"b\")\n"+
|
||||
"(+ 0b1010 -0xDEAD_BEEF)\n"+
|
||||
"(. a b c d e f g)\n"+
|
||||
"(test (test1 \"hi\") (test2 \"hi 2\"))\n"+
|
||||
"(test (. \"awa\" `awawa` \"awawawa\" \"awawawawa\"))\n"+
|
||||
"(test \n `new\nline`)\n"+
|
||||
"(test (. 0x0.1Fp1 '\\t' 2i '\\u6767' '\\U0001F600' '\\x23' '\\043'))\n")
|
||||
}
|
||||
func TestInterpretString(t *testing.T) {
|
||||
testSchema(t, "(test \"\\\" \\\\v \\u6767 \\U0001F600 \\x23 \\043 \" `\\\\ \\t \\u6767 \\U0001F600 \\x23 \\043`)")
|
||||
}
|
||||
func testSchema(t *testing.T, test string) {
|
||||
schema, err := CreateSchema(test)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println(schema)
|
||||
}
|
||||
198
schema/token.go
198
schema/token.go
@@ -1,198 +0,0 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Token struct {
|
||||
Type TokenType
|
||||
Number int64
|
||||
Value string
|
||||
}
|
||||
|
||||
type TokenType uintptr
|
||||
|
||||
const (
|
||||
StringLiteralTokenType TokenType = iota
|
||||
NumberLiteralTokenType
|
||||
NameTokenType
|
||||
OpenParenTokenType
|
||||
CloseParenTokenType
|
||||
)
|
||||
|
||||
func (t *Token) String() string {
|
||||
switch t.Type {
|
||||
case StringLiteralTokenType:
|
||||
return fmt.Sprintf("[l'%s']", t.Value)
|
||||
case NumberLiteralTokenType:
|
||||
return fmt.Sprintf("[l%d]", t.Number)
|
||||
case NameTokenType:
|
||||
return fmt.Sprintf("[n'%s']", t.Value)
|
||||
case OpenParenTokenType:
|
||||
return fmt.Sprintf("[(%d]", t.Number)
|
||||
case CloseParenTokenType:
|
||||
return fmt.Sprintf("[%d)]", t.Number)
|
||||
}
|
||||
return fmt.Sprintf("[?'%s']", t.Value)
|
||||
}
|
||||
|
||||
func StringLiteralToken(Value string) *Token {
|
||||
return &Token{Type: StringLiteralTokenType, Value: Value}
|
||||
}
|
||||
|
||||
func NumberLiteralToken(Value string) *Token {
|
||||
number, err := strconv.ParseInt(Value, 0, 64)
|
||||
if err != nil {
|
||||
log.Panicf("failed to parse '%s' as number: %s", Value, err)
|
||||
}
|
||||
return &Token{Type: NumberLiteralTokenType, Number: number}
|
||||
}
|
||||
func NameToken(Name string) *Token {
|
||||
return &Token{Type: NameTokenType, Value: Name}
|
||||
}
|
||||
func OpenParenToken(Depth int) *Token {
|
||||
return &Token{Type: OpenParenTokenType, Number: int64(Depth)}
|
||||
}
|
||||
func CloseParenToken(Depth int) *Token {
|
||||
return &Token{Type: CloseParenTokenType, Number: int64(Depth)}
|
||||
}
|
||||
|
||||
// preprocess removes comments and newlines.
|
||||
func preprocess(in []byte) ([]byte, int) {
|
||||
lines := bytes.Split(in, []byte("\n"))
|
||||
var wg sync.WaitGroup
|
||||
length := len(lines)
|
||||
wg.Add(length)
|
||||
for n, l := range lines {
|
||||
go func(n int, l []byte) {
|
||||
defer wg.Done()
|
||||
quote := false // "
|
||||
grave := false // `
|
||||
|
||||
for i, c := range l {
|
||||
if c == '"' && !quote && !grave {
|
||||
quote = true
|
||||
}
|
||||
if c == '"' && quote && !grave {
|
||||
quote = false
|
||||
}
|
||||
if c == '`' && !quote && !grave {
|
||||
grave = true
|
||||
}
|
||||
if c == '`' && !quote && grave {
|
||||
grave = false
|
||||
}
|
||||
if c == ';' && !(quote || grave) {
|
||||
lines[n] = l[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}(n, l)
|
||||
}
|
||||
wg.Wait()
|
||||
return bytes.Join(lines, []byte(" ")), length
|
||||
}
|
||||
func Tokenize(s []byte) ([][]*Token, error) {
|
||||
s, _ = preprocess(s)
|
||||
var tokens = make([][]*Token, 0)
|
||||
statement := 0
|
||||
token := 0
|
||||
depth := 0
|
||||
literalbegin := -1
|
||||
namebegin := -1
|
||||
quote := false
|
||||
grave := false
|
||||
|
||||
for i, c := range s {
|
||||
if !quote && !grave {
|
||||
switch c {
|
||||
case '(':
|
||||
if depth == 0 {
|
||||
tokens = append(tokens, make([]*Token, 0))
|
||||
}
|
||||
tokens[statement] = append(tokens[statement], OpenParenToken(depth))
|
||||
depth++
|
||||
token++
|
||||
break
|
||||
case ')':
|
||||
if namebegin != -1 {
|
||||
tokens[statement] = append(tokens[statement], NameToken(string(s[namebegin:i])))
|
||||
namebegin = -1
|
||||
token++
|
||||
} else if literalbegin != -1 {
|
||||
tokens[statement] = append(tokens[statement], NumberLiteralToken(string(s[literalbegin:i])))
|
||||
token++
|
||||
literalbegin = -1
|
||||
}
|
||||
depth--
|
||||
if depth < 0 {
|
||||
return nil, errors.New(fmt.Sprintf("unexpected closing paren at [%d,%d]", statement, token))
|
||||
}
|
||||
tokens[statement] = append(tokens[statement], CloseParenToken(depth))
|
||||
token++
|
||||
if depth == 0 {
|
||||
statement++
|
||||
if statement >= len(tokens) {
|
||||
slices.Grow(tokens, 1)
|
||||
}
|
||||
}
|
||||
break
|
||||
case '"':
|
||||
literalbegin = i + 1
|
||||
quote = true
|
||||
break
|
||||
case '`':
|
||||
literalbegin = i + 1
|
||||
grave = true
|
||||
break
|
||||
case ' ':
|
||||
if namebegin != -1 {
|
||||
tokens[statement] = append(tokens[statement], NameToken(string(s[namebegin:i])))
|
||||
token++
|
||||
namebegin = -1
|
||||
} else if literalbegin != -1 {
|
||||
tokens[statement] = append(tokens[statement], NumberLiteralToken(string(s[literalbegin:i])))
|
||||
token++
|
||||
literalbegin = -1
|
||||
}
|
||||
break
|
||||
default:
|
||||
if namebegin == -1 && literalbegin == -1 {
|
||||
if isDigit(c) {
|
||||
literalbegin = i
|
||||
} else if isAllowedName(c) {
|
||||
namebegin = i
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if c == '"' && quote {
|
||||
tokens[statement] = append(tokens[statement], StringLiteralToken(string(s[literalbegin:i])))
|
||||
literalbegin = -1
|
||||
quote = false
|
||||
token++
|
||||
} else if c == '`' && grave {
|
||||
tokens[statement] = append(tokens[statement], StringLiteralToken(string(s[literalbegin:i])))
|
||||
literalbegin = -1
|
||||
grave = false
|
||||
token++
|
||||
}
|
||||
}
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
// isDigit checks if a character is a digit and therefore is allowed to be the start of a numeric literal.
|
||||
func isDigit(c byte) bool {
|
||||
return c >= '0' && c <= '9'
|
||||
}
|
||||
|
||||
// isAllowedName checks if a character is allowed to be the first character of a name.
|
||||
// Variable names beginning with a number or containing any of the reserved characters are forbidden.
|
||||
func isAllowedName(c byte) bool {
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || (c >= '*' && c <= '/') || (c >= ':' && c <= '@')
|
||||
}
|
||||
@@ -138,8 +138,12 @@ var TokMap = TokenMap{
|
||||
typeMap: []string{
|
||||
"INVALID",
|
||||
"␚",
|
||||
"string",
|
||||
"number",
|
||||
"raw_string",
|
||||
"interpreted_string",
|
||||
"rune",
|
||||
"int",
|
||||
"float",
|
||||
"imaginary",
|
||||
"name",
|
||||
"(",
|
||||
")",
|
||||
@@ -149,11 +153,15 @@ var TokMap = TokenMap{
|
||||
idMap: map[string]Type{
|
||||
"INVALID": 0,
|
||||
"␚": 1,
|
||||
"string": 2,
|
||||
"number": 3,
|
||||
"name": 4,
|
||||
"(": 5,
|
||||
")": 6,
|
||||
".": 7,
|
||||
"raw_string": 2,
|
||||
"interpreted_string": 3,
|
||||
"rune": 4,
|
||||
"int": 5,
|
||||
"float": 6,
|
||||
"imaginary": 7,
|
||||
"name": 8,
|
||||
"(": 9,
|
||||
")": 10,
|
||||
".": 11,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTokenize(t *testing.T) {
|
||||
in := "(test ; test comment\n" +
|
||||
"@test) ; test comment\n" +
|
||||
`(test "Hello World")` + "\n" +
|
||||
"; test comment 2\n" +
|
||||
"(+ 1 2)\n" +
|
||||
"(test `\"Hello world\"`)\n"
|
||||
want := "[(0][n'test'][n'@test'][0)]\n" +
|
||||
"[(0][n'test'][l'Hello World'][0)]\n" +
|
||||
"[(0][n'+'][l1][l2][0)]\n" +
|
||||
"[(0][n'test'][l'\"Hello world\"'][0)]\n"
|
||||
tokens, _ := Tokenize([]byte(in))
|
||||
var test strings.Builder
|
||||
|
||||
for _, statement := range tokens {
|
||||
for _, token := range statement {
|
||||
test.WriteString(token.String())
|
||||
}
|
||||
test.WriteString("\n")
|
||||
}
|
||||
if test.String() != want {
|
||||
t.Errorf("\ngot:\n%s\nwant:\n%s", test.String(), want)
|
||||
}
|
||||
}
|
||||
97
schema/util/util.go
Normal file
97
schema/util/util.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func InterpretString(in string) (string, error) {
|
||||
in = in[1 : len(in)-1]
|
||||
sb := strings.Builder{}
|
||||
s := []rune(in)
|
||||
for i := 0; i < len(s); {
|
||||
r := s[i]
|
||||
if r == '\\' {
|
||||
if i == len(s)-1 {
|
||||
return "", errors.New("illegal escape character")
|
||||
}
|
||||
switch s[i+1] {
|
||||
case 'a':
|
||||
sb.WriteRune('\a')
|
||||
i += 2
|
||||
break
|
||||
case 'b':
|
||||
sb.WriteRune('\b')
|
||||
i += 2
|
||||
break
|
||||
case 'f':
|
||||
sb.WriteRune('\f')
|
||||
i += 2
|
||||
break
|
||||
case 'n':
|
||||
sb.WriteRune('\n')
|
||||
i += 2
|
||||
break
|
||||
case 'r':
|
||||
sb.WriteRune('\r')
|
||||
i += 2
|
||||
break
|
||||
case 't':
|
||||
sb.WriteRune('\t')
|
||||
i += 2
|
||||
break
|
||||
case 'v':
|
||||
sb.WriteRune('\v')
|
||||
i += 2
|
||||
break
|
||||
case '\\':
|
||||
sb.WriteRune('\\')
|
||||
i += 2
|
||||
break
|
||||
case '"':
|
||||
sb.WriteRune('"')
|
||||
i += 2
|
||||
break
|
||||
case 'u':
|
||||
sub := s[i+2 : i+6]
|
||||
n, err := strconv.ParseInt(string(sub), 16, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sb.WriteRune(rune(n))
|
||||
i += 6
|
||||
case 'U':
|
||||
sub := s[i+2 : i+10]
|
||||
n, err := strconv.ParseInt(string(sub), 16, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sb.WriteRune(rune(n))
|
||||
i += 10
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
sub := s[i+1 : i+4]
|
||||
n, err := strconv.ParseInt(string(sub), 8, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sb.WriteRune(rune(n))
|
||||
i += 4
|
||||
case 'x':
|
||||
sub := s[i+2 : i+4]
|
||||
n, err := strconv.ParseInt(string(sub), 16, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sb.WriteRune(rune(n))
|
||||
i += 4
|
||||
default:
|
||||
return "", errors.New("could not parse escape character")
|
||||
}
|
||||
} else {
|
||||
sb.WriteRune(r)
|
||||
i++
|
||||
}
|
||||
}
|
||||
return sb.String(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user