Skip to content

Instantly share code, notes, and snippets.

@diakopter
Created June 8, 2012 04:53
Show Gist options
  • Save diakopter/2893670 to your computer and use it in GitHub Desktop.
Save diakopter/2893670 to your computer and use it in GitHub Desktop.
grammar Go {
token TOP {
^ <literal>
[ $ || <.panic: "Syntax error"> ]
}
token ws {
\s
}
######################################################################
## Lexical elements
#### Characters
regex unicode_letter {
<.alpha>
}
regex unicode_digit {
<.digit>
}
#### Letters and digits
regex letter {
<unicode_letter> | '_'
}
regex decimal_digit {
<.digit>
}
regex octal_digit {
<[0..7]>
}
regex hex_digit {
<.xdigit>
}
#### Comments
#### Semicolons
#### Identifiers
token identifier {
<letter> [<letter> | <unicode_digit>]*
}
#### Keywords
#### Operators and Delimiters
#### Integer literals
token int_lit {
| <decimal_lit>
| <octal_lit>
| <hex_lit>
}
token decimal_lit {
<[1..9]> <.decimal_digit>*
}
token octal_lit {
0 <.octal_digit>*
}
token hex_lit {
0x <.hex_digit>+
}
#### Floating-point literals
#### Imaginary literals
#### Character literals
#### String literalsConst
#### Constants
######################################################################
## Types
#### Method sets
#### Boolean types
#### Numeric types
#### String types
#### Array types
#### Slice types
#### Struct types
#### Pointer types
#### Function types
#### Interface types
#### Map types
#### Channel types
#### Properties of types and values
#### Blocks
######################################################################
## Declarations and scope
rule declaration {
| <const_decl>
| <type_decl>
| <var_decl>
}
rule top_level_decl {
| <declaration>
| <function_decl>
| <method_decl>
}
#### Constant declarations
rule const_decl {
const [<const_spec> | '(' [<const_spec> <.semi>]* ')']
}
rule const_spec {
<identifier_list> [<type>? '=' <expression_list>]
}
rule identifier_list {
<identifier>+ % ','
}
rule expression_list {
<expression>+ % ','
}
#### Type declarations
#### Variable declarations
######################################################################
## Expressions
######################################################################
## Statements
rule statement_list { [ <statement> | <?> ]+ % ';' }
rule statement {
# | <declaration>
# | <labeled_stmt>
| <simple_stmt>
# | <keyword_stmt>
# | <if_stmt>
| <block>
}
rule simple_stmt {
| <expression_stmt>
# | <send_stmt>
| <incdec_stmt>
| <assignment>
| <short_var_decl>
}
######################################################################
## Packages
rule expression_list { [ <statement> | <?> ]+ % ';' }
rule expression {
| <unary_expr>
| <binary_expr>
}
rule binary_expr {
<expression> <binary_op> <unary_expr>
}
rule unary_expr {
| <primary_expr>
| <unary_op> <unary_expr>
}
rule method_expr {
<receiver_type> '.' <method_name>
}
rule receiver_type {
<type_name> | [ '(' '*' <type_name> ')' ]
}
rule conversion {
<type> '(' <expression> ')'
}
rule operand {
| <literal>
| <qualified_ident>
| <method_expr>
| '(' <expression> ')'
}
rule literal {
| <basic_lit>
| <composite_lit>
| <function_lit>
}
rule basic_lit {
| <int_lit>
| <float_lit>
| <imaginary_lit>
| <char_lit>
| <string_lit>
}
rule composite_lit { <literal_type> <literal_value> }
rule literal_type {
| <struct_type>
| <array_type>
| '[...]' <element_type>
| <slice_type>
| <map_type>
| <type_name>
}
rule literal_value { '{' ~ '}' [ <element> ** ',' ] ','? }
rule element { [ <key> ':' ]? <value> }
rule key { <field_name> | <element_index> }
rule field_name { <identifier> }
rule element_index { <expression> }
rule value { <expression> | <literal_value> }
rule opt_simple_stmt {
[ [ <simple_stmt> | <?> ] ';' ]?
}
proto rule if_stmt {*}
rule if_stmt:sym<if> {
<sym> <opt_simple_stmt> <expression> <block>
<else_stmt>?
}
proto rule else_stmt {*}
rule else_stmt:sym<else> {
<sym> [ <if_stmt> | <block> ]
}
rule labeled_stmt { <label> ':' <statement> }
rule label { <identifier> }
rule expression_stmt { <expression> }
rule send_stmt { <channel> '<-' <expression> }
rule channel { <expression> }
proto rule keyword_stmt {*}
rule keyword_stmt:sym<go> { <sym> <expression> }
rule keyword_stmt:sym<return> { <sym> <expression_list>? }
rule keyword_stmt:sym<break> { <sym> <label>? }
rule keyword_stmt:sym<continue> { <sym> <label>? }
rule keyword_stmt:sym<goto> { <sym> <label> }
rule keyword_stmt:sym<fallthrough> { <sym> }
rule keyword_stmt:sym<switch> { <sym> <opt_simple_stmt> [ <type_switch> | <expr_switch> ] }
rule keyword_stmt:sym<select> { <sym> <comm_select> }
rule keyword_stmt:sym<for> { <sym> [ <condition> | <for_clause> | <range_clause> ] <block> }
rule keyword_stmt:sym<defer> { <sym> <expression> }
rule condition { <expression> }
rule init_stmt { [ <simple_stmt> | <?> ] }
rule post_stmt { [ <simple_stmt> | <?> ] }
rule for_clause { <init_stmt>? ';' <condition>? ';' <post_stmt>? }
rule range_clause { <expr_assign> 'range' <expression> }
proto rule expr_case {*}
rule expr_case:sym<case> { <sym> <expression_list> }
rule expr_case:sym<default> { <sym> }
rule expr_clause { <exprcase> ':' <statement_list>* }
rule expr_switch {
<expression>? '{' <expr_clause> '}'
}
proto rule type_case {*}
rule type_case:sym<case> { <sym> <type_list> }
rule type_case:sym<default> { <sym> }
rule type_clause { <type_case> ':' <statement_list>* }
rule type_guard { [ <identifier> ':=' ]? <primary_expr> '.(type)' }
rule type_list { <type> ** ',' }
rule type_switch {
<type_guard> "{" { <type_clause> } "}"
}
proto rule comm_case {*}
rule comm_case:sym<case> { <sym> [ <send_stmt> | <recv_stmt> ] }
rule comm_case:sym<default> { <sym> }
rule expr_assign { <expression> [ ',' <expression> ]? [ '=' | ':=' ]}
rule recv_expr { <expression> }
rule recv_stmt { <expr_assign>? <recv_expr> }
rule comm_clause { <comm_case> ':' <statement_list> }
rule comm_select {
'{' <comm_clause>* '}'
}
rule incdec_stmt {
| <inc_stmt>
| <dec_stmt>
}
rule inc_stmt { <expression> '++' }
rule dec_stmt { <expression> '--' }
rule assignment {
<expr_list> <assign_op> <expr_list>
}
#token assign_op is infix { [ <add_op> | <mul_op> ] '=' }
#
#proto token binary_op is infix {*}
#
proto token rel_op {*}
token rel_op:sym<==> { <sym> }
token rel_op:sym<!=> { <sym> }
token rel_op:sym«<» { <sym> }
token rel_op:sym«<=» { <sym> }
token rel_op:sym«>» { <sym> }
token rel_op:sym«>=» { <sym> }
proto token add_op {*}
token add_op:sym<+> { <sym> }
token add_op:sym<-> { <sym> }
token add_op:sym<|> { <sym> }
token add_op:sym<^> { <sym> }
proto token mul_op {*}
token mul_op:sym<*> { <sym> }
token mul_op:sym</> { <sym> }
token mul_op:sym<%> { <sym> }
token mul_op:sym«<<» { <sym> }
token mul_op:sym«>>» { <sym> }
token mul_op:sym<&> { <sym> }
token mul_op:sym<&^> { <sym> }
proto token unary_op {*}
token unary_op:sym<+> { <sym> }
token unary_op:sym<-> { <sym> }
token unary_op:sym<!> { <sym> }
token unary_op:sym<^> { <sym> }
token unary_op:sym<*> { <sym> }
token unary_op:sym<&> { <sym> }
token unary_op:sym«<-» { <sym> }
#proto token statement_control { <...> }
#rule statement_control:sym<say> { <sym> [ <EXPR> ] ** ',' }
#rule statement_control:sym<print> { <sym> [ <EXPR> ] ** ',' }
## Terms
#token term:sym<integer> { <integer> }
#token term:sym<quote> { <quote> }
#proto token quote { <...> }
#token quote:sym<'> { <?[']> <quote_EXPR: ':q'> }
#token quote:sym<"> { <?["]> <quote_EXPR: ':qq'> }
## Operators
#INIT {
# Go::Grammar.O(':prec<u>, :assoc<left>', '%multiplicative');
# Go::Grammar.O(':prec<t>, :assoc<left>', '%additive');
#}
#token circumfix:sym<( )> { '(' <.ws> <EXPR> ')' }
#
#token infix:sym<*> { <sym> <O('%multiplicative, :pirop<mul>')> }
#token infix:sym</> { <sym> <O('%multiplicative, :pirop<div>')> }
#
#token infix:sym<+> { <sym> <O('%additive, :pirop<add>')> }
#token infix:sym<-> { <sym> <O('%additive, :pirop<sub>')> }
}
Go.parse('1');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment