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.
73 lines
2.6 KiB
Plaintext
73 lines
2.6 KiB
Plaintext
4 years ago
|
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? returnToken=ID? response=replybody?;
|
||
|
body: lp='(' (ID)? rp=')';
|
||
|
replybody: lp='(' dataType? rp=')';
|
||
|
// kv
|
||
|
kvLit: key=ID {checkKeyValue(p)}value=LINE_VALUE;
|
||
|
|
||
|
serviceName: (ID '-'?)+;
|
||
|
path: (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+;
|