Skip to content

Instantly share code, notes, and snippets.

@andersonsp
Last active June 2, 2023 11:21
Show Gist options
  • Save andersonsp/7daef95b4dc94f337a8cc6aee08cf852 to your computer and use it in GitHub Desktop.
Save andersonsp/7daef95b4dc94f337a8cc6aee08cf852 to your computer and use it in GitHub Desktop.
program : statement_seq
statement_seq : statement {sep statement}
statement : var_decl
| class_decl
| method_decl
| "if" expression opt_then statement_seq ["else" statement_seq] "end"
| "while" expression opt_do statement_seq "end"
| "return" expression
| "print" expression
| sep
| expression
;
opt_then : "then" | sep ;
opt_do : "do" | sep ;
var_decl : "var" identifier ["=" expression] {"," identifier ["=" expression]} ;
class_decl : "class" identifier ["(" ident_list ")"] ["extends" identifier] sep statement_seq "end" ;
method_decl : "def" identifier "(" ident_list ")" sep statement_seq "end" ;
expression : atom
| prefix_op atom
| { atom binop atom }
| lhs "=" expression
;
atom : literal
| identifier "(" [expression {"," expression}] ")"
| "(" statement ")"
| lhs
;
lhs : identifier
| atom `[' [ARGS] `]'
| atom `.' identifier
;
binop : <pratt_parser> ;
prefix_op : <pratt_parser> ;
literal : number | string | symbol | block ;
ident_list : ident {"," ident}
identifier : ["_"] alnum {alnum | "_"} ["!" | "?"]
number : integer | float ;
integer : {digits}
float : {digits}["." {digits}]
string : "\"" chars "\""
symbol : "'" chars "'"
block : "do" statement_seq "end"
sep : "\n" | ";"
chars : *
digits : [0-9]
alpha : [a-zA-Z]
alnum : alpha | digits
space : " "
Module = MODULE ident ";" [ImportList] DeclSeq
[BEGIN StatementSeq] END ident ".".
ImportList = IMPORT [ident ":="] ident {"," [ident ":="] ident} ";".
DeclSeq = { CONST {ConstDecl ";" } | TYPE {TypeDecl ";"}
| VAR {VarDecl ";"}} {ProcDecl ";" | ForwardDecl ";"}.
ConstDecl = IdentDef "=" ConstExpr.
TypeDecl = IdentDef "=" Type.
VarDecl = IdentList ":" Type.
ProcDecl = PROCEDURE [Receiver] IdentDef [FormalPars] ";" DeclSeq
[BEGIN StatementSeq] END ident.
ForwardDecl = PROCEDURE "^" [Receiver] IdentDef [FormalPars].
FormalPars = "(" [FPSection {";" FPSection}] ")" [":" Qualident].
FPSection = [VAR] ident {"," ident} ":" Type.
Receiver = "(" [VAR] ident ":" ident ")".
Type = Qualident
| ARRAY [ConstExpr {"," ConstExpr}] OF Type
| RECORD ["("Qualident")"] FieldList {";" FieldList} END
| POINTER TO Type
| PROCEDURE [FormalPars].
FieldList = [IdentList ":" Type].
StatementSeq = Statement {";" Statement}.
Statement = [ Designator ":=" Expr
| Designator ["(" [ExprList] ")"]
| IF Expr THEN StatementSeq {ELSIF Expr THEN StatementSeq}
[ELSE StatementSeq] END
| CASE Expr OF Case {"|" Case} [ELSE StatementSeq] END
| WHILE Expr DO StatementSeq END
| REPEAT StatementSeq UNTIL Expr
| FOR ident ":=" Expr TO Expr [BY ConstExpr] DO StatementSeq END
| LOOP StatementSeq END
| WITH Guard DO StatementSeq {"|" Guard DO StatementSeq}
[ELSE StatementSeq] END
| EXIT
| RETURN [Expr]
].
Case = [CaseLabels {"," CaseLabels} ":" StatementSeq].
CaseLabels = ConstExpr [".." ConstExpr].
Guard = Qualident ":" Qualident.
ConstExpr = Expr.
Expr = SimpleExpr [Relation SimpleExpr].
SimpleExpr = ["+" | "-"] Term {AddOp Term}.
Term = Factor {MulOp Factor}.
Factor = Designator ["(" [ExprList] ")"] | number | character | string
| NIL | Set | "(" Expr ")" | " ~ " Factor.
Set = "{" [Element {"," Element}] "}".
Element = Expr [".." Expr].
Relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.
AddOp = "+" | "-" | OR.
MulOp = " * " | "/" | DIV | MOD | "&".
Designator = Qualident {"." ident | "[" ExprList "]" | " ^ "
| "(" Qualident ")"}.
ExprList = Expr {"," Expr}.
IdentList = IdentDef {"," IdentDef}.
Qualident = [ident "."] ident.
IdentDef = ident [" * " | "-"].
PROGRAM : COMPSTMT
COMPSTMT : STMT (TERM EXPR)* [TERM]
STMT : CALL do [`|' [BLOCK_VAR] `|'] COMPSTMT end
| undef FNAME
| alias FNAME FNAME
| STMT if EXPR
| STMT while EXPR
| STMT unless EXPR
| STMT until EXPR
| `BEGIN' `{' COMPSTMT `}'
| `END' `{' COMPSTMT `}'
| LHS `=' COMMAND [do [`|' [BLOCK_VAR] `|'] COMPSTMT end]
| EXPR
EXPR : MLHS `=' MRHS
| return CALL_ARGS
| yield CALL_ARGS
| EXPR and EXPR
| EXPR or EXPR
| not EXPR
| COMMAND
| `!' COMMAND
| ARG
CALL : FUNCTION
| COMMAND
COMMAND : OPERATION CALL_ARGS
| PRIMARY `.' OPERATION CALL_ARGS
| PRIMARY `::' OPERATION CALL_ARGS
| super CALL_ARGS
FUNCTION : OPERATION [`(' [CALL_ARGS] `)']
| PRIMARY `.' OPERATION `(' [CALL_ARGS] `)'
| PRIMARY `::' OPERATION `(' [CALL_ARGS] `)'
| PRIMARY `.' OPERATION
| PRIMARY `::' OPERATION
| super `(' [CALL_ARGS] `)'
| super
ARG : LHS `=' ARG
| LHS OP_ASGN ARG
| ARG `..' ARG
| ARG `...' ARG
| ARG `+' ARG
| ARG `-' ARG
| ARG `*' ARG
| ARG `/' ARG
| ARG `%' ARG
| ARG `**' ARG
| `+' ARG
| `-' ARG
| ARG `|' ARG
| ARG `^' ARG
| ARG `&' ARG
| ARG `<=>' ARG
| ARG `>' ARG
| ARG `>=' ARG
| ARG `<' ARG
| ARG `<=' ARG
| ARG `==' ARG
| ARG `===' ARG
| ARG `!=' ARG
| ARG `=~' ARG
| ARG `!~' ARG
| `!' ARG
| `~' ARG
| ARG `<<' ARG
| ARG `>>' ARG
| ARG `&&' ARG
| ARG `||' ARG
| defined? ARG
| PRIMARY
PRIMARY : `(' COMPSTMT `)'
| LITERAL
| VARIABLE
| PRIMARY `::' IDENTIFIER
| `::' IDENTIFIER
| PRIMARY `[' [ARGS] `]'
| `[' [ARGS [`,']] `]'
| `{' [(ARGS|ASSOCS) [`,']] `}'
| return [`(' [CALL_ARGS] `)']
| yield [`(' [CALL_ARGS] `)']
| defined? `(' ARG `)'
| FUNCTION
| FUNCTION `{' [`|' [BLOCK_VAR] `|'] COMPSTMT `}'
| if EXPR THEN
COMPSTMT
(elsif EXPR THEN COMPSTMT)*
[else COMPSTMT]
end
| unless EXPR THEN
COMPSTMT
[else COMPSTMT]
end
| while EXPR DO COMPSTMT end
| until EXPR DO COMPSTMT end
| case COMPSTMT
(when WHEN_ARGS THEN COMPSTMT)+
[else COMPSTMT]
end
| for BLOCK_VAR in EXPR DO
COMPSTMT
end
| begin
COMPSTMT
[rescue [ARGS] DO COMPSTMT]+
[else COMPSTMT]
[ensure COMPSTMT]
end
| class IDENTIFIER [`<' IDENTIFIER]
COMPSTMT
end
| module IDENTIFIER
COMPSTMT
end
| def FNAME ARGDECL
COMPSTMT
end
| def SINGLETON (`.'|`::') FNAME ARGDECL
COMPSTMT
end
WHEN_ARGS : ARGS [`,' `*' ARG]
| `*' ARG
THEN : TERM
| then
| TERM then
DO : TERM
| do
| TERM do
BLOCK_VAR : LHS
| MLHS
MLHS : MLHS_ITEM `,' [MLHS_ITEM (`,' MLHS_ITEM)*] [`*' [LHS]]
| `*' LHS
MLHS_ITEM : LHS
| '(' MLHS ')'
LHS : VARIABLE
| PRIMARY `[' [ARGS] `]'
| PRIMARY `.' IDENTIFIER
MRHS : ARGS [`,' `*' ARG]
| `*' ARG
CALL_ARGS : ARGS
| ARGS [`,' ASSOCS] [`,' `*' ARG] [`,' `&' ARG]
| ASSOCS [`,' `*' ARG] [`,' `&' ARG]
| `*' ARG [`,' `&' ARG]
| `&' ARG
| COMMAND
ARGS : ARG (`,' ARG)*
ARGDECL : `(' ARGLIST `)'
| ARGLIST TERM
ARGLIST : IDENTIFIER(`,'IDENTIFIER)*[`,'`*'[IDENTIFIER]][`,'`&'IDENTIFIER]
| `*'IDENTIFIER[`,'`&'IDENTIFIER]
| [`&'IDENTIFIER]
SINGLETON : VARIABLE
| `(' EXPR `)'
ASSOCS : ASSOC (`,' ASSOC)*
ASSOC : ARG `=>' ARG
VARIABLE : VARNAME
| nil
| self
LITERAL : numeric
| SYMBOL
| STRING
| STRING2
| HERE_DOC
| REGEXP
TERM : `;'
| `\n'
<program> ::= <statement>
<statement> ::= "if" <paren_expr> <statement> |
"if" <paren_expr> <statement> "else" <statement> |
"while" <paren_expr> <statement> |
"do" <statement> "while" <paren_expr> ";" |
"{" { <statement> } "}" |
<expr> ";" |
";"
<paren_expr> ::= "(" <expr> ")"
<expr> ::= <test> | <id> "=" <expr>
<test> ::= <sum> | <sum> "<" <sum>
<sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term>
<term> ::= <id> | <int> | <paren_expr>
<id> ::= "a" | "b" | "c" | "d" | ... | "z"
<int> ::= <an_unsigned_decimal_integer>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment