mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
171 lines
6.1 KiB
Text
171 lines
6.1 KiB
Text
|
# This grammar is released under an MIT license
|
||
|
# Author: William Howard (http://github.com/whoward)
|
||
|
# Source: https://github.com/whoward/cadenza/blob/master/src/cadenza.y
|
||
|
|
||
|
class Cadenza::RaccParser
|
||
|
|
||
|
/* expect this many shift/reduce conflicts */
|
||
|
expect 37
|
||
|
|
||
|
rule
|
||
|
target
|
||
|
: document
|
||
|
| /* none */ { result = nil }
|
||
|
;
|
||
|
|
||
|
parameter_list
|
||
|
: logical_expression { result = [val[0]] }
|
||
|
| parameter_list ',' logical_expression { result = val[0].push(val[2]) }
|
||
|
;
|
||
|
|
||
|
/* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
|
||
|
primary_expression
|
||
|
: IDENTIFIER { result = VariableNode.new(val[0].value) }
|
||
|
| IDENTIFIER parameter_list { result = VariableNode.new(val[0].value, val[1]) }
|
||
|
| INTEGER { result = ConstantNode.new(val[0].value) }
|
||
|
| REAL { result = ConstantNode.new(val[0].value) }
|
||
|
| STRING { result = ConstantNode.new(val[0].value) }
|
||
|
| '(' filtered_expression ')' { result = val[1] }
|
||
|
;
|
||
|
|
||
|
multiplicative_expression
|
||
|
: primary_expression
|
||
|
| multiplicative_expression '*' primary_expression { result = OperationNode.new(val[0], "*", val[2]) }
|
||
|
| multiplicative_expression '/' primary_expression { result = OperationNode.new(val[0], "/", val[2]) }
|
||
|
;
|
||
|
|
||
|
additive_expression
|
||
|
: multiplicative_expression
|
||
|
| additive_expression '+' multiplicative_expression { result = OperationNode.new(val[0], "+", val[2]) }
|
||
|
| additive_expression '-' multiplicative_expression { result = OperationNode.new(val[0], "-", val[2]) }
|
||
|
;
|
||
|
|
||
|
boolean_expression
|
||
|
: additive_expression
|
||
|
| boolean_expression OP_EQ additive_expression { result = OperationNode.new(val[0], "==", val[2]) }
|
||
|
| boolean_expression OP_NEQ additive_expression { result = OperationNode.new(val[0], "!=", val[2]) }
|
||
|
| boolean_expression OP_LEQ additive_expression { result = OperationNode.new(val[0], "<=", val[2]) }
|
||
|
| boolean_expression OP_GEQ additive_expression { result = OperationNode.new(val[0], ">=", val[2]) }
|
||
|
| boolean_expression '>' additive_expression { result = OperationNode.new(val[0], ">", val[2]) }
|
||
|
| boolean_expression '<' additive_expression { result = OperationNode.new(val[0], "<", val[2]) }
|
||
|
;
|
||
|
|
||
|
inverse_expression
|
||
|
: boolean_expression
|
||
|
| NOT boolean_expression { result = BooleanInverseNode.new(val[1]) }
|
||
|
;
|
||
|
|
||
|
logical_expression
|
||
|
: inverse_expression
|
||
|
| logical_expression AND inverse_expression { result = OperationNode.new(val[0], "and", val[2]) }
|
||
|
| logical_expression OR inverse_expression { result = OperationNode.new(val[0], "or", val[2]) }
|
||
|
;
|
||
|
|
||
|
filter
|
||
|
: IDENTIFIER { result = FilterNode.new(val[0].value) }
|
||
|
| IDENTIFIER ':' parameter_list { result = FilterNode.new(val[0].value, val[2]) }
|
||
|
;
|
||
|
|
||
|
filter_list
|
||
|
: filter { result = [val[0]] }
|
||
|
| filter_list '|' filter { result = val[0].push(val[2]) }
|
||
|
;
|
||
|
|
||
|
filtered_expression
|
||
|
: logical_expression
|
||
|
| logical_expression '|' filter_list { result = FilteredValueNode.new(val[0], val[2]) }
|
||
|
;
|
||
|
|
||
|
inject_statement
|
||
|
: VAR_OPEN filtered_expression VAR_CLOSE { result = val[1] }
|
||
|
;
|
||
|
|
||
|
if_tag
|
||
|
: STMT_OPEN IF logical_expression STMT_CLOSE { open_scope!; result = val[2] }
|
||
|
| STMT_OPEN UNLESS logical_expression STMT_CLOSE { open_scope!; result = BooleanInverseNode.new(val[2]) }
|
||
|
;
|
||
|
|
||
|
else_tag
|
||
|
: STMT_OPEN ELSE STMT_CLOSE { result = close_scope!; open_scope! }
|
||
|
;
|
||
|
|
||
|
end_if_tag
|
||
|
: STMT_OPEN ENDIF STMT_CLOSE { result = close_scope! }
|
||
|
| STMT_OPEN ENDUNLESS STMT_CLOSE { result = close_scope! }
|
||
|
;
|
||
|
|
||
|
if_block
|
||
|
: if_tag end_if_tag { result = IfNode.new(val[0], val[1]) }
|
||
|
| if_tag document end_if_tag { result = IfNode.new(val[0], val[2]) }
|
||
|
| if_tag else_tag document end_if_tag { result = IfNode.new(val[0], val[1], val[3]) }
|
||
|
| if_tag document else_tag end_if_tag { result = IfNode.new(val[0], val[2], val[3]) }
|
||
|
| if_tag document else_tag document end_if_tag { result = IfNode.new(val[0], val[2], val[4]) }
|
||
|
;
|
||
|
|
||
|
for_tag
|
||
|
: STMT_OPEN FOR IDENTIFIER IN filtered_expression STMT_CLOSE { open_scope!; result = [val[2].value, val[4]] }
|
||
|
;
|
||
|
|
||
|
end_for_tag
|
||
|
: STMT_OPEN ENDFOR STMT_CLOSE { result = close_scope! }
|
||
|
;
|
||
|
|
||
|
/* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
|
||
|
for_block
|
||
|
: for_tag end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[1]) }
|
||
|
| for_tag document end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[2]) }
|
||
|
;
|
||
|
|
||
|
block_tag
|
||
|
: STMT_OPEN BLOCK IDENTIFIER STMT_CLOSE { result = open_block_scope!(val[2].value) }
|
||
|
;
|
||
|
|
||
|
end_block_tag
|
||
|
: STMT_OPEN ENDBLOCK STMT_CLOSE { result = close_block_scope! }
|
||
|
;
|
||
|
|
||
|
/* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
|
||
|
block_block
|
||
|
: block_tag end_block_tag { result = BlockNode.new(val[0], val[1]) }
|
||
|
| block_tag document end_block_tag { result = BlockNode.new(val[0], val[2]) }
|
||
|
;
|
||
|
|
||
|
generic_block_tag
|
||
|
: STMT_OPEN IDENTIFIER STMT_CLOSE { open_scope!; result = [val[1].value, []] }
|
||
|
| STMT_OPEN IDENTIFIER parameter_list STMT_CLOSE { open_scope!; result = [val[1].value, val[2]] }
|
||
|
;
|
||
|
|
||
|
end_generic_block_tag
|
||
|
: STMT_OPEN END STMT_CLOSE { result = close_scope! }
|
||
|
;
|
||
|
|
||
|
generic_block
|
||
|
: generic_block_tag document end_generic_block_tag { result = GenericBlockNode.new(val[0].first, val[2], val[0].last) }
|
||
|
;
|
||
|
|
||
|
extends_statement
|
||
|
: STMT_OPEN EXTENDS STRING STMT_CLOSE { result = val[2].value }
|
||
|
| STMT_OPEN EXTENDS IDENTIFIER STMT_CLOSE { result = VariableNode.new(val[2].value) }
|
||
|
;
|
||
|
|
||
|
document_component
|
||
|
: TEXT_BLOCK { result = TextNode.new(val[0].value) }
|
||
|
| inject_statement
|
||
|
| if_block
|
||
|
| for_block
|
||
|
| generic_block
|
||
|
| block_block
|
||
|
;
|
||
|
|
||
|
document
|
||
|
: document_component { push val[0] }
|
||
|
| document document_component { push val[1] }
|
||
|
| extends_statement { document.extends = val[0] }
|
||
|
| document extends_statement { document.extends = val[1] }
|
||
|
;
|
||
|
|
||
|
---- header ----
|
||
|
# racc_parser.rb : generated by racc
|
||
|
|
||
|
---- inner ----
|