Created
September 4, 2013 18:07
-
-
Save sritchie/6440578 to your computer and use it in GitHub Desktop.
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
// First pass at a thrift parser using instaparse: | |
(def instagram | |
(insta/parser | |
" | |
Document ::= <ws> Header* Definition* | |
SlashComment ::= <'//'> #'[^\n]'* | |
PoundComment ::= <'#'> #'[^\n]'* | |
BlockComment ::= '/*' #'(?s).'* '*/' | |
Comment ::= SlashComment | PoundComment | BlockComment | <ws> | |
ws ::= <[#'\\s*']> | (Comment <ws>) | |
Header ::= (Include | CppInclude | Namespace) | |
Include ::= <'include'> <ws> Literal <ws> | |
CppInclude ::= <'cpp_include'> <ws> Literal <ws> | |
Namespace ::= (( <'namespace'> <ws> ( NamespaceScope Identifier ) | | |
( <'smalltalk.category'> <ws> STIdentifier ) | | |
( <'smalltalk.prefix'> <ws> Identifier ) ) | | |
( <'php_namespace'> <ws> Literal ) | | |
( <'xsd_namespace'> <ws> Literal )) <ws> | |
NamespaceScope ::= ('*' | 'cpp' | 'java' | 'py' | 'perl' | 'rb' | 'cocoa' | 'csharp' | 'clojure') <ws> | |
Definition ::= (Const | Typedef | Enum | Senum | Struct | Exception | Service) <ws> | |
Const ::= <'const'> <ws> FieldType Identifier <'='> <ws> ConstValue ListSeparator? | |
Typedef ::= <'typedef'> <ws> DefinitionType Identifier | |
Enum ::= <'enum'> <ws> Identifier <'{'> <ws> (EnumEntry | DefaultEntry)* <ws> <'}'> | |
EnumEntry ::= Identifier <ListSeparator?> | |
DefaultEntry ::= Identifier DefaultValue <ListSeparator?> | |
DefaultValue ::= <'='> <ws> IntConstant <ws> | |
Senum ::= <'senum'> <ws> Identifier <'{'> (Literal ListSeparator?)* <'}'> | |
Struct ::= <'struct'> <ws> Identifier <ws> ('xsd_all'? | <ws>) <'{'> (<ws> Field <ws>)* <'}'> | |
Exception ::= <'exception'> <ws> Identifier <'{'> (<ws> Field)* <'}'> | |
Service ::= <'service'> <ws> Identifier ( <'extends'> <ws> Identifier )? <'{'> (<ws> Function <ws>)* <'}'> | |
Field ::= FieldID <ws> FieldReq? <ws> FieldType <ws> Identifier <ws> ('=' <ws> ConstValue)? <ws> XsdFieldOptions <ws> <ListSeparator>? <ws> | |
FieldID ::= (IntConstant <ws> <':'>) <ws> | |
FieldReq ::= ('required' | 'optional') <ws> | |
XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs? | |
XsdAttrs ::= 'xsd_attrs' '{' Field* '}' | |
Function ::= <('oneway' ws)?> FunctionType Identifier '(' Field* ')' Throws? ListSeparator? | |
FunctionType ::= FieldType | 'void' | |
Throws ::= 'throws' '(' Field* ')' | |
FieldType ::= Identifier | BaseType | ContainerType | |
DefinitionType ::= BaseType | ContainerType | |
BaseType ::= ('bool' | 'byte' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist') <ws> | |
ContainerType ::= MapType | SetType | ListType | |
MapType ::= <'map'> <ws> CppType? <'<'> <ws> FieldType <','> FieldType <'>'> <ws> | |
SetType ::= <'set'> <ws> CppType? <'<'> FieldType <'>'> <ws> | |
ListType ::= <'list'> <ws> <'<'> FieldType <'>'> CppType? <ws> | |
CppType ::= <'cpp_type'> <ws> Literal | |
ConstValue ::= (IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap) | |
IntConstant ::= ('+' | '-')? Digit+ <ws> | |
DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )? <ws> | |
ConstList ::= <'['> (ConstValue ListSeparator?)* <']'> <ws> | |
ConstMap ::= <'{'> (ConstValue <':'> ConstValue <ListSeparator>?)* <'}'> <ws> | |
Literal ::= ((<'\\\"'> #'[^\"]+'* <'\\\"'>) | (<\"'\"> #'[^\\']+'* <\"'\">)) <ws> | |
Identifier ::= (( Letter | '_' ) ( Letter | Digit | '.' | '_' )*) <ws> | |
STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )* <ws> | |
ListSeparator ::= (',' | ';') <ws> | |
<Letter> ::= #'[a-zA-Z]' | |
<Digit> ::= #'[0-9]'")) | |
// And the test. Enums are still busted. | |
(def forma | |
"/** | |
* Just some comment nastiness. // nested line. | |
* | |
* | |
*/ | |
// And more comments by me. | |
# Bullshit. | |
// include \"DOESNTEXIST.thrift\" | |
include \"face.thrift\" | |
cpp_include \"boggle.thrift\" | |
namespace clojure forma.schema | |
namespace rb forma.schema | |
/** | |
* Thrift lets you do typedefs to get pretty names for your types. Standard | |
* C style here. | |
*/ | |
typedef i32 MyInteger | |
/** | |
* Thrift also lets you define constants for use across languages. Complex | |
* types and structs are specified using JSON notation. | |
*/ | |
const i32 INT32CONSTANT = 9853 | |
struct /* random whitespace */ FireValue { | |
1: i32 temp330; | |
2: i32 conf50; | |
3: i32 bothPreds; | |
4: i32 count; | |
} | |
enum Operation { | |
ADD, | |
SUBTRACT = 2, | |
MULTIPLY // should have a value of 3 | |
DIVIDE = 4 | |
} | |
/** | |
* Structs can also be exceptions, if they are nasty. | |
*/ | |
exception InvalidOperation { | |
1: i32 what, | |
2: string why | |
} | |
service Calculator extends face.SharedService { | |
/** | |
* A method definition looks like C code. It has a return type, arguments, | |
* and optionally a list of exceptions that it may throw. Note that argument | |
* lists and exception lists are specified using the exact same syntax as | |
* field lists in struct or exception definitions. NOTE: Overloading of | |
* methods is not supported; each method requires a unique name. | |
*/ | |
void ping(), | |
i32 add(1:i32 num1, 2:i32 num2), | |
i32 calculate(1:i32 logid, 2:FireValue fv) throws (1:InvalidOperation ouch), | |
/** | |
* This method has an oneway modifier. That means the client only makes | |
* a request and does not listen for any response at all. Oneway methods | |
* must be void. | |
* | |
* The server may execute async invocations of the same client in parallel/ | |
* out of order. | |
*/ | |
oneway void zip(), | |
} | |
struct FormaValue { | |
1: FireValue fireValue; | |
2: double shortDrop; | |
3: double longDrop; | |
4: double tStat; | |
5: optional double paramBreak; | |
} | |
") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment