All pastes #1068970 Raw Edit

Unnamed

public text v1 · immutable
#1068970 ·published 2008-07-11 08:36 UTC
rendered paste body

%{
	public class PdlrClass
	{
		string name, base_type;
		List<string> interfaces;
		List<PdlrMember> members;

		public PdlrClass (string name, string baseType, List<string> interfaces, List<PdlrMember> members)
		{
			this.name = name;
			this.base_type = baseType;
			this.interfaces = interfaces;
			this.members = members;
		}
	}

	public abstract class PdlrMember
	{
	}

%}

%token IDENTIFIER
%token NUMERIC_LITERAL
%token STRING_LITERAL
%token CLASS			"class"
%token EXTENDS			"extends"
%token IMPLEMENTS		"implements"
%token WHILE			"while"
%token BREAK			"break"
%token RETURN			"return"
%token IF			"if"
%token ELSE			"else"
%token FOR			"for"
%token SWITCH			"switch"
%token CASE			"case"
%token DEFAULT			"default"
%token NEW			"new"
%token TRUE			"true"
%token FALSE			"false"
%token THIS			"this"
%token SUPER			"super"
%token NULL			"null"
%token PLUS			"+"
%token MINUS			"-"
%token ASTERISK			"*"
%token SLASH			"/"
%token PERCENT			"%"
%token PLUS_EQUAL		"+="
%token MINUS_EQUAL		"-="
%token PLUS_PLUS		"++"
%token MINUS_MINUS		"--"
%token EQUAL			"="
%token EQUAL2			"=="
%token COMMA 			","
%token DOT 			"."
%token COLON 			":"
%token SEMICOLON		";"
%token QUESTION			"?"
%token EXCLAIM			"!"
%token EXCLAIM_EQUAL		"!="
%token AND 			"&"
%token AND2 			"&&"
%token BAR			"|"
%token BAR2			"||"
%token OPEN_CURLY		"{"
%token CLOSE_CURLY		"}"
%token OPEN_PAREN		"("
%token CLOSE_PAREN		")"
%token OPEN_BRACE		"["
%token CLOSE_BRACE		"]"
%token OPEN_ANGLE		"<"
%token OPEN_ANGLE2		"<<"
%token OPEN_ANGLE_EQUAL		"<="
%token CLOSE_ANGLE		">"
%token CLOSE_ANGLE2		">>"
%token CLOSE_ANGLE_EQUAL	">="

%start top_level_contents
%%

identifier : IDENTIFIER

top_level_contents
	: // empty
	{
		return new List<Expression> ();
	}
	| top_level_content top_level_contents
	{
		var l = (List<Expression>) $2;
		l.Insert (0, $1);
		$$ = l;
	}
	;

top_level_content
	: statements
	| callable_expression
	| class_declaration
	| global_function_definition
	;


global_function_definition
	: function_definition
	;

class_declaration
	: CLASS identifier
	  opt_derivation_indication opt_implementation_indications
	  OPEN_CURLY class_member_definitions CLOSE_CURLY
	{
		var name = (string) $2;
		var baseType = (string) $3;
		var interfaces = (List<string>) $4;
		var members = (List<PdlrMember>) $5;
		$$ = new PdlrClass (name, baseType, interfaces, members);
	}

opt_derivation_indication
	: { $$ = null; } // empty
	| derivation_indication
	;

opt_implementation_indications
	: { $$ = null; } // empty
	| implementation_indications
	;

derivation_indication
	: EXTENDS identifier
	{
		$$ = $2;
	}
	;

implementation_indications
	 : IMPLEMENTS identifier_list_comma
	 {
	 	$$ = $2;
	 }

identifier_list_comma
	: identifier
	{
		var l = new List<string> ();
		l.Add ($1);
		$$ = l;
	}
	| identifier COMMA identifier_list_comma
	{
		var l = (List<string>) $3;
		l.Insert (0, (string) $1);
		$$ = l;
	}
	;

class_member_definitions
	: { $$ = null; } // empty
	| class_member_definition class_member_definitions
	{
		var l = (List<PdlrMember>) $2 ?? new List<PdlrMember> ();
		l.Insert (0, (PdlrMember) $1);
		$$ = l;
	}

class_member_definition
	: field_definition
	| constructor_definition
	| function_definition

field_definition
	: variable_declaration_statement SEMICOLON { $$ = $1; }

constructor_definition
	: function_definition_base
	{
		$$ = new PdlrConstructor ((FunctionBase) $1);
	}

function_definition
	: type_name function_definition_base
	{
		$$ = new PdlrFunction ((string) $1, (FunctionBase) $2);
	}

