# # This file is derived from # https://raw.githubusercontent.com/samuel/go-thrift/master/parser/grammar.peg # (commit id: 586f6174a55deba8cbe982f15ecc28a901e44f4a) # # Reference: # - https://thrift.apache.org/docs/idl # - https://diwakergupta.github.io/thrift-missing-guide/ # # # Copyright (c) 2012, Samuel Stauffer # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the author nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # %prefix "pthrift" %auxil "struct parserCtx *" %earlysource { #include "general.h" } %header { struct parserCtx; } %source { #include "thrift_pre.h" #include "routines.h" } Grammar <- __ ( Statement __ )* (EOF / SyntaxError) SyntaxError <- . # MODIFIED Include <- <( "include" / "cpp_include" )> _ EOS { vString *f = unliteral ($2); if (vStringLength(f) > 0) { if ($1[0] == 'i') makeThriftTagFull (auxil, vStringValue (f), $2s, K_THRIFTFILE, THRIFT_THRIFT_FILE_INCLUDED, false); else { tagEntryInfo e; initForeignRefTagEntry (&e, vStringValue(f), getNamedLanguage ("C++", 0), CXXTagKindINCLUDE, CR_HEADER_LOCAL); e.lineNumber = getInputLineNumberForFileOffset ($2s); e.filePosition = getInputFilePositionForLine (e.lineNumber); makeTagEntry (&e); } } vStringDelete (f); } Statement <- Include / Namespace / Const / Enum / TypeDef / Struct / Exception / Union / Service Namespace <- "namespace" _ <[-*a-z.]+> _ { int r = makeThriftTag (auxil, $2, $2s, K_NAMESPACE, false); attachParserFieldToCorkEntry (r, ThriftFields[F_TARGET].ftype, $1); } EOS Const <- "const" _ _ { int r = makeThriftTag (auxil, $2, $2s, K_CONST, false); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) { e->extensionFields.typeRef[0] = eStrdup ("typename"); e->extensionFields.typeRef[1] = eStrdup ($1); } } __ "=" __ ConstValue _ ListSeparator? EOS # MODIFIED Enum <- "enum" { PUSH_KIND (auxil, K_ENUM); } _ { makeThriftTag (auxil, $1, $1s, USE_KIND_STACK, true); } __ '{' __ (EnumValue __)* '}' _ TypeAnnotations? EOS { POP_KIND (auxil, true); } EnumValue <- { makeThriftTag (auxil, $1, $1s, K_ENUMERATOR, false); } _ ('=' _ IntConstant)? _ TypeAnnotations? ListSeparator? TypeDef <- "typedef" _ _ { int r = makeThriftTag (auxil, $2, $2s, K_TYPEDEF, false); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) { e->extensionFields.typeRef[0] = eStrdup ("typename"); e->extensionFields.typeRef[1] = eStrdup ($1); } } _ TypeAnnotations? EOS Struct <- "struct" { PUSH_KIND (auxil, K_STRUCT); }_ StructLike { POP_KIND (auxil, true); } Exception <- "exception" { PUSH_KIND (auxil, K_EXCEPTION); } _ StructLike { POP_KIND (auxil, true); } Union <- "union" { PUSH_KIND (auxil, K_UNION); } _ StructLike { POP_KIND (auxil, true); } StructLike <- { makeThriftTag (auxil, $1, $1s, USE_KIND_STACK, true); PUSH_KIND (auxil, K_MEMBER); } __ '{' __ FieldList '}' _ TypeAnnotations? EOS { POP_KIND (auxil, false); } FieldList <- (Field __)* Field <- IntConstant _ ':' _ FieldReq? _ _ { int r = makeThriftTag (auxil, $2, $2s, USE_KIND_STACK, false); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) { e->extensionFields.typeRef[0] = eStrdup ("typename"); e->extensionFields.typeRef[1] = eStrdup ($1); } } __ ('=' _ ConstValue)? _ TypeAnnotations? ListSeparator? FieldReq <- ("required" / "optional") Service <- "service" _ { makeThriftTag (auxil, $1, $1s, K_SERVICE, true); } _ ("extends" __ { int r = BASE_SCOPE (auxil); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) e->extensionFields.inheritance = eStrdup ($2); } __)? __ '{' __ (Function __)* ('}' / EndOfServiceError) _ TypeAnnotations? EOS { POP_SCOPE (auxil); } EndOfServiceError <- . Function <- ("oneway" __)? __ { int r = makeThriftTag (auxil, $2, $2s, K_FUNCTION, true); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) { e->extensionFields.typeRef[0] = eStrdup ("typename"); e->extensionFields.typeRef[1] = eStrdup ($1); } PUSH_KIND (auxil, K_PARAMETER); } _ <'(' __ FieldList ')'> { int r = BASE_SCOPE (auxil); tagEntryInfo *e = getEntryInCorkQueue (r); if (e) e->extensionFields.signature = eStrdup ($3); } __ Throws? _ TypeAnnotations? ListSeparator? { POP_KIND (auxil, true); } FunctionType <- ("void" / FieldType) Throws <- "throws" { PUSH_KIND (auxil, K_THROWSPARAM); } __ < '(' __ FieldList ')' > { int r = BASE_SCOPE (auxil); attachParserFieldToCorkEntry (r, ThriftFields[F_THROWS].ftype, $1); POP_KIND (auxil, false); } FieldType <- (BaseType / ContainerType / Identifier) # DefinitionType <- (BaseType / ContainerType) BaseType <- BaseTypeName _ TypeAnnotations? BaseTypeName <- ("bool" / "byte" / "i16" / "i32" / "i64" / "double" / "string" / "binary" ) ContainerType <- (MapType / SetType / ListType) MapType <- CppType? "map" WS "<" WS FieldType WS "," WS FieldType WS ">" _ TypeAnnotations? SetType <- CppType? "set" WS "<" WS FieldType WS ">" _ TypeAnnotations? ListType <- "list" WS "<" WS FieldType WS ">" _ TypeAnnotations? CppType <- "cpp_type" Literal ConstValue <- Literal / DoubleConstant / IntConstant / ConstMap / ConstList / Identifier TypeAnnotations <- '(' __ TypeAnnotation* ')' TypeAnnotation <- Identifier _ ('=' __ Literal)? ListSeparator? __ IntConstant <- [-+]? Digit+ DoubleConstant <- [-+]? Digit* '.' Digit* ( ['Ee'] IntConstant )? ConstList <- '[' __ (ConstValue __ ListSeparator? __)* __ ']' # MODIFIED ConstMap <- '{' __ (ConstValue __ ':' __ ConstValue __ (ListSeparator? / &'}') __)* '}' # ... Literal <- (('"' ("\\\"" / [^"])* '"') / ("'" ("\\'" / [^'])* "'")) # '" Identifier <- (Letter / '_')+ (Letter / Digit / [._])* ListSeparator <- [,;] Letter <- [A-Za-z] Digit <- [0-9] # // SourceChar <- . Comment <- MultiLineComment / SingleLineComment MultiLineComment <- "/*" ( !"*/" SourceChar )* "*/" MultiLineCommentNoLineTerminator <- "/*" ( !( "*/" / EOL ) SourceChar )* "*/" SingleLineComment <- ("//" ( !EOL SourceChar )*) / ("#" ( !EOL SourceChar )*) __ <- ( Whitespace / EOL / Comment )* _ <- ( Whitespace / MultiLineCommentNoLineTerminator )* WS <- Whitespace* Whitespace <- [ \t\r] EOL <- '\n' EOS <- __ ';' / _ SingleLineComment? EOL / __ EOF EOF <- !. %% #include "thrift_post.h"