moving along with whitespace

This commit is contained in:
Jeremy Ashkenas
2009-12-28 23:08:02 -05:00
parent ddd52a1845
commit cea417de02
9 changed files with 91 additions and 107 deletions

View File

@@ -30,11 +30,12 @@ prechigh
right '-=' '+=' '/=' '*=' '%='
right DELETE INSTANCEOF TYPEOF
left '.'
right INDENT
left OUTDENT
right THROW FOR IN WHILE NEW SUPER
left UNLESS IF ELSE EXTENDS
left ASSIGN '||=' '&&='
right RETURN INDENT
left OUTDENT
right RETURN
preclow
# We expect 3 shift/reduce errors for optional syntax.
@@ -88,8 +89,7 @@ rule
;
Block:
Then Expression { result = Expressions.new([val[1]]) }
| INDENT Expressions OUTDENT { result = val[1] }
INDENT Expressions OUTDENT { result = val[1] }
;
# All tokens that can terminate an expression.
@@ -98,12 +98,6 @@ rule
| ";"
;
# All tokens that can serve to begin the second block of a multi-part expression.
Then:
THEN
| Terminator
;
# All hard-coded values.
Literal:
NUMBER { result = LiteralNode.new(val[0]) }
@@ -122,13 +116,13 @@ rule
# Assignment to a variable.
Assign:
Value ASSIGN Expression { result = AssignNode.new(val[0], val[2]) }
Value ASSIGN Expression { result = AssignNode.new(val[0], val[2]) }
;
# Assignment within an object literal.
AssignObj:
IDENTIFIER ASSIGN Expression { result = AssignNode.new(ValueNode.new(val[0]), val[2], :object) }
| STRING ASSIGN Expression { result = AssignNode.new(ValueNode.new(LiteralNode.new(val[0])), val[2], :object) }
IDENTIFIER ASSIGN Expression { result = AssignNode.new(ValueNode.new(val[0]), val[2], :object) }
| STRING ASSIGN Expression { result = AssignNode.new(ValueNode.new(LiteralNode.new(val[0])), val[2], :object) }
| Comment { result = val[0] }
;
@@ -146,69 +140,45 @@ rule
# For Ruby's Operator precedence, see:
# https://www.cs.auckland.ac.nz/references/ruby/ProgrammingRuby/language.html
Operation:
'!' Expression { result = OpNode.new(val[0], val[1]) }
| '!!' Expression { result = OpNode.new(val[0], val[1]) }
| '-' Expression = UMINUS { result = OpNode.new(val[0], val[1]) }
| NOT Expression { result = OpNode.new(val[0], val[1]) }
| '~' Expression { result = OpNode.new(val[0], val[1]) }
| '--' Expression { result = OpNode.new(val[0], val[1]) }
| '++' Expression { result = OpNode.new(val[0], val[1]) }
| Expression '--' { result = OpNode.new(val[1], val[0], nil, true) }
| Expression '++' { result = OpNode.new(val[1], val[0], nil, true) }
PrefixOperation
| InfixOperation
| PostfixOperation
;
| Expression '*' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '/' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '%' Expression { result = OpNode.new(val[1], val[0], val[2]) }
PrefixOperation:
PrefixSymbol PureExpression { result = OpNode.new(val[0], val[1]) }
;
| Expression '+' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '-' Expression { result = OpNode.new(val[1], val[0], val[2]) }
PostfixOperation:
PureExpression PostfixSymbol { result = OpNode.new(val[1], val[0], nil, true) }
;
| Expression '<<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '>>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
InfixOperation:
PureExpression
InfixSymbol PureExpression { result = OpNode.new(val[1], val[0], val[2]) }
;
| Expression '&' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '|' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '^' Expression { result = OpNode.new(val[1], val[0], val[2]) }
PrefixSymbol:
'!' | '!!' | '-' = UMINUS | NOT | '~' | '--' | '++' | DELETE | TYPEOF
;
| Expression '<=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '>=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
PostfixSymbol:
'--' | '++'
;
| Expression '==' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '!=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression IS Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression ISNT Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '&&' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '||' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression AND Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression OR Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '-=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '+=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '/=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '*=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '%=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '||=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '&&=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| DELETE Expression { result = OpNode.new(val[0], val[1]) }
| TYPEOF Expression { result = OpNode.new(val[0], val[1]) }
| Expression INSTANCEOF Expression { result = OpNode.new(val[1], val[0], val[2]) }
InfixSymbol:
'*' | '/' | '%' | '+' | '-' | '<<' | '>>' | '>>>' | '&' | '|' | '^'
| '<=' | '<' | '>' | '>=' | '==' | '!=' | IS | ISNT | '&&' | '||'
| AND | OR | '-=' | '+=' | '/=' | '*=' | '%=' | '||=' | '&&=' | INSTANCEOF
;
# Function definition.
Code:
ParamList "=>" CodeBody { result = CodeNode.new(val[0], val[2]) }
| "=>" CodeBody { result = CodeNode.new([], val[1]) }
;
# The body of a function.
CodeBody:
/* nothing */ { result = Expressions.new([]) }
| Block { result = val[0] }
ParamList "=>" Block { result = CodeNode.new(val[0], val[2]) }
| ParamList "=>" Expression { result = CodeNode.new(val[0], Expressions.new([val[2]])) }
| "=>" Block { result = CodeNode.new([], val[1]) }
| "=>" Expression { result = CodeNode.new([], Expressions.new([val[1]])) }
| "=>" { result = CodeNode.new([], nil) }
;
# The parameters to a function definition.
@@ -299,7 +269,7 @@ rule
Try:
TRY Block Catch { result = TryNode.new(val[1], val[2][0], val[2][1]) }
| TRY Block Catch
FINALLY Block { result = TryNode.new(val[1], val[2][0], val[2][1], val[4]) }
FINALLY Block { result = TryNode.new(val[1], val[2][0], val[2][1], val[4]) }
;
# A catch clause.
@@ -310,7 +280,7 @@ rule
# Throw an exception.
Throw:
THROW Expression { result = ThrowNode.new(val[1]) }
THROW PureExpression { result = ThrowNode.new(val[1]) }
;
# Parenthetical expressions.
@@ -320,7 +290,7 @@ rule
# The while loop. (there is no do..while).
While:
WHILE Expression Block { result = WhileNode.new(val[1], val[3]) }
WHILE PureExpression Block { result = WhileNode.new(val[1], val[3]) }
;
# Array comprehensions, including guard and current index.
@@ -328,8 +298,7 @@ rule
For:
Expression FOR
ForVariables ForSource "." { result = ForNode.new(val[0], val[3][0], val[2][0], val[3][1], val[2][1]) }
| FOR ForVariables ForSource
Terminator Expressions "." { result = ForNode.new(val[4], val[2][0], val[1][0], val[2][1], val[1][1]) }
| FOR ForVariables ForSource Block { result = ForNode.new(val[3], val[2][0], val[1][0], val[2][1], val[1][1]) }
;
# An array comprehension has variables for the current element and index.
@@ -347,10 +316,12 @@ rule
# Switch/When blocks.
Switch:
SWITCH Expression Then
Whens { result = val[3].rewrite_condition(val[1]) }
| SWITCH Expression Then
Whens ELSE Block { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
SWITCH Expression INDENT
Whens OUTDENT { result = val[3].rewrite_condition(val[1]) }
| SWITCH Expression INDENT
Whens ELSE Block OUTDENT { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
| SWITCH Expression INDENT
Whens ELSE Expression OUTDENT { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
;
# The inner list of whens.
@@ -361,15 +332,27 @@ rule
# An individual when.
When:
WHEN Expression Then Block { result = IfNode.new(val[1], val[3]) }
WHEN PureExpression Block { result = IfNode.new(val[1], val[2], nil, {:statement => true}) }
| WHEN PureExpression
THEN Expression Terminator { result = IfNode.new(val[1], val[3], nil, {:statement => true}) }
;
# All of the following nutso if-else destructuring is to make the
# grammar expand unambiguously.
# The condition itself.
IfClause:
IF PureExpression { result = val[1] }
;
IfBlock:
IfClause Block { result = IfNode.new(val[0], val[1]) }
| IfClause THEN Expression { result = IfNode.new(val[0], val[2]) }
;
# An elsif portion of an if-else block.
ElsIf:
ELSE IF Expression Block { result = IfNode.new(val[2], val[4]) }
ELSE IfBlock { result = val[1] }
;
# Multiple elsifs can be chained together.
@@ -392,9 +375,9 @@ rule
# The full complement of if blocks, including postfix one-liner ifs and unlesses.
If:
IF Expression Block IfEnd { result = IfNode.new(val[1], val[2], val[3]) }
| Expression IF Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true}) }
| Expression UNLESS Expression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) }
IfBlock IfEnd { result = val[0].add_else(val[1]) }
| Block IfClause { result = IfNode.new(val[1], Expressions.new([val[0]]), nil, {:statement => true}) }
| Block UNLESS PureExpression { result = IfNode.new(val[2], Expressions.new([val[0]]), nil, {:statement => true, :invert => true}) }
;
end