see Pseudo BNF Syntax of Ruby

just a demo, need a 'real' grammar spec....

opasgn := '+=' meps | '-=' | '*-' | '/=' | '%=' | '**='
	| '&=' | '|=' | '^=' | '<<=' | '>>=' 
	| '&&=' | '||=' .				" opasgn << '+='; << '||=' "
identifier := '\a[\w_]*' regex.				" identifier << 'a_1' "
fname :=  identifier | '..' | '|' | '^' | '&'
	| '<=>' | '===' | '==' | '=~'
	| '>=' | '>>' | '>' | '<<' | '<=' | '<'
	| '+@' | '+' | '-@' | '-' | '/' | '%' | '**' | '*'
	| '~' | '[]=' | '[]'.				" fname << '[]'; << 'abc' "
global :='\$' regex ,< identifier
	| '\$\-.' regex
	| '\$.'  regex.					" global << '$abc'; << '$-a'; <<'$a' "
varname := global
	| ('@' regex ,< identifier)
	| identifier.					" varname << '@abc'; << 'abc' "
symbol  := (':' regex ,< fname)
	| (':' regex ,< varname).			" symbol << ':@abc'; << ':===' "
operation := identifier deepCopy ,< '[!\?]' regex.		" operation  << 'abc!'; << 'abc?' "
string := '"[^"]*"' regex.							
string2 :=												 	
	[ : input : peek |
	| p1 p2 char matchChar matchAny |
	p1 := input position .
	matchChar := [input match: '.' regex action: [:r | char := r]].
	matchAny := [ input matchUpToAll: char asString action: [ : r | r ]].
	input match: '%[Qqx]' regex , matchChar , matchAny , [char]
		action: [ : r |
			p2 := input position .
			input position: p1 .
			input next: p2 - p1]].		" string2 meps << '%QzABCz' ; << '%x%foo%' "
heredoc := 
	[ : input : peek | 
		| p1 p2 ident matchIdent matchBody |
		p1 := input position .
		matchIdent := [ input match: identifier meps | string
			action: [ : r | ident := r ]].
		matchBody := [ input matchUpToAll: ident action: [ : r | r ]].
		input
			match: '<<' meps , matchIdent , matchBody , [ident]
			action: [ : oc | 
				p2 := input position.
				input position: p1 .
				input next: p2 - p1]].	" heredoc meps << '<<zz abc def abc zz' "
regexp := 
	[ : input : peek |
		| rule1 rule2 p1 p2 char matchChar matchAny|
		p1 := input position .
		rule1 := '\/[^\/]*\/[io]' regex .
		matchChar := [input match: '.' regex action:[:r | char := r]].
		matchAny := [ input matchUpToAll: char asString action: [ : r | r ]].
		rule2 := [input match: '%r' regex , matchChar , matchAny , [matchChar] action: [:r|r]].
		input match: rule1 | rule2
			action: [ : r |
				p2 := input position .
				input position: p1 .
				input next: p2 - p1]].	" regexp meps << '/abc/i'; << '/abc/o' "