Godep vendoring for external packages
This commit is contained in:
4
vendor/github.com/mattn/anko/parser/Makefile
generated
vendored
Normal file
4
vendor/github.com/mattn/anko/parser/Makefile
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
all : parser.go
|
||||
|
||||
parser.go : parser.go.y
|
||||
go tool yacc -o $@ parser.go.y
|
||||
530
vendor/github.com/mattn/anko/parser/lexer.go
generated
vendored
Normal file
530
vendor/github.com/mattn/anko/parser/lexer.go
generated
vendored
Normal file
@@ -0,0 +1,530 @@
|
||||
// Package parser implements parser for anko.
|
||||
package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattn/anko/ast"
|
||||
)
|
||||
|
||||
const (
|
||||
EOF = -1 // End of file.
|
||||
EOL = '\n' // End of line.
|
||||
)
|
||||
|
||||
// Error provides a convenient interface for handling runtime error.
|
||||
// It can be Error inteface with type cast which can call Pos().
|
||||
type Error struct {
|
||||
Message string
|
||||
Pos ast.Position
|
||||
Filename string
|
||||
Fatal bool
|
||||
}
|
||||
|
||||
// Error returns the error message.
|
||||
func (e *Error) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// Scanner stores informations for lexer.
|
||||
type Scanner struct {
|
||||
src []rune
|
||||
offset int
|
||||
lineHead int
|
||||
line int
|
||||
}
|
||||
|
||||
// opName is correction of operation names.
|
||||
var opName = map[string]int{
|
||||
"func": FUNC,
|
||||
"return": RETURN,
|
||||
"var": VAR,
|
||||
"throw": THROW,
|
||||
"if": IF,
|
||||
"for": FOR,
|
||||
"break": BREAK,
|
||||
"continue": CONTINUE,
|
||||
"in": IN,
|
||||
"else": ELSE,
|
||||
"new": NEW,
|
||||
"true": TRUE,
|
||||
"false": FALSE,
|
||||
"nil": NIL,
|
||||
"module": MODULE,
|
||||
"try": TRY,
|
||||
"catch": CATCH,
|
||||
"finally": FINALLY,
|
||||
"switch": SWITCH,
|
||||
"case": CASE,
|
||||
"default": DEFAULT,
|
||||
"go": GO,
|
||||
"chan": CHAN,
|
||||
"make": MAKE,
|
||||
}
|
||||
|
||||
// Init resets code to scan.
|
||||
func (s *Scanner) Init(src string) {
|
||||
s.src = []rune(src)
|
||||
}
|
||||
|
||||
// Scan analyses token, and decide identify or literals.
|
||||
func (s *Scanner) Scan() (tok int, lit string, pos ast.Position, err error) {
|
||||
retry:
|
||||
s.skipBlank()
|
||||
pos = s.pos()
|
||||
switch ch := s.peek(); {
|
||||
case isLetter(ch):
|
||||
lit, err = s.scanIdentifier()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if name, ok := opName[lit]; ok {
|
||||
tok = name
|
||||
} else {
|
||||
tok = IDENT
|
||||
}
|
||||
case isDigit(ch):
|
||||
tok = NUMBER
|
||||
lit, err = s.scanNumber()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case ch == '"':
|
||||
tok = STRING
|
||||
lit, err = s.scanString('"')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case ch == '\'':
|
||||
tok = STRING
|
||||
lit, err = s.scanString('\'')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case ch == '`':
|
||||
tok = STRING
|
||||
lit, err = s.scanRawString()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
default:
|
||||
switch ch {
|
||||
case EOF:
|
||||
tok = EOF
|
||||
case '#':
|
||||
for !isEOL(s.peek()) {
|
||||
s.next()
|
||||
}
|
||||
goto retry
|
||||
case '!':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '=':
|
||||
tok = NEQ
|
||||
lit = "!="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '=':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '=':
|
||||
tok = EQEQ
|
||||
lit = "=="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '+':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '+':
|
||||
tok = PLUSPLUS
|
||||
lit = "++"
|
||||
case '=':
|
||||
tok = PLUSEQ
|
||||
lit = "+="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '-':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '-':
|
||||
tok = MINUSMINUS
|
||||
lit = "--"
|
||||
case '=':
|
||||
tok = MINUSEQ
|
||||
lit = "-="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '*':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '*':
|
||||
tok = POW
|
||||
lit = "**"
|
||||
case '=':
|
||||
tok = MULEQ
|
||||
lit = "*="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '/':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '=':
|
||||
tok = DIVEQ
|
||||
lit = "/="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '>':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '=':
|
||||
tok = GE
|
||||
lit = ">="
|
||||
case '>':
|
||||
tok = SHIFTRIGHT
|
||||
lit = ">>"
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '<':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '-':
|
||||
tok = OPCHAN
|
||||
lit = "<-"
|
||||
case '=':
|
||||
tok = LE
|
||||
lit = "<="
|
||||
case '<':
|
||||
tok = SHIFTLEFT
|
||||
lit = "<<"
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '|':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '|':
|
||||
tok = OROR
|
||||
lit = "||"
|
||||
case '=':
|
||||
tok = OREQ
|
||||
lit = "|="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '&':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case '&':
|
||||
tok = ANDAND
|
||||
lit = "&&"
|
||||
case '=':
|
||||
tok = ANDEQ
|
||||
lit = "&="
|
||||
default:
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '.':
|
||||
s.next()
|
||||
if s.peek() == '.' {
|
||||
s.next()
|
||||
if s.peek() == '.' {
|
||||
tok = VARARG
|
||||
} else {
|
||||
err = fmt.Errorf(`syntax error "%s"`, "..")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
case '(', ')', ':', ';', '%', '?', '{', '}', ',', '[', ']', '^', '\n':
|
||||
s.next()
|
||||
if ch == '[' && s.peek() == ']' {
|
||||
s.next()
|
||||
if isLetter(s.peek()) {
|
||||
s.back()
|
||||
tok = ARRAYLIT
|
||||
lit = "[]"
|
||||
} else {
|
||||
s.back()
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
} else {
|
||||
s.back()
|
||||
tok = int(ch)
|
||||
lit = string(ch)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf(`syntax error "%s"`, string(ch))
|
||||
return
|
||||
}
|
||||
s.next()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// isLetter returns true if the rune is a letter for identity.
|
||||
func isLetter(ch rune) bool {
|
||||
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
|
||||
}
|
||||
|
||||
// isDigit returns true if the rune is a number.
|
||||
func isDigit(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9'
|
||||
}
|
||||
|
||||
// isHex returns true if the rune is a hex digits.
|
||||
func isHex(ch rune) bool {
|
||||
return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
|
||||
}
|
||||
|
||||
// isEOL returns true if the rune is at end-of-line or end-of-file.
|
||||
func isEOL(ch rune) bool {
|
||||
return ch == '\n' || ch == -1
|
||||
}
|
||||
|
||||
// isBlank returns true if the rune is empty character..
|
||||
func isBlank(ch rune) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\r'
|
||||
}
|
||||
|
||||
// peek returns current rune in the code.
|
||||
func (s *Scanner) peek() rune {
|
||||
if s.reachEOF() {
|
||||
return EOF
|
||||
}
|
||||
return s.src[s.offset]
|
||||
}
|
||||
|
||||
// next moves offset to next.
|
||||
func (s *Scanner) next() {
|
||||
if !s.reachEOF() {
|
||||
if s.peek() == '\n' {
|
||||
s.lineHead = s.offset + 1
|
||||
s.line++
|
||||
}
|
||||
s.offset++
|
||||
}
|
||||
}
|
||||
|
||||
// current returns the current offset.
|
||||
func (s *Scanner) current() int {
|
||||
return s.offset
|
||||
}
|
||||
|
||||
// offset sets the offset value.
|
||||
func (s *Scanner) set(o int) {
|
||||
s.offset = o
|
||||
}
|
||||
|
||||
// back moves back offset once to top.
|
||||
func (s *Scanner) back() {
|
||||
s.offset--
|
||||
}
|
||||
|
||||
// reachEOF returns true if offset is at end-of-file.
|
||||
func (s *Scanner) reachEOF() bool {
|
||||
return len(s.src) <= s.offset
|
||||
}
|
||||
|
||||
// pos returns the position of current.
|
||||
func (s *Scanner) pos() ast.Position {
|
||||
return ast.Position{Line: s.line + 1, Column: s.offset - s.lineHead + 1}
|
||||
}
|
||||
|
||||
// skipBlank moves position into non-black character.
|
||||
func (s *Scanner) skipBlank() {
|
||||
for isBlank(s.peek()) {
|
||||
s.next()
|
||||
}
|
||||
}
|
||||
|
||||
// scanIdentifier returns identifier begining at current position.
|
||||
func (s *Scanner) scanIdentifier() (string, error) {
|
||||
var ret []rune
|
||||
for {
|
||||
if !isLetter(s.peek()) && !isDigit(s.peek()) {
|
||||
break
|
||||
}
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
}
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// scanNumber returns number begining at current position.
|
||||
func (s *Scanner) scanNumber() (string, error) {
|
||||
var ret []rune
|
||||
ch := s.peek()
|
||||
ret = append(ret, ch)
|
||||
s.next()
|
||||
if ch == '0' && s.peek() == 'x' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
for isHex(s.peek()) {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
}
|
||||
} else {
|
||||
for isDigit(s.peek()) || s.peek() == '.' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
}
|
||||
if s.peek() == 'e' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
if isDigit(s.peek()) || s.peek() == '+' || s.peek() == '-' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
for isDigit(s.peek()) || s.peek() == '.' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
}
|
||||
}
|
||||
for isDigit(s.peek()) || s.peek() == '.' {
|
||||
ret = append(ret, s.peek())
|
||||
s.next()
|
||||
}
|
||||
}
|
||||
if isLetter(s.peek()) {
|
||||
return "", errors.New("identifier starts immediately after numeric literal")
|
||||
}
|
||||
}
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// scanRawString returns raw-string starting at current position.
|
||||
func (s *Scanner) scanRawString() (string, error) {
|
||||
var ret []rune
|
||||
for {
|
||||
s.next()
|
||||
if s.peek() == EOF {
|
||||
return "", errors.New("unexpected EOF")
|
||||
break
|
||||
}
|
||||
if s.peek() == '`' {
|
||||
s.next()
|
||||
break
|
||||
}
|
||||
ret = append(ret, s.peek())
|
||||
}
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// scanString returns string starting at current position.
|
||||
// This handles backslash escaping.
|
||||
func (s *Scanner) scanString(l rune) (string, error) {
|
||||
var ret []rune
|
||||
eos:
|
||||
for {
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case EOL:
|
||||
return "", errors.New("unexpected EOL")
|
||||
case EOF:
|
||||
return "", errors.New("unexpected EOF")
|
||||
case l:
|
||||
s.next()
|
||||
break eos
|
||||
case '\\':
|
||||
s.next()
|
||||
switch s.peek() {
|
||||
case 'b':
|
||||
ret = append(ret, '\b')
|
||||
continue
|
||||
case 'f':
|
||||
ret = append(ret, '\f')
|
||||
continue
|
||||
case 'r':
|
||||
ret = append(ret, '\r')
|
||||
continue
|
||||
case 'n':
|
||||
ret = append(ret, '\n')
|
||||
continue
|
||||
case 't':
|
||||
ret = append(ret, '\t')
|
||||
continue
|
||||
}
|
||||
ret = append(ret, s.peek())
|
||||
continue
|
||||
default:
|
||||
ret = append(ret, s.peek())
|
||||
}
|
||||
}
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
// Lexer provides inteface to parse codes.
|
||||
type Lexer struct {
|
||||
s *Scanner
|
||||
lit string
|
||||
pos ast.Position
|
||||
e error
|
||||
stmts []ast.Stmt
|
||||
}
|
||||
|
||||
// Lex scans the token and literals.
|
||||
func (l *Lexer) Lex(lval *yySymType) int {
|
||||
tok, lit, pos, err := l.s.Scan()
|
||||
if err != nil {
|
||||
l.e = &Error{Message: fmt.Sprintf("%s", err.Error()), Pos: pos, Fatal: true}
|
||||
}
|
||||
lval.tok = ast.Token{Tok: tok, Lit: lit}
|
||||
lval.tok.SetPosition(pos)
|
||||
l.lit = lit
|
||||
l.pos = pos
|
||||
return tok
|
||||
}
|
||||
|
||||
// Error sets parse error.
|
||||
func (l *Lexer) Error(msg string) {
|
||||
l.e = &Error{Message: msg, Pos: l.pos, Fatal: false}
|
||||
}
|
||||
|
||||
// Parser provides way to parse the code using Scanner.
|
||||
func Parse(s *Scanner) ([]ast.Stmt, error) {
|
||||
l := Lexer{s: s}
|
||||
if yyParse(&l) != 0 {
|
||||
return nil, l.e
|
||||
}
|
||||
return l.stmts, l.e
|
||||
}
|
||||
|
||||
// ParserSrc provides way to parse the code from source.
|
||||
func ParseSrc(src string) ([]ast.Stmt, error) {
|
||||
scanner := &Scanner{
|
||||
src: []rune(src),
|
||||
}
|
||||
return Parse(scanner)
|
||||
}
|
||||
1997
vendor/github.com/mattn/anko/parser/parser.go
generated
vendored
Normal file
1997
vendor/github.com/mattn/anko/parser/parser.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
705
vendor/github.com/mattn/anko/parser/parser.go.y
generated
vendored
Normal file
705
vendor/github.com/mattn/anko/parser/parser.go.y
generated
vendored
Normal file
@@ -0,0 +1,705 @@
|
||||
%{
|
||||
package parser
|
||||
|
||||
import (
|
||||
"github.com/mattn/anko/ast"
|
||||
)
|
||||
|
||||
%}
|
||||
|
||||
%type<compstmt> compstmt
|
||||
%type<stmts> stmts
|
||||
%type<stmt> stmt
|
||||
%type<stmt_if> stmt_if
|
||||
%type<stmt_default> stmt_default
|
||||
%type<stmt_case> stmt_case
|
||||
%type<stmt_cases> stmt_cases
|
||||
%type<typ> typ
|
||||
%type<expr> expr
|
||||
%type<exprs> exprs
|
||||
%type<expr_many> expr_many
|
||||
%type<expr_lets> expr_lets
|
||||
%type<expr_pair> expr_pair
|
||||
%type<expr_pairs> expr_pairs
|
||||
%type<expr_idents> expr_idents
|
||||
|
||||
%union{
|
||||
compstmt []ast.Stmt
|
||||
stmt_if ast.Stmt
|
||||
stmt_default ast.Stmt
|
||||
stmt_case ast.Stmt
|
||||
stmt_cases []ast.Stmt
|
||||
stmts []ast.Stmt
|
||||
stmt ast.Stmt
|
||||
typ ast.Type
|
||||
expr ast.Expr
|
||||
exprs []ast.Expr
|
||||
expr_many []ast.Expr
|
||||
expr_lets ast.Expr
|
||||
expr_pair ast.Expr
|
||||
expr_pairs []ast.Expr
|
||||
expr_idents []string
|
||||
tok ast.Token
|
||||
term ast.Token
|
||||
terms ast.Token
|
||||
opt_terms ast.Token
|
||||
}
|
||||
|
||||
%token<tok> IDENT NUMBER STRING ARRAY VARARG FUNC RETURN VAR THROW IF ELSE FOR IN EQEQ NEQ GE LE OROR ANDAND NEW TRUE FALSE NIL MODULE TRY CATCH FINALLY PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ BREAK CONTINUE PLUSPLUS MINUSMINUS POW SHIFTLEFT SHIFTRIGHT SWITCH CASE DEFAULT GO CHAN MAKE OPCHAN ARRAYLIT
|
||||
|
||||
%right '='
|
||||
%right '?' ':'
|
||||
%left OROR
|
||||
%left ANDAND
|
||||
%left IDENT
|
||||
%nonassoc EQEQ NEQ ','
|
||||
%left '>' GE '<' LE SHIFTLEFT SHIFTRIGHT
|
||||
|
||||
%left '+' '-' PLUSPLUS MINUSMINUS
|
||||
%left '*' '/' '%'
|
||||
%right UNARY
|
||||
|
||||
%%
|
||||
|
||||
compstmt : opt_terms
|
||||
{
|
||||
$$ = nil
|
||||
}
|
||||
| stmts opt_terms
|
||||
{
|
||||
$$ = $1
|
||||
}
|
||||
|
||||
stmts :
|
||||
{
|
||||
$$ = nil
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.stmts = $$
|
||||
}
|
||||
}
|
||||
| opt_terms stmt
|
||||
{
|
||||
$$ = []ast.Stmt{$2}
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.stmts = $$
|
||||
}
|
||||
}
|
||||
| stmts terms stmt
|
||||
{
|
||||
if $3 != nil {
|
||||
$$ = append($1, $3)
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.stmts = $$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stmt :
|
||||
VAR expr_idents '=' expr_many
|
||||
{
|
||||
$$ = &ast.VarStmt{Names: $2, Exprs: $4}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '=' expr
|
||||
{
|
||||
$$ = &ast.LetsStmt{Lhss: []ast.Expr{$1}, Operator: "=", Rhss: []ast.Expr{$3}}
|
||||
}
|
||||
| expr_many '=' expr_many
|
||||
{
|
||||
$$ = &ast.LetsStmt{Lhss: $1, Operator: "=", Rhss: $3}
|
||||
}
|
||||
| BREAK
|
||||
{
|
||||
$$ = &ast.BreakStmt{}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| CONTINUE
|
||||
{
|
||||
$$ = &ast.ContinueStmt{}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| RETURN exprs
|
||||
{
|
||||
$$ = &ast.ReturnStmt{Exprs: $2}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| THROW expr
|
||||
{
|
||||
$$ = &ast.ThrowStmt{Expr: $2}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| MODULE IDENT '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.ModuleStmt{Name: $2.Lit, Stmts: $4}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| stmt_if
|
||||
{
|
||||
$$ = $1
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FOR '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.LoopStmt{Stmts: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FOR IDENT IN expr '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.ForStmt{Var: $2.Lit, Value: $4, Stmts: $6}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FOR expr_lets ';' expr ';' expr '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.CForStmt{Expr1: $2, Expr2: $4, Expr3: $6, Stmts: $8}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FOR expr '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.LoopStmt{Expr: $2, Stmts: $4}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}' FINALLY '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8, Finally: $12}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| TRY '{' compstmt '}' CATCH '{' compstmt '}' FINALLY '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.TryStmt{Try: $3, Catch: $7, Finally: $11}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| TRY '{' compstmt '}' CATCH '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.TryStmt{Try: $3, Catch: $7}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| SWITCH expr '{' stmt_cases '}'
|
||||
{
|
||||
$$ = &ast.SwitchStmt{Expr: $2, Cases: $4}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr
|
||||
{
|
||||
$$ = &ast.ExprStmt{Expr: $1}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
|
||||
|
||||
stmt_if :
|
||||
stmt_if ELSE IF expr '{' compstmt '}'
|
||||
{
|
||||
$1.(*ast.IfStmt).ElseIf = append($1.(*ast.IfStmt).ElseIf, &ast.IfStmt{If: $4, Then: $6})
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| stmt_if ELSE '{' compstmt '}'
|
||||
{
|
||||
if $$.(*ast.IfStmt).Else != nil {
|
||||
yylex.Error("multiple else statement")
|
||||
} else {
|
||||
$$.(*ast.IfStmt).Else = append($$.(*ast.IfStmt).Else, $4...)
|
||||
}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| IF expr '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.IfStmt{If: $2, Then: $4, Else: nil}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
|
||||
stmt_cases :
|
||||
{
|
||||
$$ = []ast.Stmt{}
|
||||
}
|
||||
| opt_terms stmt_case
|
||||
{
|
||||
$$ = []ast.Stmt{$2}
|
||||
}
|
||||
| opt_terms stmt_default
|
||||
{
|
||||
$$ = []ast.Stmt{$2}
|
||||
}
|
||||
| stmt_cases stmt_case
|
||||
{
|
||||
$$ = append($1, $2)
|
||||
}
|
||||
| stmt_cases stmt_default
|
||||
{
|
||||
for _, stmt := range $1 {
|
||||
if _, ok := stmt.(*ast.DefaultStmt); ok {
|
||||
yylex.Error("multiple default statement")
|
||||
}
|
||||
}
|
||||
$$ = append($1, $2)
|
||||
}
|
||||
|
||||
stmt_case :
|
||||
CASE expr ':' opt_terms compstmt
|
||||
{
|
||||
$$ = &ast.CaseStmt{Expr: $2, Stmts: $5}
|
||||
}
|
||||
|
||||
stmt_default :
|
||||
DEFAULT ':' opt_terms compstmt
|
||||
{
|
||||
$$ = &ast.DefaultStmt{Stmts: $4}
|
||||
}
|
||||
|
||||
expr_pair :
|
||||
STRING ':' expr
|
||||
{
|
||||
$$ = &ast.PairExpr{Key: $1.Lit, Value: $3}
|
||||
}
|
||||
|
||||
expr_pairs :
|
||||
{
|
||||
$$ = []ast.Expr{}
|
||||
}
|
||||
| expr_pair
|
||||
{
|
||||
$$ = []ast.Expr{$1}
|
||||
}
|
||||
| expr_pairs ',' opt_terms expr_pair
|
||||
{
|
||||
$$ = append($1, $4)
|
||||
}
|
||||
|
||||
expr_idents :
|
||||
{
|
||||
$$ = []string{}
|
||||
}
|
||||
| IDENT
|
||||
{
|
||||
$$ = []string{$1.Lit}
|
||||
}
|
||||
| expr_idents ',' opt_terms IDENT
|
||||
{
|
||||
$$ = append($1, $4.Lit)
|
||||
}
|
||||
|
||||
expr_lets : expr_many '=' expr_many
|
||||
{
|
||||
$$ = &ast.LetsExpr{Lhss: $1, Operator: "=", Rhss: $3}
|
||||
}
|
||||
|
||||
expr_many :
|
||||
expr
|
||||
{
|
||||
$$ = []ast.Expr{$1}
|
||||
}
|
||||
| exprs ',' opt_terms expr
|
||||
{
|
||||
$$ = append($1, $4)
|
||||
}
|
||||
| exprs ',' opt_terms IDENT
|
||||
{
|
||||
$$ = append($1, &ast.IdentExpr{Lit: $4.Lit})
|
||||
}
|
||||
|
||||
typ : IDENT
|
||||
{
|
||||
$$ = ast.Type{Name: $1.Lit}
|
||||
}
|
||||
| typ '.' IDENT
|
||||
{
|
||||
$$ = ast.Type{Name: $1.Name + "." + $3.Lit}
|
||||
}
|
||||
|
||||
exprs :
|
||||
{
|
||||
$$ = nil
|
||||
}
|
||||
| expr
|
||||
{
|
||||
$$ = []ast.Expr{$1}
|
||||
}
|
||||
| exprs ',' opt_terms expr
|
||||
{
|
||||
$$ = append($1, $4)
|
||||
}
|
||||
| exprs ',' opt_terms IDENT
|
||||
{
|
||||
$$ = append($1, &ast.IdentExpr{Lit: $4.Lit})
|
||||
}
|
||||
|
||||
expr :
|
||||
IDENT
|
||||
{
|
||||
$$ = &ast.IdentExpr{Lit: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| NUMBER
|
||||
{
|
||||
$$ = &ast.NumberExpr{Lit: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| '-' expr %prec UNARY
|
||||
{
|
||||
$$ = &ast.UnaryExpr{Operator: "-", Expr: $2}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '!' expr %prec UNARY
|
||||
{
|
||||
$$ = &ast.UnaryExpr{Operator: "!", Expr: $2}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '^' expr %prec UNARY
|
||||
{
|
||||
$$ = &ast.UnaryExpr{Operator: "^", Expr: $2}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '&' IDENT %prec UNARY
|
||||
{
|
||||
$$ = &ast.AddrExpr{Expr: &ast.IdentExpr{Lit: $2.Lit}}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '&' expr '.' IDENT %prec UNARY
|
||||
{
|
||||
$$ = &ast.AddrExpr{Expr: &ast.MemberExpr{Expr: $2, Name: $4.Lit}}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '*' IDENT %prec UNARY
|
||||
{
|
||||
$$ = &ast.DerefExpr{Expr: &ast.IdentExpr{Lit: $2.Lit}}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| '*' expr '.' IDENT %prec UNARY
|
||||
{
|
||||
$$ = &ast.DerefExpr{Expr: &ast.MemberExpr{Expr: $2, Name: $4.Lit}}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| STRING
|
||||
{
|
||||
$$ = &ast.StringExpr{Lit: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| TRUE
|
||||
{
|
||||
$$ = &ast.ConstExpr{Value: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FALSE
|
||||
{
|
||||
$$ = &ast.ConstExpr{Value: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| NIL
|
||||
{
|
||||
$$ = &ast.ConstExpr{Value: $1.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '?' expr ':' expr
|
||||
{
|
||||
$$ = &ast.TernaryOpExpr{Expr: $1, Lhs: $3, Rhs: $5}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '.' IDENT
|
||||
{
|
||||
$$ = &ast.MemberExpr{Expr: $1, Name: $3.Lit}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FUNC '(' expr_idents ')' '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.FuncExpr{Args: $3, Stmts: $6}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FUNC '(' IDENT VARARG ')' '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.FuncExpr{Args: []string{$3.Lit}, Stmts: $7, VarArg: true}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FUNC IDENT '(' expr_idents ')' '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.FuncExpr{Name: $2.Lit, Args: $4, Stmts: $7}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| FUNC IDENT '(' IDENT VARARG ')' '{' compstmt '}'
|
||||
{
|
||||
$$ = &ast.FuncExpr{Name: $2.Lit, Args: []string{$4.Lit}, Stmts: $8, VarArg: true}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| '[' opt_terms exprs opt_terms ']'
|
||||
{
|
||||
$$ = &ast.ArrayExpr{Exprs: $3}
|
||||
if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
|
||||
}
|
||||
| '[' opt_terms exprs ',' opt_terms ']'
|
||||
{
|
||||
$$ = &ast.ArrayExpr{Exprs: $3}
|
||||
if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
|
||||
}
|
||||
| '{' opt_terms expr_pairs opt_terms '}'
|
||||
{
|
||||
mapExpr := make(map[string]ast.Expr)
|
||||
for _, v := range $3 {
|
||||
mapExpr[v.(*ast.PairExpr).Key] = v.(*ast.PairExpr).Value
|
||||
}
|
||||
$$ = &ast.MapExpr{MapExpr: mapExpr}
|
||||
if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
|
||||
}
|
||||
| '{' opt_terms expr_pairs ',' opt_terms '}'
|
||||
{
|
||||
mapExpr := make(map[string]ast.Expr)
|
||||
for _, v := range $3 {
|
||||
mapExpr[v.(*ast.PairExpr).Key] = v.(*ast.PairExpr).Value
|
||||
}
|
||||
$$ = &ast.MapExpr{MapExpr: mapExpr}
|
||||
if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
$$ = &ast.ParenExpr{SubExpr: $2}
|
||||
if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
|
||||
}
|
||||
| NEW IDENT '(' exprs ')'
|
||||
{
|
||||
$$ = &ast.NewExpr{Name: $2.Lit, SubExprs: $4}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '+' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "+", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '-' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "-", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '*' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "*", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '/' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "/", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '%' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "%", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr POW expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "**", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr SHIFTLEFT expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "<<", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr SHIFTRIGHT expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: ">>", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr EQEQ expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "==", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr NEQ expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "!=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '>' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: ">", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr GE expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: ">=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '<' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "<", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr LE expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "<=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr PLUSEQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "+=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr MINUSEQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "-=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr MULEQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "*=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr DIVEQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "/=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr ANDEQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "&=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr OREQ expr
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "|=", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr PLUSPLUS
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "++"}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr MINUSMINUS
|
||||
{
|
||||
$$ = &ast.AssocExpr{Lhs: $1, Operator: "--"}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '|' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "|", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr OROR expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "||", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "&", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr ANDAND expr
|
||||
{
|
||||
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "&&", Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| IDENT '(' exprs VARARG ')'
|
||||
{
|
||||
$$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3, VarArg: true}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| IDENT '(' exprs ')'
|
||||
{
|
||||
$$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| GO IDENT '(' exprs VARARG ')'
|
||||
{
|
||||
$$ = &ast.CallExpr{Name: $2.Lit, SubExprs: $4, VarArg: true, Go: true}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| GO IDENT '(' exprs ')'
|
||||
{
|
||||
$$ = &ast.CallExpr{Name: $2.Lit, SubExprs: $4, Go: true}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| expr '(' exprs VARARG ')'
|
||||
{
|
||||
$$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3, VarArg: true}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '(' exprs ')'
|
||||
{
|
||||
$$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| GO expr '(' exprs VARARG ')'
|
||||
{
|
||||
$$ = &ast.AnonCallExpr{Expr: $2, SubExprs: $4, VarArg: true, Go: true}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
| GO expr '(' exprs ')'
|
||||
{
|
||||
$$ = &ast.AnonCallExpr{Expr: $2, SubExprs: $4, Go: true}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| IDENT '[' expr ']'
|
||||
{
|
||||
$$ = &ast.ItemExpr{Value: &ast.IdentExpr{Lit: $1.Lit}, Index: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '[' expr ']'
|
||||
{
|
||||
$$ = &ast.ItemExpr{Value: $1, Index: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| IDENT '[' expr ':' expr ']'
|
||||
{
|
||||
$$ = &ast.SliceExpr{Value: &ast.IdentExpr{Lit: $1.Lit}, Begin: $3, End: $5}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr '[' expr ':' expr ']'
|
||||
{
|
||||
$$ = &ast.SliceExpr{Value: $1, Begin: $3, End: $5}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| MAKE '(' CHAN typ ')'
|
||||
{
|
||||
$$ = &ast.MakeChanExpr{Type: $4.Name, SizeExpr: nil}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| MAKE '(' CHAN typ ',' expr ')'
|
||||
{
|
||||
$$ = &ast.MakeChanExpr{Type: $4.Name, SizeExpr: $6}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| MAKE '(' ARRAYLIT typ ',' expr ')'
|
||||
{
|
||||
$$ = &ast.MakeArrayExpr{Type: $4.Name, LenExpr: $6}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| MAKE '(' ARRAYLIT typ ',' expr ',' expr ')'
|
||||
{
|
||||
$$ = &ast.MakeArrayExpr{Type: $4.Name, LenExpr: $6, CapExpr: $8}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| expr OPCHAN expr
|
||||
{
|
||||
$$ = &ast.ChanExpr{Lhs: $1, Rhs: $3}
|
||||
$$.SetPosition($1.Position())
|
||||
}
|
||||
| OPCHAN expr
|
||||
{
|
||||
$$ = &ast.ChanExpr{Rhs: $2}
|
||||
$$.SetPosition($2.Position())
|
||||
}
|
||||
|
||||
opt_terms : /* none */
|
||||
| terms
|
||||
;
|
||||
|
||||
|
||||
terms : term
|
||||
{
|
||||
}
|
||||
| terms term
|
||||
{
|
||||
}
|
||||
;
|
||||
|
||||
term : ';'
|
||||
{
|
||||
}
|
||||
| '\n'
|
||||
{
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
Reference in New Issue
Block a user