blob: e3d62f94550f9abe438d8cb813d8915b5fa816ba [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import (
"android.googlesource.com/platform/tools/gpu/api/ast"
"android.googlesource.com/platform/tools/gpu/parse"
)
func identifier(p *parse.Parser, cst *parse.Branch) *ast.Identifier {
if !p.AlphaNumeric() {
return nil
}
n := &ast.Identifier{}
p.ParseLeaf(cst, func(p *parse.Parser, l *parse.Leaf) {
n.CST = l
l.SetToken(p.Consume())
n.Value = l.Token().String()
})
return n
}
func requireIdentifier(p *parse.Parser, cst *parse.Branch) *ast.Identifier {
n := identifier(p, cst)
if n == nil {
p.Expected("Identifier")
}
return n
}
// name '!' ( type | '(' type [ ',' type ] ')' )
func generic(p *parse.Parser, cst *parse.Branch) *ast.Generic {
i := identifier(p, cst)
if i == nil {
return nil
}
g := &ast.Generic{Name: i}
p.ParseBranch(cst, func(p *parse.Parser, cst *parse.Branch) {
g.CST = cst
if operator(ast.OpGeneric, p, cst) {
if operator(ast.OpListStart, p, cst) {
for !operator(ast.OpListEnd, p, cst) {
if len(g.Arguments) > 0 {
requireOperator(ast.OpListSeparator, p, cst)
}
g.Arguments = append(g.Arguments, requireTypeRef(p, cst))
}
} else {
g.Arguments = append(g.Arguments, requireTypeRef(p, cst))
}
}
})
return g
}
func requireGeneric(p *parse.Parser, cst *parse.Branch) *ast.Generic {
n := generic(p, cst)
if n == nil {
p.Expected("generic identifier")
}
return n
}
func peekKeyword(k string, p *parse.Parser) bool {
if !p.AlphaNumeric() {
return false
}
if p.Token().String() != string(k) {
p.Rollback()
return false
}
p.Rollback()
return true
}
func keyword(k string, p *parse.Parser, cst *parse.Branch) *parse.Leaf {
if !p.AlphaNumeric() {
return nil
}
if p.Token().String() != string(k) {
p.Rollback()
return nil
}
var result *parse.Leaf
p.ParseLeaf(cst, func(p *parse.Parser, l *parse.Leaf) {
result = l
})
return result
}
func requireKeyword(k string, p *parse.Parser, cst *parse.Branch) {
if keyword(k, p, cst) == nil {
p.Expected(string(k))
}
}