%% name = Stark::Parser
%% namespace = ast Namespace(lang, namespace) %% include = ast Include(path) %% struct = ast Struct(type, name, fields) %% field = ast Field(index, type, name, value, options) %% function = ast Function(name, return_type, arguments, throws, options) %% service = ast Service(name, functions) %% comment = ast Comment(text) %% enum = ast Enum(name, values) %% map = ast Map(key,value) %% set = ast Set(value) %% list = ast List(value) %% exception = ast Exception(name, fields) %% const_int = ast ConstInt(value) %% const_str = ast ConstString(value) %% const_id = ast ConstIdentifier(value) %% const_list = ast ConstList(values) %% const_map = ast ConstMap(values) %% const_dbl = ast ConstDouble(value)
intconstant = /([+-]?[0-9]+)/ hexconstant = /(“0x”+)/ dubconstant = /([+-]?[0-9]+(.+)([eE]?[0-9]+)?)/
| /([+-]?[0-9]+([eE][+-]?[0-9]+))/ | /([+-]?(\.[0-9]+)([eE][+-]?[0-9]+)?)/ # | /([+-]?[0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?)/
identifier = /([a-zA-Z_]*)/ whitespace = /([ trn]*)/ # sillycomm = /(“/*”“*”*“*/”)/ # multicomm = /(“/*”[^*]“/”*([^*/]|[^*]“/”|“*”[^/])*“*”*“*/”)/ # doctext = “/**” (/[^*/]|[^*]/ “/”|“*” /[^/]/)* “*”* “*/” # comment = /(“//”[^n]*)/ # unixcomment = /(“#”[^n]*)/ st_identifier = /([a-zA-Z-]*)/ literal_begin = /(['"])/
reserved =
"BEGIN" | "END" | "__CLASS__" | "__DIR__" | "__FILE__" | "__FUNCTION__" | "__LINE__" | "__METHOD__" | "__NAMESPACE__" | "abstract" | "alias" | "and" | "args" | "as" | "assert" | "begin" | "break" | "case" | "catch" | "class" | "clone" | "continue" | "declare" | "def" | "default" | "del" | "delete" | "do" | "dynamic" | "elif" | "else" | "elseif" | "elsif" | "end" | "enddeclare" | "endfor" | "endforeach" | "endif" | "endswitch" | "endwhile" | "ensure" | "except" | "exec" | "finally" | "float" | "for" | "foreach" | "function" | "global" | "goto" | "if" | "implements" | "import" | "in" | "inline" | "instanceof" | "interface" | "is" | "lambda" | "module" | "native" | "new" | "next" | "nil" | "not" | "or" | "pass" | "public" | "print" | "private" | "protected" | "public" | "raise" | "redo" | "rescue" | "retry" | "register" | "return" | "self" | "sizeof" | "static" | "super" | "switch" | "synchronized" | "then" | "this" | "throws" | "transient" | "try" | "undef" | "union" | "unless" | "unsigned" | "until" | "use" | "var" | "virtual" | "volatile" | "when" | "while" | "with" | "xor" | "yield"
tok_int_constant = < intconstant > { text.to_i }
| < hexconstant > { text.to_i } | "false" { 0 } | "true" { 1 }
tok_dub_constant = dubconstant:f { f.to_f }
tok_identifier = < identifier > ~text tok_st_identifier = st_identifier
escapes = “\r” { “r” }
| "\\n" { "\n" } | "\\t" { "\t" } | "\\\"" { "\"" } | "\\'" { "'" } | "\\\\" { "\\" }
tok_literal = “"” < (escapes | !“"” . )* > “"” ~text
| "'" < (escapes | !"'" . )* > "'" ~text
osp = /[ t]*/ bsp = /[s]+/ obsp = /[s]*/
root = Program !.
# Program = HeaderList - DefinitionList
Program = Element*:a { a }
CMLComment = “/*” < (!“*/” .)* > “*/” obsp ~comment(text)
CSLComment = “//” < (!“n” .)* > bsp ~comment(text)
HComment = “#” < (!“n” .)* > bsp ~comment(text)
Comment = CMLComment | CSLComment | HComment
CaptureDocText = {} DestroyDocText = {} HeaderList = HeaderList Header
| Header
Element = Comment
| obsp Header bsp | Definition obsp
Header = Include | Namespace
Namespace = “namespace” - tok_identifier:l - tok_identifier:n ~namespace(l,n)
| "namespace" - "*" - tok_identifier:n ~namespace(nil,n)
Include = “include” - tok_literal:f ~include(f)
DefinitionList = DefinitionList CaptureDocText Definition
Definition = Const
| TypeDefinition | Service
TypeDefinition = Typedef
| Enum | Senum | Struct | Xception
Typedef = “typedef” - FieldType tok_identifier
CommaOrSemicolonOptional = (“,” | “;”)? obsp
Enum = “enum” - tok_identifier:name osp “{” obsp EnumDefList:vals obsp “}” ~enum(name, vals)
EnumDefList = EnumDefList:l EnumDef:e { l + [e] }
| EnumDef:e { [e] }
EnumDef = CaptureDocText tok_identifier osp “=” osp tok_int_constant CommaOrSemicolonOptional
| CaptureDocText tok_identifier CommaOrSemicolonOptional
Senum = “senum” - tok_identifier “{” SenumDefList “}”
SenumDefList = SenumDefList SenumDef
| nothing
SenumDef = tok_literal CommaOrSemicolonOptional
Const = “const” - FieldType tok_identifier osp “=” osp ConstValue CommaOrSemicolonOptional
ConstValue = tok_int_constant:i ~const_int(i)
| tok_literal:s ~const_str(s) | tok_identifier:i ~const_id(i) | ConstList | ConstMap | tok_dub_constant:d ~const_dbl(d)
ConstList = “[” osp ConstListContents*:l osp “]” ~const_list(l)
ConstListContents = ConstValue:i CommaOrSemicolonOptional osp ~i
ConstMap = “{” osp ConstMapContents*:m osp “}” ~const_map(m)
# ConstMapContents = ConstMapContents ConstValue osp “:” osp ConstValue CommaOrSemicolonOptional
# | ConstValue osp ":" osp ConstValue CommaOrSemicolonOptional
ConstMapContents = ConstValue:k osp “:” osp ConstValue:v CommaOrSemicolonOptional
{ [k,v] }
StructHead = < “struct” | “union”> ~text
Struct = StructHead:t - tok_identifier:name - XsdAll? osp
"{" obsp Comment? FieldList?:list obsp "}" # TypeAnnotations ~struct(t.to_sym,name,list)
XsdAll = “xsd_all”
XsdOptional = “xsd_optional” - | nothing
XsdNillable = “xsd_nillable” - | nothing
XsdAttributes = “xsd_attrs” - “{” FieldList “}”
| nothing
Xception = “exception” - tok_identifier:name osp “{” obsp FieldList?:list obsp “}” ~exception(name, list)
Service = “service” - tok_identifier:name - Extends? osp
"{" obsp FunctionList?:funcs obsp "}" ~service(name, funcs)
Extends = “extends” - tok_identifier
FunctionList = FunctionList:l Function:f { l + [f] }
| Function:f { [f] }
Function = CaptureDocText OneWay?:o FunctionType:rt - tok_identifier:name
osp "(" obsp FieldList?:args ")" Throws?:t CommaOrSemicolonOptional ~function(name, rt, args, t, o)
OneWay = (“oneway” | “async”) - { :oneway }
Throws = osp “throws” osp “(” obsp FieldList “)”
FieldList = FieldList:l Field:f { l + [f] }
| Field:f { [f] }
Field = CaptureDocText FieldIdentifier?:i osp FieldRequiredness?:req osp
FieldType:t osp tok_identifier:n osp FieldValue?:val CommaOrSemicolonOptional ~field(i,t,n,val,req) # XsdOptional XsdNillable XsdAttributes TypeAnnotations
FieldIdentifier = tok_int_constant:n “:” ~n
FieldRequiredness = < (“required” | “optional”) > { [text] }
FieldValue = “=” osp ConstValue:e ~e
FunctionType = FieldType | “void”
FieldType = ContainerType
| tok_identifier:n ~n
BaseType = SimpleBaseType:t TypeAnnotations ~t
SimpleBaseType = “string” { :string }
| "binary" { :binary } | "slist" { :slist } | "bool" { :bool } | "byte" { :byte } | "i16" { :i16 } | "i32" { :i32 } | "i64" { :i64 } | "double" { :double }
ContainerType = SimpleContainerType
SimpleContainerType = MapType | SetType | ListType
MapType = “map” “<” FieldType:a osp “,” osp FieldType:b “>” ~map(a,b)
SetType = “set” “<” FieldType:a “>” ~set(a)
ListType = “list” “<” FieldType:a “>” ~list(a)
CppType = tok_cpp_type tok_literal
| nothing
TypeAnnotationList = TypeAnnotationList TypeAnnotation
TypeAnnotation = tok_identifier “=” tok_literal CommaOrSemicolonOptional