%% 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