function_definition_base
	: identifier OPEN_PAREN argument_definitions CLOSE_PAREN statement_block
	{
		$$ = new FunctionBase ((string) $1, (List<FunctionArgument>) $3, (List<Expression>) $5);
	}

argument_definitions
	: { $$ = null; } // empty
	| argument_definition COMMA argument_definitions
	{
		var l = (List<FunctionArgument>) $3 ?? new List<FunctionArgument> ();
		l.Insert (0, (FunctionArgument) $1);
		$$ = l;
	}

argument_definition
	: type_name identifier
	{
		$$ = new FunctionArgument ((string) $1, (string) $2);
	}

// Statements

statement_block
	: OPEN_CURLY statements CLOSE_CURLY
	{
		$$ = $2;
	}

statements
	: { $$ = null; } // empty
	| statement statements
	{
		var l = (List<Expression>) $2 ?? new List<Expression> ();
		l.Insert (0, (Expression) $1);
		$$ = l;
	}

statement
	: statement_with_semicolon SEMICOLON { $$ = $1; }
	| statement_without_semicolon

statement_with_semicolon
	: return_statement
	| abstract_assignment_statement
	| break_statement
	| increment_statement
	| decrement_statement
	| variable_declaration_statement
	| call_super_statement

statement_without_semicolon
	: if_statement
	| for_statement
	| while_statement
	| switch_statement

abstract_assignment_statement
	: assignment_statement
	| add_assignment_statement
	| subtract_assignment_statement

add_assignment_statement
	: expression PLUS_EQUAL expression
	{
		var e1 = (Expression) $1, e2 = (Expression) $3;
		$$ = Expression.Assign (e1, Expression.AddChecked (e1, e2));
	}

subtract_assignment_statement
	: expression MINUS_EQUAL expression
	{
		var e1 = (Expression) $1, e2 = (Expression) $3;
		$$ = Expression.Assign (e1, Expression.SubtractChecked (e1, e2));
	}

increment_statement
	: expression PLUS_PLUS // FIXME: no pre-positioned increment?
	{
		var e1 = (Expression) $1;
		$$ = Expression.Assign (e1, Expression.AddChecked (e1, Expression.Constant (1)));
	}

decrement_statement
	: expression MINUS_MINUS // FIXME: no pre-positioned increment?
	{
		var e1 = (Expression) $1;
		$$ = Expression.Assign (e1, Expression.SubtractChecked (e1, Expression.Constant (1)));
	}

call_super_statement
	: SUPER OPEN_PAREN function_args CLOSE_PAREN
	{
		// FIXME: get current type, find base constructor, and call it.
	}

return_statement
	: RETURN expression
	{
		$$ = Expression.Return ((Expression) $2);
	}

assignment_statement
	: variable_or_member_reference EQUAL expression
	{
		$$ = Expression.Assign ((Expression) $1, (Expression) $2);
	}

while_statement
	: WHILE OPEN_PAREN expression CLOSE_PAREN statement_block
	{
		$$ = Expression.Loop ((Expression) $3, null, Expression.Block (null, (List<Expression>) $5), Expression.Break (null), null);
	}

break_statement : BREAK { $$ = Expression.Break (null); }

/// variable-declaration

variable_declaration_statement
	: type_name opt_array_indicator variable_declaration_pairs SEMICOLON
	{
		// FIXME: CreateType() is not likely possible here.
		var l = new List<VariableExpression> ();
		Type t = CreateType ((string) $1, (bool) $2);
		foreach (VariableDeclarationPair p in $3)
			l.Add (Expression.Variable (t, 
	}

type_name : identifier

opt_array_indicator
	: { $$ = false; } // empty
	| OPEN_BRACE CLOSE_BRACE { $$ = true; }

variable_declaration_pairs
	: variable_declaration_pair
	{
		var l = new List<VariableDeclarationPair> ();
		l.Add ((VariableDeclarationPair) $1);
		$$ = l;
	}
	| variable_declaration_pair COMMA variable_declaration_pairs
	{
		var l = (List<VariableDeclarationPair>) $3;
		l.Insert (0, (VariableDeclarationPair) $1);
		$$ = l;
	}

variable_declaration_pair
	: identifier opt_variable_initializer
	{
		$$ = new VariableDeclarationPair ((string) $1, (Expression) $2);
	}

opt_variable_initializer
	: { $$ = null; } // empty
	| variable_initializer

variable_initializer
	: EQUAL expression
	{
		$$ = $2;
	}

/// if-else

if_statement
	: IF OPEN_PAREN expression CLOSE_PAREN statement_block opt_else_block
	{
		var cond = (Expression) $3;
		var tb = (List<Expression>) $5;
		var fb = (List<Expression>) $6;
		$$ = eb != null ?
			Expression.IfThenElse (cond, Expression.Block (tb), Expression.Block (fb)) :
			Expression.IfThen (cond, Expression.Block (tb));
	}

opt_else_block
	: { $$ = null; } // empty
	| else_block

else_block
	: ELSE statement_block { $$ = $2; }

/// for

for_statement
	: FOR OPEN_PAREN for_initializer SEMICOLON expression SEMICOLON
	for_continuations CLOSE_PAREN statement_block
	{
		var init = (List<Expression>) $3;
		var cond = (Expression) $5;
		var cont = (List<Expression>) $7;
		var loop = Expression.Loop (cond,
			cont != null ? Expression.Block (cont) : null,
			Expression.Block ((List<Expression>) $9),
			Expression.Break (null),
			new LabelTarget (null));
		$$ = init != null ? Expression.Block (init, loop) : loop;
	}

for_initializer
	: { $$ = null; } // empty
	| variable_declaration_statement
	| abstract_assignment_list

abstract_assignment_list
	: abstract_assignment_statement
	{
		var l = new List<Expression> ();
		l.Add ((Expression) $1);
		$$ = l;
	}
	| abstract_assignment_statement COMMA abstract_assignment_list
	{
		var l = (List<Expression>) $3;
		l.Insert (0, (Expression) $1);
		$$ = l;
	}

for_continuations : statements // FIXME: no constraints?

/// switch-case

switch_statement
	: SWITCH OPEN_PAREN expression CLOSE_PAREN
	  OPEN_CURLY switch_case_list CLOSE_CURLY
	{
		$$ = Expression.Switch (null, null, (Expression) $3, ((List<SwitchCase>) $6).ToArray ());
	}

switch_case_list
	: { $$ = new List<SwitchCase> (); } // empty
	| switch_case_default switch_case_list
		// switch_default cannot appear twice
	{
		var l = (List<SwitchCase>) $2;
		l.Insert (0, (SwitchCase) $1);
		$$ = l;
	}

switch_case_default
	: switch_case
	| switch_default

switch_case
	: CASE literal COLON statements
	{
		var l = (List<Expression>) $4;
		// must end with break_statement
		if (!(l [l.Length - 1] is BreakExpression))
			l.Add (Expression.Break (null));
		$$ = Expression.SwitchCase (GetIntValue ((ConstantExpression) $2), Expression.Block (l));
	}

switch_default
	: DEFAULT COLON statements
	{
		var l = (List<Expression>) $3;
		// must end with break_statement
		if (!(l [l.Length - 1] is BreakExpression))
			l.Add (Expression.Break (null));
		$$ = Expression.DefaultCase (Expression.Block (l));
	}

// Expressions

expression
	: callable_expression
	| operation_expression
	| variable_or_member_reference
	| literal
	| field_access_expression
	| super_expression
	| this_expression
	| new_expression
	| array_access_expression
	| null_expression
	| parenthesized_expression
	| numeric_negation_expression

variable_or_member_reference
	: identifier
	{
		// FIXME: how can I distinguish variable and field-or-property?
		// FIXME: how can I instantiate an Expression for varref?
	}

// new

new_expression
	: new_object_expression
	| new_array_expression

new_object_expression
	: NEW function_call_base
	{
		// FIXME: CreateType() is unlikely possible
		var fcb = KeyValuePair<string, List<Expression>> $2;
		// FIXME: no CallSiteBinder?
		$$ = Expression.New (CreateType (fcb.Key), null, fcb.Value);
	}

new_array_expression
	: NEW identifier OPEN_BRACE expression CLOSE_BRACE
	{
		// FIXME: CreateType() is unlikely possible
		$$ = Expression.NewArrayBounds (CreateType ((string) $2), (Expression) $4);
	}

// callable expressions

callable_expression
	: function_call_expression
	| function_access_expression

function_call_expression : function_call_base

function_call_base
	: identifier OPEN_PAREN function_args CLOSE_PAREN
	{
		$$ = new KeyValuePair<string, List<Expression>> ((string) $1, (List<Expression>) $3);
	}

function_args
	: { $$ = new List<Expression> (); } // empty
	| function_arg_list

function_arg_list
	: expression
	{
		var l = new List<Expression> ();
		l.Add ((Expression) $1);
		$$ = l;
	}
	| expression COMMA function_arg_list
	{
		var l = (List<Expression>) $3;
		l.Insert (0, (Expression) $1);
		$$ = l;
	}

literal
	: string_literal
	| numeric_literal
	| true_expression
	| false_expression

true_expression := TRUE { $$ = Expression.TRue (); }

false_expression : FALSE { $$ = Expression.False (); }

numeric_literal : NUMERIC_LITERAL

string_literal : STRING_LITERAL

/// operation expressions

operation_expression
	: comparison_expression
	| logical_operation_expression
	| arithmetic_expression

comparison_expression
	: less_than_expression
	| less_eq_expression
	| greater_than_expression
	| greater_eq_expression
	| eq_expression
	| not_eq_expression
	| conditional_expression

logical_operation_expression
	: logical_or_expression
	| logical_and_expression
	| logical_not_expression

arithmetic_expression
	: additive_expression
	| multiplicative_expression

additive_expression
	: add_expression
	| subtract_expression
	| bitwise_and_expression
	| bitwise_or_expression
	| left_shift_expression
	| right_shift_expression

multiplicative_expression
	: multiply_expression
	| divide_expression
	| modulo_expression

// FIXME: "expression" in below items need to be more specific.
// For example, First expression in "additive_expression" is 
// "multiplicative_expression" (for operator priority)

field_access_expression
	: expression DOT identifier
	{
		$$ = Expression.PropertyOrField ((Expression) $1, (string) $3);
	}

function_access_expression
	: expression DOT function_call_base
	{
		var inst = (Expression) $1;
		var fcb = (KeyValuePair<string, List<Expression>>) $3;
		// FIXME: GetMethod() is unlikely possible
		$$ = Expression.Call (inst, GetMethod (inst, fcb.Key), fcb.Value.ToArray ());
	}

super_expression
	: SUPER
	{
		// FIXME: needs current type context, Type, and then base type
	}

this_expression := THIS { } // FIXME: how can I represent it?

array_access_expression
	: expression OPEN_BRACE expression CLOSE_BRACE
	{
		$$ = Expression.ArrayIndex ((Expression) $1, (Expression) $3);
	}

null_expression : NULL { $$ = Expression.Null (); }

parenthesized_expression : OPEN_PAREN expression CLOSE_PAREN { $$ = $2; }

less_than_expression
	: expression OPEN_ANGLE expression
	{ $$ = Expression.LessThan ((Expression) $1, (Expression) $3); }

less_eq_expression
	: expression OPEN_ANGLE_EQUAL expression
	{ $$ = Expression.LessThanOrEqual ((Expression) $1, (Expression) $3); }

greater_than_expression
	:  expression CLOSE_ANGLE expression
	{ $$ = Expression.GreaterThan ((Expression) $1, (Expression) $3); }

greater_eq_expression
	: expression CLOSE_ANGLE_EQUAL expression
	{ $$ = Expression.GreaterThanOrEqual ((Expression) $1, (Expression) $3); }

eq_expression
	: expression EQUAL2 expression
	{ $$ = Expression.Equal ((Expression) $1, (Expression) $3); }

not_eq_expression
	: expression EXCLAIM_EQUAL expression
	{ $$ = Expression.NotEqual ((Expression) $1, (Expression) $3); }

conditional_expression
	: expression QUESTION expression COLON expression
	{ $$ = Expression.Condition ((Expression) $1, (Expression) $3, (Expression) $5); }

logical_or_expression
	: expression BAR2 expression
	{ $$ = Expression.OrElse ((Expression) $1, (Expression) $3); }

logical_and_expression 
	: expression AND2 expression
	{ $$ = Expression.AndAlso ((Expression) $1, (Expression) $3); }

logical_not_expression
	: EXCLAIM expression
	{ $$ = Expression.Not ((Expression) $1); }

add_expression
	: expression PLUS expression
	{ $$ = Expression.AddChecked ((Expression) $1, (Expression) $3); }

subtract_expression 
	: expression MINUS expression
	{ $$ = Expression.SubtractChecked ((Expression) $1, (Expression) $3); }

numeric_negation_expression
	: MINUS expression
	{ $$ = Expression.MultiplyChecked ((Expression) $1, Expression.Constant (-1)); }

multiply_expression
	: expression ASTERISK expression
	{ $$ = Expression.MultiplyChecked ((Expression) $1, (Expression) $3); }

divide_expression
	: expression SLASH expression
	{ $$ = Expression.DivideChecked ((Expression) $1, (Expression) $3); }

modulo_expression 
	: expression PERCENT expression
	{ $$ = Expression.Modulo Checked ((Expression) $1, (Expression) $3); }

bitwise_and_expression 
	: expression AND expression
	{ $$ = Expression.And ((Expression) $1, (Expression) $3); }

bitwise_or_expression 
	: expression BAR expression
	{ $$ = Expression.Or ((Expression) $1, (Expression) $3); }

left_shift_expression 
	: expression OPEN_ANGLE2 expression
	{ $$ = Expression.LeftShift ((Expression) $1, (Expression) $3); }

right_shift_expression
	: expression CLOSE_ANGLE2 expression
	{ $$ = Expression.RightShift ((Expression) $1, (Expression) $3); }