summaryrefslogtreecommitdiff
path: root/grammar/go/go.lm
diff options
context:
space:
mode:
Diffstat (limited to 'grammar/go/go.lm')
-rw-r--r--grammar/go/go.lm177
1 files changed, 174 insertions, 3 deletions
diff --git a/grammar/go/go.lm b/grammar/go/go.lm
index 0dec2329..0ab8f7fd 100644
--- a/grammar/go/go.lm
+++ b/grammar/go/go.lm
@@ -3,6 +3,9 @@ include 'utf8.lm'
token BOM / 0xEF 0xBB 0xBF /
lex
+ #
+ # Definitions.
+ #
rl newline / 0x0A /
rl valid_utf8 /
@@ -12,12 +15,180 @@ lex
0xF0 .. 0xF7 any any any
/
- rl unicode_char / valid_utf8 - 0x0A /
+ rl unicode_char / valid_utf8 - 0x0A /
- token id / unicode_letter unicode_letter* /
+ rl letter / unicode_letter | '_' /
+ rl binary_digit / '0' | '1' /
+ rl octal_digit / '0' .. '7' /
+ rl decimal_digit / '0' .. '9' /
+ rl hex_digit / '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' /
+ #
+ # Tokens
+ #
+
+ literal
+ `+ `& `+= `&= `&& `== `!= `( `)
+ `- `| `-= `|= `|| `< `<= `[ `]
+ `* `^ `*= `^= `<- `> `>= `{ `}
+ `/ `<< `/= `<<= `++ `= `:= `, #;
+ `% `>> `%= `>>= `-- `! `... `. `:
+ `&^ `&^=
+
+ token SEMI /';'/
+
+ literal
+ `break `default `func `interface `select
+ `case `defer `go `map `struct
+ `chan `else `goto `package `switch
+ `const `fallthrough `if `range `type
+ `continue `for `import `return `var
+
+ token id
+ / letter ( letter | unicode_digit )* /
+
+ #
+ # Non-float numbers
+ #
+
+ rl binary_digits / binary_digit ( '_'? binary_digit )* /
+ rl octal_digits / octal_digit ( '_'? octal_digit )* /
+ rl decimal_digits / decimal_digit ( '_'? decimal_digit )* /
+ rl hex_digits / hex_digit ( '_'? hex_digit )* /
+
+ token binary_lit / '0' ( 'b' | 'B' ) '_'? binary_digits /
+ token octal_lit / '0' ( 'o' | 'O' )? '_'? octal_digits /
+ token decimal_lit / '0' | ( '1' .. '9' ) ( '_'? decimal_digits )? /
+ token hex_lit / '0' ( 'x' | 'X' ) '_'? hex_digits /
+
+ rl int_lit
+ / decimal_lit | binary_lit | octal_lit | hex_lit /
+
+ def int_lit
+ [decimal_lit] | [binary_lit] | [octal_lit] | [hex_lit]
+
+ rl decimal_exponent / ( 'e' | 'E' ) ( '+' | '-' )? decimal_digits /
+
+ #
+ # Floats
+ #
+ token decimal_float_lit /
+ decimal_digits '.' decimal_digits? decimal_exponent? |
+ decimal_digits decimal_exponent |
+ '.' decimal_digits decimal_exponent? /
+
+ rl hex_mantissa
+ / '_'? hex_digits '.' hex_digits? | '_'? hex_digits | '.' hex_digits /
+ rl hex_exponent
+ / ( 'p' | 'P' ) ( '+' | '-' )? decimal_digits /
+
+ token hex_float_lit
+ / '0' ( 'x' | 'X' ) hex_mantissa hex_exponent /
+
+ rl float_lit
+ / decimal_float_lit | hex_float_lit /
+
+ def float_lit
+ [decimal_float_lit] | [hex_float_lit]
+
+ #
+ # Imaginary
+ #
+ token imaginary_lit /
+ ( decimal_digits | int_lit | float_lit ) 'i' /
+
+ #
+ # Rune literals
+ #
+
+
+ rl escaped_char
+ / '\\' ( 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '\\' | "'" | '"' ) /
+
+ rl octal_byte_value / '\\' octal_digit octal_digit octal_digit /
+ rl hex_byte_value / '\\' 'x' hex_digit hex_digit /
+ rl little_u_value / '\\' 'u' hex_digit hex_digit hex_digit hex_digit /
+ rl big_u_value / '\\' 'U' hex_digit hex_digit hex_digit hex_digit
+ hex_digit hex_digit hex_digit hex_digit /
+
+ rl byte_value / octal_byte_value | hex_byte_value /
+ rl unicode_value / unicode_char | little_u_value | big_u_value | escaped_char /
+
+ token rune_lit / "'" ( unicode_value | byte_value ) "'" /
+
+ #
+ # String literals
+ #
+ rl raw_string_lit / "`" ( ( unicode_char | newline ) - '`' )* "`" /
+ rl interpreted_string_lit / '"' ( ( unicode_value | byte_value ) - '"' )* '"' /
+ token string_lit / raw_string_lit | interpreted_string_lit /
+
+ #
+ # Comments
+ #
+ rl line_comment
+ / '//' [^\n]* '\n' /
+
+ rl general_comment
+ / '/*' any* :> '*/'/
+
+ rl pre_insert_semi /
+ ( id -
+ 'break' - 'default' - 'func' - 'interface' - 'select'
+ 'case' - 'defer' - 'go' - 'map' - 'struct'
+ 'chan' - 'else' - 'goto' - 'package' - 'switch'
+ 'const' - 'fallthrough' - 'if' - 'range' - 'type'
+ 'continue' - 'for' - 'import' - 'return' - 'var' ) |
+ int_lit |
+ float_lit |
+ imaginary_lit |
+ rune_lit |
+ string_lit
+ /
+
+ #
+ # Semi-colons
+ #
+ token insert_semi /
+ pre_insert_semi
+ ( [ \t]+ | general_comment )*
+ ( '/*' [^\n]* | line_comment | '\n' )
+ /
+ {
+ parse BA: break_apart::break_apart[match_text]
+
+ Prefix: str = input->pull( BA.pre_semi.data.length )
+ input->push( make_token( typeid<SEMI>, ';' ) )
+ input->push( Prefix )
+ }
+
+ ignore /line_comment/
+ ignore /general_comment/
ignore /[ \t\n\r]+/
end
+namespace break_apart
+ lex
+ token pre_semi / pre_insert_semi /
+ ignore /line_comment/
+ ignore /'/*' any*/
+ ignore /[ \t\n\r]+/
+ end
+
+ def break_apart
+ [pre_semi]
+end
+
+def item
+ [id]
+| [int_lit]
+| [float_lit]
+| [imaginary_lit]
+| [rune_lit]
+| [string_lit]
+
+def stmt
+ [item+ SEMI]
+
def program
- [BOM? id*]
+ [BOM? stmt*]