You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/tools/goctl/api/parser/g4/ApiParser.g4

73 lines
2.6 KiB
Plaintext

grammar ApiParser;
import ApiLexer;
@lexer::members{
const COMEMNTS = 88
}
api: spec*;
spec: syntaxLit
|importSpec
|infoSpec
|typeSpec
|serviceSpec
;
// syntax
syntaxLit: {match(p,"syntax")}syntaxToken=ID assign='=' {checkVersion(p)}version=STRING;
// import
importSpec: importLit|importBlock;
importLit: {match(p,"import")}importToken=ID importValue ;
importBlock: {match(p,"import")}importToken=ID '(' importBlockValue+ ')';
importBlockValue: importValue;
importValue: {checkImportValue(p)}STRING;
// info
infoSpec: {match(p,"info")}infoToken=ID lp='(' kvLit+ rp=')';
// type
typeSpec: typeLit
|typeBlock;
// eg: type Foo int
typeLit: {match(p,"type")}typeToken=ID typeLitBody;
// eg: type (...)
typeBlock: {match(p,"type")}typeToken=ID lp='(' typeBlockBody* rp=')';
typeLitBody: typeStruct|typeAlias;
typeBlockBody: typeBlockStruct|typeBlockAlias;
typeStruct: {checkKeyword(p)}structName=ID structToken=ID? lbrace='{' field* rbrace='}';
typeAlias: {checkKeyword(p)}alias=ID assign='='? dataType;
typeBlockStruct: {checkKeyword(p)}structName=ID structToken=ID? lbrace='{' field* rbrace='}';
typeBlockAlias: {checkKeyword(p)}alias=ID assign='='? dataType;
field: {isNormal(p)}? normalField|anonymousFiled ;
normalField: {checkKeyword(p)}fieldName=ID dataType tag=RAW_STRING?;
anonymousFiled: star='*'? ID;
dataType: {isInterface(p)}ID
|mapType
|arrayType
|inter='interface{}'
|time='time.Time'
|pointerType
|typeStruct
;
pointerType: star='*' {checkKeyword(p)}ID;
mapType: {match(p,"map")}mapToken=ID lbrack='[' {checkKey(p)}key=ID rbrack=']' value=dataType;
arrayType: lbrack='[' rbrack=']' dataType;
// service
serviceSpec: atServer? serviceApi;
atServer: ATSERVER lp='(' kvLit+ rp=')';
serviceApi: {match(p,"service")}serviceToken=ID serviceName lbrace='{' serviceRoute* rbrace='}';
serviceRoute: atDoc? (atServer|atHandler) route;
atDoc: ATDOC lp='('? ((kvLit+)|STRING) rp=')'?;
atHandler: ATHANDLER ID;
route: {checkHTTPMethod(p)}httpMethod=ID path request=body? response=replybody?;
body: lp='(' (ID)? rp=')';
replybody: returnToken='returns' lp='(' dataType? rp=')';
// kv
kvLit: key=ID {checkKeyValue(p)}value=LINE_VALUE;
serviceName: (ID '-'?)+;
path: (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+ | '/';