Skip to content

Instantly share code, notes, and snippets.

@seansawyer
Last active August 29, 2015 14:16
Show Gist options
  • Save seansawyer/6f1718829202b28c3bee to your computer and use it in GitHub Desktop.
Save seansawyer/6f1718829202b28c3bee to your computer and use it in GitHub Desktop.
Parboiled parser definition for Thrift IDL
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