Last active
August 29, 2015 14:16
-
-
Save seansawyer/6f1718829202b28c3bee to your computer and use it in GitHub Desktop.
Parboiled parser definition for Thrift IDL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.rsglab.chimpquery.consumer.thrift | |
import org.parboiled.scala._ | |
/** | |
* Parboiled parser definition for Thrift IDL | |
* @see https://thrift.apache.org/docs/idl | |
*/ | |
class ThriftIdl extends Parser { | |
/** | |
* [1] Document ::= Header* Definition* | |
*/ | |
def Document: Rule0 = rule { zeroOrMore(Header) ~ zeroOrMore(Definition) } | |
/** | |
* [2] Header ::= Include | CppInclude | Namespace | |
*/ | |
def Header = rule { Include | CppInclude | Namespace } | |
/** | |
* [3] Include ::= 'include' Literal | |
*/ | |
def Include = rule { "include" ~ Literal } | |
/** | |
* [4] CppInclude ::= 'cpp_include' Literal | |
*/ | |
def CppInclude = rule { "cpp_include" ~ Literal } | |
/** | |
* [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) | | |
* ( 'smalltalk.category' STIdentifier ) | | |
* ( 'smalltalk.prefix' Identifier ) ) | | |
* ( 'php_namespace' Literal ) | | |
* ( 'xsd_namespace' Literal ) | |
*/ | |
def Namespace = rule { ScopedNamespace | PhpNamespace | XsdNamespace } | |
def ScopedNamespace = rule { "namespace" ~ ScopeAndId} | |
def ScopeAndId = rule { GeneralScopeAndId | StCategoryScopeAndId | StPrefixScopeAndId } | |
def GeneralScopeAndId = rule { NamespaceScope ~ Identifier } | |
def StCategoryScopeAndId = rule { "smalltalk.category" ~ StIdentifier } | |
def StPrefixScopeAndId = rule { "smalltalk.prefix" ~ Identifier } | |
def PhpNamespace = rule { "php_namespace" ~ Literal } | |
def XsdNamespace = rule { "xsd_namespace" ~ Literal } | |
/** | |
* [6] NamespaceScope ::= '*' | 'cpp' | 'java' | 'py' | 'perl' | 'rb' | 'cocoa' | 'csharp' | |
*/ | |
def NamespaceScope = rule { "*" | "cpp" | "java" | "py" | "perl" | "rb" | "cocoa" | "csharp" } | |
/** | |
* [7] Definition ::= Const | Typedef | Enum | Senum | Struct | Union | Exception | Service | |
*/ | |
def Definition = rule { Const | Typedef | Enum | Senum | Struct | Union | Exception | Service } | |
/** | |
* [8] Const ::= 'const' FieldType Identifier '=' ConstValue ListSeparator? | |
*/ | |
def Const = rule { "const" ~ FieldType ~ Identifier ~ "=" ~ ConstValue ~ optional(ListSeparator) } | |
/** | |
* [9] Typedef ::= 'typedef' DefinitionType Identifier | |
*/ | |
def Typedef = rule { "typedef" ~ DefinitionType ~ Identifier } | |
/** | |
* [10] Enum ::= 'enum' Identifier '{' (Identifier ('=' IntConstant)? ListSeparator?)* '}' | |
*/ | |
def Enum = rule { "enum" ~ Identifier ~ "{" ~ zeroOrMore(EnumValue) ~ "}" } | |
def EnumValue = rule { Identifier ~ optional(EnumConst) ~ optional(ListSeparator) } | |
def EnumConst = rule { "=" ~ IntConstant } | |
/** | |
* [11] Senum ::= 'senum' Identifier '{' (Literal ListSeparator?)* '}' | |
*/ | |
def Senum = rule { "senum" ~ Identifier ~ "{" ~ zeroOrMore(SenumValue) ~ "}" } | |
def SenumValue = rule { Literal ~ optional(ListSeparator) } | |
/** | |
* [12] Struct ::= 'struct' Identifier 'xsd_all'? '{' Field* '}' | |
*/ | |
def Struct = rule { | |
"struct" ~ | |
Identifier ~ | |
optional("xsd_all") ~ | |
"{" ~ zeroOrMore(Field) ~ "}" | |
} | |
/** | |
* [13] Union ::= 'union' Identifier 'xsd_all'? '{' Field* '}' | |
*/ | |
def Union = rule { | |
"union" ~ | |
Identifier ~ | |
optional("xsd_all") ~ | |
"{" ~ zeroOrMore(Field) ~ "}" | |
} | |
/** | |
* [14] Exception ::= 'exception' Identifier '{' Field* '}' | |
*/ | |
def Exception = rule { | |
"exception" ~ | |
Identifier ~ | |
"{" ~ zeroOrMore(Field) ~ "}" | |
} | |
/** | |
* [15] Service ::= 'service' Identifier ( 'extends' Identifier )? '{' Function* '}' | |
*/ | |
def Service = rule { | |
"service" ~ | |
Identifier ~ | |
optional(Inheritance) ~ | |
"{" ~ zeroOrMore(Function) ~ "}" | |
} | |
def Inheritance = rule { "extends" ~ Identifier } | |
/** | |
* [16] Field ::= FieldID? FieldReq? FieldType Identifier ('= ConstValue)? XsdFieldOptions ListSeparator? | |
*/ | |
def Field: Rule0 = rule { | |
optional(FieldId) ~ | |
optional(FieldReq) ~ | |
FieldType ~ | |
Identifier ~ | |
optional("=" ~ ConstValue) ~ | |
XsdFieldOptions ~ | |
optional(ListSeparator) | |
} | |
/** | |
* [17] FieldID ::= IntConstant ':' | |
*/ | |
def FieldId = rule { IntConstant ~ ":" } | |
/** | |
* [18] FieldReq ::= 'required' | 'optional' | |
*/ | |
def FieldReq = rule { "required" | "optional" } | |
/** | |
* [19] XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs? | |
*/ | |
def XsdFieldOptions = rule { | |
optional("xsd_optional") ~ | |
optional("xsd_nillable") ~ | |
optional(XsdAttrs) | |
} | |
/** | |
* [20] XsdAttrs ::= 'xsd_attrs' '{' Field* '}' | |
*/ | |
def XsdAttrs = rule { "xsd_attrs" ~ "{" ~ zeroOrMore(Field) ~ "}" } | |
/** | |
* [21] Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator? | |
*/ | |
def Function = rule { | |
optional("oneway") ~ | |
FunctionType ~ | |
Identifier ~ | |
"(" ~ zeroOrMore(Field) ~ ")" ~ | |
optional(Throws) ~ optional(ListSeparator) | |
} | |
/** | |
* [22] FunctionType ::= FieldType | 'void' | |
*/ | |
def FunctionType = rule { FieldType | "void" } | |
/** | |
* [23] Throws ::= 'throws' '(' Field* ')' | |
*/ | |
def Throws = rule { "throws" ~ "(" ~ zeroOrMore(Field) ~ ")" } | |
/** | |
* [24] FieldType ::= Identifier | BaseType | ContainerType | |
*/ | |
def FieldType: Rule0 = rule { Identifier | BaseType | ContainerType } | |
/** | |
* [25] DefinitionType ::= BaseType | ContainerType | |
*/ | |
def DefinitionType = rule { BaseType | ContainerType } | |
/** | |
* [26] BaseType ::= 'bool' | 'byte' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist' | |
*/ | |
def BaseType = rule { "bool" | "byte" | "i16" | "i32" | "i64" | "double" | "string" | "binary" | "slist" } | |
/** | |
* [27] ContainerType ::= MapType | SetType | ListType | |
*/ | |
def ContainerType = rule { MapType | SetType | ListType } | |
/** | |
* [28] MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>' | |
*/ | |
def MapType = rule { "map" ~ optional(CppType) ~ "<" ~ FieldType ~ "," ~ FieldType ~ ">" } | |
/** | |
* [29] SetType ::= 'set' CppType? '<' FieldType '>' | |
*/ | |
def SetType = rule { "set" ~ optional(CppType) ~ "<" ~ FieldType ~ ">" } | |
/** | |
* [30] ListType ::= 'list' '<' FieldType '>' CppType? | |
*/ | |
def ListType = rule { "list" ~ "<" ~ FieldType ~ ">" ~ optional(CppType) } | |
/** | |
* [31] CppType ::= 'cpp_type' Literal | |
*/ | |
def CppType = rule { "cpp_type" ~ Literal } | |
/** | |
* [32] ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap | |
*/ | |
def ConstValue: Rule0 = rule { IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap } | |
/** | |
* [33] IntConstant ::= ('+' | '-')? Digit+ | |
*/ | |
def IntConstant = rule { MaybeSign ~ oneOrMore(Digit) } | |
def MaybeSign = rule { optional(anyOf("+-")) } | |
/** | |
* [34] DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )? | |
*/ | |
def DoubleConstant = rule { MaybeSign ~ oneOrMore(Digit) ~ MaybeDecimal ~ MaybeScientific } | |
def MaybeDecimal = rule { optional("." ~ oneOrMore(Digit)) } | |
def MaybeScientific = rule { optional(anyOf("Ee") ~ IntConstant) } | |
/** | |
* [35] ConstList ::= '[' (ConstValue ListSeparator?)* ']' | |
*/ | |
def ConstList = rule { "[" ~ zeroOrMore(ConstValue ~ optional(ListSeparator)) ~ "]" } | |
/** | |
* [36] ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}' | |
*/ | |
def ConstMap = rule { "{" ~ zeroOrMore(ConstMapEntry) ~ "}" } | |
def ConstMapEntry = rule { ConstValue ~ ":" ~ ConstValue ~ optional(ListSeparator) } | |
/** | |
* [37] Literal ::= ('"' [^"]* '"') | ("'" [^']* "'") | |
*/ | |
def Literal = rule { DoubleQuotedLiteral | SingleQuotedLiteral } | |
def DoubleQuotedLiteral = rule { "\"" ~ zeroOrMore(anyOf("^\"")) ~ "\"" } | |
def SingleQuotedLiteral = rule { "'" ~ zeroOrMore(anyOf("^'")) ~ "'" } | |
/** | |
* [38] Identifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' )* | |
*/ | |
def Identifier = rule { IdentStart ~ zeroOrMore(IdentChar) } | |
def IdentStart = rule { Letter | "_" } | |
def IdentChar = rule { Letter | Digit | "." | "_" } | |
/** | |
* [39] STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )* | |
*/ | |
def StIdentifier = rule { IdentStart ~ zeroOrMore(StIdentChar) } | |
def StIdentChar = rule { IdentChar | "-" } | |
/** | |
* [40] ListSeparator ::= ',' | ';' | |
*/ | |
def ListSeparator = rule { anyOf(",;") } | |
/** | |
* [41] Letter ::= ['A'-'Z'] | ['a'-'z'] | |
*/ | |
def Letter = rule { "A" - "Z" | "a" - "z" } | |
/** | |
* [42] Digit ::= ['0'-'9'] | |
*/ | |
def Digit = rule { "0" - "9" } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment