mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-08 08:52:26 +00:00
Project structure refactor:
- Change package name general_server to gateway - Changing the structure of directories and packages - Adding vendor to the project
This commit is contained in:
7
vendor/github.com/yuin/gopher-lua/parse/Makefile
generated
vendored
Normal file
7
vendor/github.com/yuin/gopher-lua/parse/Makefile
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
all : parser.go
|
||||
|
||||
parser.go : parser.go.y
|
||||
goyacc -o $@ parser.go.y; [ -f y.output ] && ( rm -f y.output )
|
||||
|
||||
clean:
|
||||
rm -f parser.go
|
||||
549
vendor/github.com/yuin/gopher-lua/parse/lexer.go
generated
vendored
Normal file
549
vendor/github.com/yuin/gopher-lua/parse/lexer.go
generated
vendored
Normal file
@@ -0,0 +1,549 @@
|
||||
package parse
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/yuin/gopher-lua/ast"
|
||||
)
|
||||
|
||||
const EOF = -1
|
||||
const whitespace1 = 1<<'\t' | 1<<' '
|
||||
const whitespace2 = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
|
||||
|
||||
type Error struct {
|
||||
Pos ast.Position
|
||||
Message string
|
||||
Token string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
pos := e.Pos
|
||||
if pos.Line == EOF {
|
||||
return fmt.Sprintf("%v at EOF: %s\n", pos.Source, e.Message)
|
||||
} else {
|
||||
return fmt.Sprintf("%v line:%d(column:%d) near '%v': %s\n", pos.Source, pos.Line, pos.Column, e.Token, e.Message)
|
||||
}
|
||||
}
|
||||
|
||||
func writeChar(buf *bytes.Buffer, c int) { buf.WriteByte(byte(c)) }
|
||||
|
||||
func isDecimal(ch int) bool { return '0' <= ch && ch <= '9' }
|
||||
|
||||
func isIdent(ch int, pos int) bool {
|
||||
return ch == '_' || 'A' <= ch && ch <= 'Z' || 'a' <= ch && ch <= 'z' || isDecimal(ch) && pos > 0
|
||||
}
|
||||
|
||||
func isDigit(ch int) bool {
|
||||
return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F'
|
||||
}
|
||||
|
||||
type Scanner struct {
|
||||
Pos ast.Position
|
||||
reader *bufio.Reader
|
||||
}
|
||||
|
||||
func NewScanner(reader io.Reader, source string) *Scanner {
|
||||
return &Scanner{
|
||||
Pos: ast.Position{
|
||||
Source: source,
|
||||
Line: 1,
|
||||
Column: 0,
|
||||
},
|
||||
reader: bufio.NewReaderSize(reader, 4096),
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *Scanner) Error(tok string, msg string) *Error { return &Error{sc.Pos, msg, tok} }
|
||||
|
||||
func (sc *Scanner) TokenError(tok ast.Token, msg string) *Error { return &Error{tok.Pos, msg, tok.Str} }
|
||||
|
||||
func (sc *Scanner) readNext() int {
|
||||
ch, err := sc.reader.ReadByte()
|
||||
if err == io.EOF {
|
||||
return EOF
|
||||
}
|
||||
return int(ch)
|
||||
}
|
||||
|
||||
func (sc *Scanner) Newline(ch int) {
|
||||
if ch < 0 {
|
||||
return
|
||||
}
|
||||
sc.Pos.Line += 1
|
||||
sc.Pos.Column = 0
|
||||
next := sc.Peek()
|
||||
if ch == '\n' && next == '\r' || ch == '\r' && next == '\n' {
|
||||
sc.reader.ReadByte()
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *Scanner) Next() int {
|
||||
ch := sc.readNext()
|
||||
switch ch {
|
||||
case '\n', '\r':
|
||||
sc.Newline(ch)
|
||||
ch = int('\n')
|
||||
case EOF:
|
||||
sc.Pos.Line = EOF
|
||||
sc.Pos.Column = 0
|
||||
default:
|
||||
sc.Pos.Column++
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
func (sc *Scanner) Peek() int {
|
||||
ch := sc.readNext()
|
||||
if ch != EOF {
|
||||
sc.reader.UnreadByte()
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
func (sc *Scanner) skipWhiteSpace(whitespace int64) int {
|
||||
ch := sc.Next()
|
||||
for ; whitespace&(1<<uint(ch)) != 0; ch = sc.Next() {
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
func (sc *Scanner) skipComments(ch int) error {
|
||||
// multiline comment
|
||||
if sc.Peek() == '[' {
|
||||
ch = sc.Next()
|
||||
if sc.Peek() == '[' || sc.Peek() == '=' {
|
||||
var buf bytes.Buffer
|
||||
if err := sc.scanMultilineString(sc.Next(), &buf); err != nil {
|
||||
return sc.Error(buf.String(), "invalid multiline comment")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
for {
|
||||
if ch == '\n' || ch == '\r' || ch < 0 {
|
||||
break
|
||||
}
|
||||
ch = sc.Next()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanIdent(ch int, buf *bytes.Buffer) error {
|
||||
writeChar(buf, ch)
|
||||
for isIdent(sc.Peek(), 1) {
|
||||
writeChar(buf, sc.Next())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanDecimal(ch int, buf *bytes.Buffer) error {
|
||||
writeChar(buf, ch)
|
||||
for isDecimal(sc.Peek()) {
|
||||
writeChar(buf, sc.Next())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanNumber(ch int, buf *bytes.Buffer) error {
|
||||
if ch == '0' { // octal
|
||||
if sc.Peek() == 'x' || sc.Peek() == 'X' {
|
||||
writeChar(buf, ch)
|
||||
writeChar(buf, sc.Next())
|
||||
hasvalue := false
|
||||
for isDigit(sc.Peek()) {
|
||||
writeChar(buf, sc.Next())
|
||||
hasvalue = true
|
||||
}
|
||||
if !hasvalue {
|
||||
return sc.Error(buf.String(), "illegal hexadecimal number")
|
||||
}
|
||||
return nil
|
||||
} else if sc.Peek() != '.' && isDecimal(sc.Peek()) {
|
||||
ch = sc.Next()
|
||||
}
|
||||
}
|
||||
sc.scanDecimal(ch, buf)
|
||||
if sc.Peek() == '.' {
|
||||
sc.scanDecimal(sc.Next(), buf)
|
||||
}
|
||||
if ch = sc.Peek(); ch == 'e' || ch == 'E' {
|
||||
writeChar(buf, sc.Next())
|
||||
if ch = sc.Peek(); ch == '-' || ch == '+' {
|
||||
writeChar(buf, sc.Next())
|
||||
}
|
||||
sc.scanDecimal(sc.Next(), buf)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanString(quote int, buf *bytes.Buffer) error {
|
||||
ch := sc.Next()
|
||||
for ch != quote {
|
||||
if ch == '\n' || ch == '\r' || ch < 0 {
|
||||
return sc.Error(buf.String(), "unterminated string")
|
||||
}
|
||||
if ch == '\\' {
|
||||
if err := sc.scanEscape(ch, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
writeChar(buf, ch)
|
||||
}
|
||||
ch = sc.Next()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanEscape(ch int, buf *bytes.Buffer) error {
|
||||
ch = sc.Next()
|
||||
switch ch {
|
||||
case 'a':
|
||||
buf.WriteByte('\a')
|
||||
case 'b':
|
||||
buf.WriteByte('\b')
|
||||
case 'f':
|
||||
buf.WriteByte('\f')
|
||||
case 'n':
|
||||
buf.WriteByte('\n')
|
||||
case 'r':
|
||||
buf.WriteByte('\r')
|
||||
case 't':
|
||||
buf.WriteByte('\t')
|
||||
case 'v':
|
||||
buf.WriteByte('\v')
|
||||
case '\\':
|
||||
buf.WriteByte('\\')
|
||||
case '"':
|
||||
buf.WriteByte('"')
|
||||
case '\'':
|
||||
buf.WriteByte('\'')
|
||||
case '\n':
|
||||
buf.WriteByte('\n')
|
||||
case '\r':
|
||||
buf.WriteByte('\n')
|
||||
sc.Newline('\r')
|
||||
default:
|
||||
if '0' <= ch && ch <= '9' {
|
||||
bytes := []byte{byte(ch)}
|
||||
for i := 0; i < 2 && isDecimal(sc.Peek()); i++ {
|
||||
bytes = append(bytes, byte(sc.Next()))
|
||||
}
|
||||
val, _ := strconv.ParseInt(string(bytes), 10, 32)
|
||||
writeChar(buf, int(val))
|
||||
} else {
|
||||
writeChar(buf, ch)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *Scanner) countSep(ch int) (int, int) {
|
||||
count := 0
|
||||
for ; ch == '='; count = count + 1 {
|
||||
ch = sc.Next()
|
||||
}
|
||||
return count, ch
|
||||
}
|
||||
|
||||
func (sc *Scanner) scanMultilineString(ch int, buf *bytes.Buffer) error {
|
||||
var count1, count2 int
|
||||
count1, ch = sc.countSep(ch)
|
||||
if ch != '[' {
|
||||
return sc.Error(string(rune(ch)), "invalid multiline string")
|
||||
}
|
||||
ch = sc.Next()
|
||||
if ch == '\n' || ch == '\r' {
|
||||
ch = sc.Next()
|
||||
}
|
||||
for {
|
||||
if ch < 0 {
|
||||
return sc.Error(buf.String(), "unterminated multiline string")
|
||||
} else if ch == ']' {
|
||||
count2, ch = sc.countSep(sc.Next())
|
||||
if count1 == count2 && ch == ']' {
|
||||
goto finally
|
||||
}
|
||||
buf.WriteByte(']')
|
||||
buf.WriteString(strings.Repeat("=", count2))
|
||||
continue
|
||||
}
|
||||
writeChar(buf, ch)
|
||||
ch = sc.Next()
|
||||
}
|
||||
|
||||
finally:
|
||||
return nil
|
||||
}
|
||||
|
||||
var reservedWords = map[string]int{
|
||||
"and": TAnd, "break": TBreak, "do": TDo, "else": TElse, "elseif": TElseIf,
|
||||
"end": TEnd, "false": TFalse, "for": TFor, "function": TFunction,
|
||||
"if": TIf, "in": TIn, "local": TLocal, "nil": TNil, "not": TNot, "or": TOr,
|
||||
"return": TReturn, "repeat": TRepeat, "then": TThen, "true": TTrue,
|
||||
"until": TUntil, "while": TWhile, "goto": TGoto}
|
||||
|
||||
func (sc *Scanner) Scan(lexer *Lexer) (ast.Token, error) {
|
||||
redo:
|
||||
var err error
|
||||
tok := ast.Token{}
|
||||
newline := false
|
||||
|
||||
ch := sc.skipWhiteSpace(whitespace1)
|
||||
if ch == '\n' || ch == '\r' {
|
||||
newline = true
|
||||
ch = sc.skipWhiteSpace(whitespace2)
|
||||
}
|
||||
|
||||
if ch == '(' && lexer.PrevTokenType == ')' {
|
||||
lexer.PNewLine = newline
|
||||
} else {
|
||||
lexer.PNewLine = false
|
||||
}
|
||||
|
||||
var _buf bytes.Buffer
|
||||
buf := &_buf
|
||||
tok.Pos = sc.Pos
|
||||
|
||||
switch {
|
||||
case isIdent(ch, 0):
|
||||
tok.Type = TIdent
|
||||
err = sc.scanIdent(ch, buf)
|
||||
tok.Str = buf.String()
|
||||
if err != nil {
|
||||
goto finally
|
||||
}
|
||||
if typ, ok := reservedWords[tok.Str]; ok {
|
||||
tok.Type = typ
|
||||
}
|
||||
case isDecimal(ch):
|
||||
tok.Type = TNumber
|
||||
err = sc.scanNumber(ch, buf)
|
||||
tok.Str = buf.String()
|
||||
default:
|
||||
switch ch {
|
||||
case EOF:
|
||||
tok.Type = EOF
|
||||
case '-':
|
||||
if sc.Peek() == '-' {
|
||||
err = sc.skipComments(sc.Next())
|
||||
if err != nil {
|
||||
goto finally
|
||||
}
|
||||
goto redo
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '"', '\'':
|
||||
tok.Type = TString
|
||||
err = sc.scanString(ch, buf)
|
||||
tok.Str = buf.String()
|
||||
case '[':
|
||||
if c := sc.Peek(); c == '[' || c == '=' {
|
||||
tok.Type = TString
|
||||
err = sc.scanMultilineString(sc.Next(), buf)
|
||||
tok.Str = buf.String()
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '=':
|
||||
if sc.Peek() == '=' {
|
||||
tok.Type = TEqeq
|
||||
tok.Str = "=="
|
||||
sc.Next()
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '~':
|
||||
if sc.Peek() == '=' {
|
||||
tok.Type = TNeq
|
||||
tok.Str = "~="
|
||||
sc.Next()
|
||||
} else {
|
||||
err = sc.Error("~", "Invalid '~' token")
|
||||
}
|
||||
case '<':
|
||||
if sc.Peek() == '=' {
|
||||
tok.Type = TLte
|
||||
tok.Str = "<="
|
||||
sc.Next()
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '>':
|
||||
if sc.Peek() == '=' {
|
||||
tok.Type = TGte
|
||||
tok.Str = ">="
|
||||
sc.Next()
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '.':
|
||||
ch2 := sc.Peek()
|
||||
switch {
|
||||
case isDecimal(ch2):
|
||||
tok.Type = TNumber
|
||||
err = sc.scanNumber(ch, buf)
|
||||
tok.Str = buf.String()
|
||||
case ch2 == '.':
|
||||
writeChar(buf, ch)
|
||||
writeChar(buf, sc.Next())
|
||||
if sc.Peek() == '.' {
|
||||
writeChar(buf, sc.Next())
|
||||
tok.Type = T3Comma
|
||||
} else {
|
||||
tok.Type = T2Comma
|
||||
}
|
||||
default:
|
||||
tok.Type = '.'
|
||||
}
|
||||
tok.Str = buf.String()
|
||||
case ':':
|
||||
if sc.Peek() == ':' {
|
||||
tok.Type = T2Colon
|
||||
tok.Str = "::"
|
||||
sc.Next()
|
||||
} else {
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
}
|
||||
case '+', '*', '/', '%', '^', '#', '(', ')', '{', '}', ']', ';', ',':
|
||||
tok.Type = ch
|
||||
tok.Str = string(rune(ch))
|
||||
default:
|
||||
writeChar(buf, ch)
|
||||
err = sc.Error(buf.String(), "Invalid token")
|
||||
goto finally
|
||||
}
|
||||
}
|
||||
|
||||
finally:
|
||||
tok.Name = TokenName(int(tok.Type))
|
||||
return tok, err
|
||||
}
|
||||
|
||||
// yacc interface {{{
|
||||
|
||||
type Lexer struct {
|
||||
scanner *Scanner
|
||||
Stmts []ast.Stmt
|
||||
PNewLine bool
|
||||
Token ast.Token
|
||||
PrevTokenType int
|
||||
}
|
||||
|
||||
func (lx *Lexer) Lex(lval *yySymType) int {
|
||||
lx.PrevTokenType = lx.Token.Type
|
||||
tok, err := lx.scanner.Scan(lx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if tok.Type < 0 {
|
||||
return 0
|
||||
}
|
||||
lval.token = tok
|
||||
lx.Token = tok
|
||||
return int(tok.Type)
|
||||
}
|
||||
|
||||
func (lx *Lexer) Error(message string) {
|
||||
panic(lx.scanner.Error(lx.Token.Str, message))
|
||||
}
|
||||
|
||||
func (lx *Lexer) TokenError(tok ast.Token, message string) {
|
||||
panic(lx.scanner.TokenError(tok, message))
|
||||
}
|
||||
|
||||
func Parse(reader io.Reader, name string) (chunk []ast.Stmt, err error) {
|
||||
lexer := &Lexer{NewScanner(reader, name), nil, false, ast.Token{Str: ""}, TNil}
|
||||
chunk = nil
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err, _ = e.(error)
|
||||
}
|
||||
}()
|
||||
yyParse(lexer)
|
||||
chunk = lexer.Stmts
|
||||
return
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// Dump {{{
|
||||
|
||||
func isInlineDumpNode(rv reflect.Value) bool {
|
||||
switch rv.Kind() {
|
||||
case reflect.Struct, reflect.Slice, reflect.Interface, reflect.Ptr:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func dump(node interface{}, level int, s string) string {
|
||||
rt := reflect.TypeOf(node)
|
||||
if fmt.Sprint(rt) == "<nil>" {
|
||||
return strings.Repeat(s, level) + "<nil>"
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(node)
|
||||
buf := []string{}
|
||||
switch rt.Kind() {
|
||||
case reflect.Slice:
|
||||
if rv.Len() == 0 {
|
||||
return strings.Repeat(s, level) + "<empty>"
|
||||
}
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
buf = append(buf, dump(rv.Index(i).Interface(), level, s))
|
||||
}
|
||||
case reflect.Ptr:
|
||||
vt := rv.Elem()
|
||||
tt := rt.Elem()
|
||||
indicies := []int{}
|
||||
for i := 0; i < tt.NumField(); i++ {
|
||||
if strings.Index(tt.Field(i).Name, "Base") > -1 {
|
||||
continue
|
||||
}
|
||||
indicies = append(indicies, i)
|
||||
}
|
||||
switch {
|
||||
case len(indicies) == 0:
|
||||
return strings.Repeat(s, level) + "<empty>"
|
||||
case len(indicies) == 1 && isInlineDumpNode(vt.Field(indicies[0])):
|
||||
for _, i := range indicies {
|
||||
buf = append(buf, strings.Repeat(s, level)+"- Node$"+tt.Name()+": "+dump(vt.Field(i).Interface(), 0, s))
|
||||
}
|
||||
default:
|
||||
buf = append(buf, strings.Repeat(s, level)+"- Node$"+tt.Name())
|
||||
for _, i := range indicies {
|
||||
if isInlineDumpNode(vt.Field(i)) {
|
||||
inf := dump(vt.Field(i).Interface(), 0, s)
|
||||
buf = append(buf, strings.Repeat(s, level+1)+tt.Field(i).Name+": "+inf)
|
||||
} else {
|
||||
buf = append(buf, strings.Repeat(s, level+1)+tt.Field(i).Name+": ")
|
||||
buf = append(buf, dump(vt.Field(i).Interface(), level+2, s))
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
buf = append(buf, strings.Repeat(s, level)+fmt.Sprint(node))
|
||||
}
|
||||
return strings.Join(buf, "\n")
|
||||
}
|
||||
|
||||
func Dump(chunk []ast.Stmt) string {
|
||||
return dump(chunk, 0, " ")
|
||||
}
|
||||
|
||||
// }}
|
||||
1383
vendor/github.com/yuin/gopher-lua/parse/parser.go
generated
vendored
Normal file
1383
vendor/github.com/yuin/gopher-lua/parse/parser.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
535
vendor/github.com/yuin/gopher-lua/parse/parser.go.y
generated
vendored
Normal file
535
vendor/github.com/yuin/gopher-lua/parse/parser.go.y
generated
vendored
Normal file
@@ -0,0 +1,535 @@
|
||||
%{
|
||||
package parse
|
||||
|
||||
import (
|
||||
"github.com/yuin/gopher-lua/ast"
|
||||
)
|
||||
%}
|
||||
%type<stmts> chunk
|
||||
%type<stmts> chunk1
|
||||
%type<stmts> block
|
||||
%type<stmt> stat
|
||||
%type<stmts> elseifs
|
||||
%type<stmt> laststat
|
||||
%type<funcname> funcname
|
||||
%type<funcname> funcname1
|
||||
%type<exprlist> varlist
|
||||
%type<expr> var
|
||||
%type<namelist> namelist
|
||||
%type<exprlist> exprlist
|
||||
%type<expr> expr
|
||||
%type<expr> string
|
||||
%type<expr> prefixexp
|
||||
%type<expr> functioncall
|
||||
%type<expr> afunctioncall
|
||||
%type<exprlist> args
|
||||
%type<expr> function
|
||||
%type<funcexpr> funcbody
|
||||
%type<parlist> parlist
|
||||
%type<expr> tableconstructor
|
||||
%type<fieldlist> fieldlist
|
||||
%type<field> field
|
||||
%type<fieldsep> fieldsep
|
||||
|
||||
%union {
|
||||
token ast.Token
|
||||
|
||||
stmts []ast.Stmt
|
||||
stmt ast.Stmt
|
||||
|
||||
funcname *ast.FuncName
|
||||
funcexpr *ast.FunctionExpr
|
||||
|
||||
exprlist []ast.Expr
|
||||
expr ast.Expr
|
||||
|
||||
fieldlist []*ast.Field
|
||||
field *ast.Field
|
||||
fieldsep string
|
||||
|
||||
namelist []string
|
||||
parlist *ast.ParList
|
||||
}
|
||||
|
||||
/* Reserved words */
|
||||
%token<token> TAnd TBreak TDo TElse TElseIf TEnd TFalse TFor TFunction TIf TIn TLocal TNil TNot TOr TReturn TRepeat TThen TTrue TUntil TWhile TGoto
|
||||
|
||||
/* Literals */
|
||||
%token<token> TEqeq TNeq TLte TGte T2Comma T3Comma T2Colon TIdent TNumber TString '{' '('
|
||||
|
||||
/* Operators */
|
||||
%left TOr
|
||||
%left TAnd
|
||||
%left '>' '<' TGte TLte TEqeq TNeq
|
||||
%right T2Comma
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right UNARY /* not # -(unary) */
|
||||
%right '^'
|
||||
|
||||
%%
|
||||
|
||||
chunk:
|
||||
chunk1 {
|
||||
$$ = $1
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.Stmts = $$
|
||||
}
|
||||
} |
|
||||
chunk1 laststat {
|
||||
$$ = append($1, $2)
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.Stmts = $$
|
||||
}
|
||||
} |
|
||||
chunk1 laststat ';' {
|
||||
$$ = append($1, $2)
|
||||
if l, ok := yylex.(*Lexer); ok {
|
||||
l.Stmts = $$
|
||||
}
|
||||
}
|
||||
|
||||
chunk1:
|
||||
{
|
||||
$$ = []ast.Stmt{}
|
||||
} |
|
||||
chunk1 stat {
|
||||
$$ = append($1, $2)
|
||||
} |
|
||||
chunk1 ';' {
|
||||
$$ = $1
|
||||
}
|
||||
|
||||
block:
|
||||
chunk {
|
||||
$$ = $1
|
||||
}
|
||||
|
||||
stat:
|
||||
varlist '=' exprlist {
|
||||
$$ = &ast.AssignStmt{Lhs: $1, Rhs: $3}
|
||||
$$.SetLine($1[0].Line())
|
||||
} |
|
||||
/* 'stat = functioncal' causes a reduce/reduce conflict */
|
||||
prefixexp {
|
||||
if _, ok := $1.(*ast.FuncCallExpr); !ok {
|
||||
yylex.(*Lexer).Error("parse error")
|
||||
} else {
|
||||
$$ = &ast.FuncCallStmt{Expr: $1}
|
||||
$$.SetLine($1.Line())
|
||||
}
|
||||
} |
|
||||
TDo block TEnd {
|
||||
$$ = &ast.DoBlockStmt{Stmts: $2}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($3.Pos.Line)
|
||||
} |
|
||||
TWhile expr TDo block TEnd {
|
||||
$$ = &ast.WhileStmt{Condition: $2, Stmts: $4}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($5.Pos.Line)
|
||||
} |
|
||||
TRepeat block TUntil expr {
|
||||
$$ = &ast.RepeatStmt{Condition: $4, Stmts: $2}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($4.Line())
|
||||
} |
|
||||
TIf expr TThen block elseifs TEnd {
|
||||
$$ = &ast.IfStmt{Condition: $2, Then: $4}
|
||||
cur := $$
|
||||
for _, elseif := range $5 {
|
||||
cur.(*ast.IfStmt).Else = []ast.Stmt{elseif}
|
||||
cur = elseif
|
||||
}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($6.Pos.Line)
|
||||
} |
|
||||
TIf expr TThen block elseifs TElse block TEnd {
|
||||
$$ = &ast.IfStmt{Condition: $2, Then: $4}
|
||||
cur := $$
|
||||
for _, elseif := range $5 {
|
||||
cur.(*ast.IfStmt).Else = []ast.Stmt{elseif}
|
||||
cur = elseif
|
||||
}
|
||||
cur.(*ast.IfStmt).Else = $7
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($8.Pos.Line)
|
||||
} |
|
||||
TFor TIdent '=' expr ',' expr TDo block TEnd {
|
||||
$$ = &ast.NumberForStmt{Name: $2.Str, Init: $4, Limit: $6, Stmts: $8}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($9.Pos.Line)
|
||||
} |
|
||||
TFor TIdent '=' expr ',' expr ',' expr TDo block TEnd {
|
||||
$$ = &ast.NumberForStmt{Name: $2.Str, Init: $4, Limit: $6, Step:$8, Stmts: $10}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($11.Pos.Line)
|
||||
} |
|
||||
TFor namelist TIn exprlist TDo block TEnd {
|
||||
$$ = &ast.GenericForStmt{Names:$2, Exprs:$4, Stmts: $6}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($7.Pos.Line)
|
||||
} |
|
||||
TFunction funcname funcbody {
|
||||
$$ = &ast.FuncDefStmt{Name: $2, Func: $3}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($3.LastLine())
|
||||
} |
|
||||
TLocal TFunction TIdent funcbody {
|
||||
$$ = &ast.LocalAssignStmt{Names:[]string{$3.Str}, Exprs: []ast.Expr{$4}}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($4.LastLine())
|
||||
} |
|
||||
TLocal namelist '=' exprlist {
|
||||
$$ = &ast.LocalAssignStmt{Names: $2, Exprs:$4}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TLocal namelist {
|
||||
$$ = &ast.LocalAssignStmt{Names: $2, Exprs:[]ast.Expr{}}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
T2Colon TIdent T2Colon {
|
||||
$$ = &ast.LabelStmt{Name: $2.Str}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TGoto TIdent {
|
||||
$$ = &ast.GotoStmt{Label: $2.Str}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
}
|
||||
|
||||
elseifs:
|
||||
{
|
||||
$$ = []ast.Stmt{}
|
||||
} |
|
||||
elseifs TElseIf expr TThen block {
|
||||
$$ = append($1, &ast.IfStmt{Condition: $3, Then: $5})
|
||||
$$[len($$)-1].SetLine($2.Pos.Line)
|
||||
}
|
||||
|
||||
laststat:
|
||||
TReturn {
|
||||
$$ = &ast.ReturnStmt{Exprs:nil}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TReturn exprlist {
|
||||
$$ = &ast.ReturnStmt{Exprs:$2}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TBreak {
|
||||
$$ = &ast.BreakStmt{}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
}
|
||||
|
||||
funcname:
|
||||
funcname1 {
|
||||
$$ = $1
|
||||
} |
|
||||
funcname1 ':' TIdent {
|
||||
$$ = &ast.FuncName{Func:nil, Receiver:$1.Func, Method: $3.Str}
|
||||
}
|
||||
|
||||
funcname1:
|
||||
TIdent {
|
||||
$$ = &ast.FuncName{Func: &ast.IdentExpr{Value:$1.Str}}
|
||||
$$.Func.SetLine($1.Pos.Line)
|
||||
} |
|
||||
funcname1 '.' TIdent {
|
||||
key:= &ast.StringExpr{Value:$3.Str}
|
||||
key.SetLine($3.Pos.Line)
|
||||
fn := &ast.AttrGetExpr{Object: $1.Func, Key: key}
|
||||
fn.SetLine($3.Pos.Line)
|
||||
$$ = &ast.FuncName{Func: fn}
|
||||
}
|
||||
|
||||
varlist:
|
||||
var {
|
||||
$$ = []ast.Expr{$1}
|
||||
} |
|
||||
varlist ',' var {
|
||||
$$ = append($1, $3)
|
||||
}
|
||||
|
||||
var:
|
||||
TIdent {
|
||||
$$ = &ast.IdentExpr{Value:$1.Str}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
prefixexp '[' expr ']' {
|
||||
$$ = &ast.AttrGetExpr{Object: $1, Key: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
prefixexp '.' TIdent {
|
||||
key := &ast.StringExpr{Value:$3.Str}
|
||||
key.SetLine($3.Pos.Line)
|
||||
$$ = &ast.AttrGetExpr{Object: $1, Key: key}
|
||||
$$.SetLine($1.Line())
|
||||
}
|
||||
|
||||
namelist:
|
||||
TIdent {
|
||||
$$ = []string{$1.Str}
|
||||
} |
|
||||
namelist ',' TIdent {
|
||||
$$ = append($1, $3.Str)
|
||||
}
|
||||
|
||||
exprlist:
|
||||
expr {
|
||||
$$ = []ast.Expr{$1}
|
||||
} |
|
||||
exprlist ',' expr {
|
||||
$$ = append($1, $3)
|
||||
}
|
||||
|
||||
expr:
|
||||
TNil {
|
||||
$$ = &ast.NilExpr{}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TFalse {
|
||||
$$ = &ast.FalseExpr{}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TTrue {
|
||||
$$ = &ast.TrueExpr{}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
TNumber {
|
||||
$$ = &ast.NumberExpr{Value: $1.Str}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
T3Comma {
|
||||
$$ = &ast.Comma3Expr{}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
function {
|
||||
$$ = $1
|
||||
} |
|
||||
prefixexp {
|
||||
$$ = $1
|
||||
} |
|
||||
string {
|
||||
$$ = $1
|
||||
} |
|
||||
tableconstructor {
|
||||
$$ = $1
|
||||
} |
|
||||
expr TOr expr {
|
||||
$$ = &ast.LogicalOpExpr{Lhs: $1, Operator: "or", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr TAnd expr {
|
||||
$$ = &ast.LogicalOpExpr{Lhs: $1, Operator: "and", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '>' expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: ">", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '<' expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "<", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr TGte expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: ">=", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr TLte expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "<=", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr TEqeq expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "==", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr TNeq expr {
|
||||
$$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "~=", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr T2Comma expr {
|
||||
$$ = &ast.StringConcatOpExpr{Lhs: $1, Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '+' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "+", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '-' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "-", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '*' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "*", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '/' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "/", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '%' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "%", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
expr '^' expr {
|
||||
$$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "^", Rhs: $3}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
'-' expr %prec UNARY {
|
||||
$$ = &ast.UnaryMinusOpExpr{Expr: $2}
|
||||
$$.SetLine($2.Line())
|
||||
} |
|
||||
TNot expr %prec UNARY {
|
||||
$$ = &ast.UnaryNotOpExpr{Expr: $2}
|
||||
$$.SetLine($2.Line())
|
||||
} |
|
||||
'#' expr %prec UNARY {
|
||||
$$ = &ast.UnaryLenOpExpr{Expr: $2}
|
||||
$$.SetLine($2.Line())
|
||||
}
|
||||
|
||||
string:
|
||||
TString {
|
||||
$$ = &ast.StringExpr{Value: $1.Str}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
}
|
||||
|
||||
prefixexp:
|
||||
var {
|
||||
$$ = $1
|
||||
} |
|
||||
afunctioncall {
|
||||
$$ = $1
|
||||
} |
|
||||
functioncall {
|
||||
$$ = $1
|
||||
} |
|
||||
'(' expr ')' {
|
||||
if ex, ok := $2.(*ast.Comma3Expr); ok {
|
||||
ex.AdjustRet = true
|
||||
}
|
||||
$$ = $2
|
||||
$$.SetLine($1.Pos.Line)
|
||||
}
|
||||
|
||||
afunctioncall:
|
||||
'(' functioncall ')' {
|
||||
$2.(*ast.FuncCallExpr).AdjustRet = true
|
||||
$$ = $2
|
||||
}
|
||||
|
||||
functioncall:
|
||||
prefixexp args {
|
||||
$$ = &ast.FuncCallExpr{Func: $1, Args: $2}
|
||||
$$.SetLine($1.Line())
|
||||
} |
|
||||
prefixexp ':' TIdent args {
|
||||
$$ = &ast.FuncCallExpr{Method: $3.Str, Receiver: $1, Args: $4}
|
||||
$$.SetLine($1.Line())
|
||||
}
|
||||
|
||||
args:
|
||||
'(' ')' {
|
||||
if yylex.(*Lexer).PNewLine {
|
||||
yylex.(*Lexer).TokenError($1, "ambiguous syntax (function call x new statement)")
|
||||
}
|
||||
$$ = []ast.Expr{}
|
||||
} |
|
||||
'(' exprlist ')' {
|
||||
if yylex.(*Lexer).PNewLine {
|
||||
yylex.(*Lexer).TokenError($1, "ambiguous syntax (function call x new statement)")
|
||||
}
|
||||
$$ = $2
|
||||
} |
|
||||
tableconstructor {
|
||||
$$ = []ast.Expr{$1}
|
||||
} |
|
||||
string {
|
||||
$$ = []ast.Expr{$1}
|
||||
}
|
||||
|
||||
function:
|
||||
TFunction funcbody {
|
||||
$$ = &ast.FunctionExpr{ParList:$2.ParList, Stmts: $2.Stmts}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($2.LastLine())
|
||||
}
|
||||
|
||||
funcbody:
|
||||
'(' parlist ')' block TEnd {
|
||||
$$ = &ast.FunctionExpr{ParList: $2, Stmts: $4}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($5.Pos.Line)
|
||||
} |
|
||||
'(' ')' block TEnd {
|
||||
$$ = &ast.FunctionExpr{ParList: &ast.ParList{HasVargs: false, Names: []string{}}, Stmts: $3}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
$$.SetLastLine($4.Pos.Line)
|
||||
}
|
||||
|
||||
parlist:
|
||||
T3Comma {
|
||||
$$ = &ast.ParList{HasVargs: true, Names: []string{}}
|
||||
} |
|
||||
namelist {
|
||||
$$ = &ast.ParList{HasVargs: false, Names: []string{}}
|
||||
$$.Names = append($$.Names, $1...)
|
||||
} |
|
||||
namelist ',' T3Comma {
|
||||
$$ = &ast.ParList{HasVargs: true, Names: []string{}}
|
||||
$$.Names = append($$.Names, $1...)
|
||||
}
|
||||
|
||||
|
||||
tableconstructor:
|
||||
'{' '}' {
|
||||
$$ = &ast.TableExpr{Fields: []*ast.Field{}}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
} |
|
||||
'{' fieldlist '}' {
|
||||
$$ = &ast.TableExpr{Fields: $2}
|
||||
$$.SetLine($1.Pos.Line)
|
||||
}
|
||||
|
||||
|
||||
fieldlist:
|
||||
field {
|
||||
$$ = []*ast.Field{$1}
|
||||
} |
|
||||
fieldlist fieldsep field {
|
||||
$$ = append($1, $3)
|
||||
} |
|
||||
fieldlist fieldsep {
|
||||
$$ = $1
|
||||
}
|
||||
|
||||
field:
|
||||
TIdent '=' expr {
|
||||
$$ = &ast.Field{Key: &ast.StringExpr{Value:$1.Str}, Value: $3}
|
||||
$$.Key.SetLine($1.Pos.Line)
|
||||
} |
|
||||
'[' expr ']' '=' expr {
|
||||
$$ = &ast.Field{Key: $2, Value: $5}
|
||||
} |
|
||||
expr {
|
||||
$$ = &ast.Field{Value: $1}
|
||||
}
|
||||
|
||||
fieldsep:
|
||||
',' {
|
||||
$$ = ","
|
||||
} |
|
||||
';' {
|
||||
$$ = ";"
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
func TokenName(c int) string {
|
||||
if c >= TAnd && c-TAnd < len(yyToknames) {
|
||||
if yyToknames[c-TAnd] != "" {
|
||||
return yyToknames[c-TAnd]
|
||||
}
|
||||
}
|
||||
return string([]byte{byte(c)})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user