Skip to content

Instantly share code, notes, and snippets.

@atsushieno
Created November 21, 2009 11:02
Show Gist options
  • Save atsushieno/240096 to your computer and use it in GitHub Desktop.
Save atsushieno/240096 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Irony.Parsing;
namespace FreeActionScript
{
[Language ("ActionScript", "3.0-", "ActionScript pseudo grammar")]
public class ActionScriptGrammar : Grammar
{
public ActionScriptGrammar ()
{
CommentTerminal single_line_comment = new CommentTerminal ("SingleLineComment", "//", "\r", "\n");
CommentTerminal delimited_comment = new CommentTerminal ("DelimitedComment", "/*", "*/");
NonGrammarTerminals.Add (single_line_comment);
NonGrammarTerminals.Add (delimited_comment);
// FIXME: should be generic identifiers or its own.
IdentifierTerminal identifier = TerminalFactory.CreateCSharpIdentifier ("Identifier");
identifier.AllFirstChars += "$";
StringLiteral string_literal = TerminalFactory.CreateCSharpString ("StringLiteral");
StringLiteral char_literal = new StringLiteral ("CharLiteral", "'");
NumberLiteral numeric_literal = TerminalFactory.CreateCSharpNumber ("Number");
RegExLiteral regex_literal = new RegExLiteral ("RegEx");
regex_literal.Switches.Add ('s', RegexOptions.None); // FIXME: other than None
// keywords
KeyTerm keyword_package = ToTerm ("package");
KeyTerm keyword_import = ToTerm ("import");
KeyTerm keyword_use = ToTerm ("use");
KeyTerm keyword_namespace = ToTerm ("namespace");
KeyTerm keyword_class = ToTerm ("class");
KeyTerm keyword_extends = ToTerm ("extends");
KeyTerm keyword_public = ToTerm ("public");
KeyTerm keyword_internal = ToTerm ("internal");
KeyTerm keyword_private = ToTerm ("private");
KeyTerm keyword_static = ToTerm ("static");
KeyTerm keyword_dynamic = ToTerm ("dynamic");
KeyTerm keyword_override = ToTerm ("override");
KeyTerm keyword_const = ToTerm ("const");
KeyTerm keyword_var = ToTerm ("var");
KeyTerm keyword_function = ToTerm ("function");
KeyTerm keyword_get = ToTerm ("get");
KeyTerm keyword_set = ToTerm ("set");
KeyTerm keyword_throw = ToTerm ("throw");
KeyTerm keyword_try = ToTerm ("try");
KeyTerm keyword_catch = ToTerm ("catch");
KeyTerm keyword_finally = ToTerm ("finally");
KeyTerm keyword_return = ToTerm ("return");
KeyTerm keyword_if = ToTerm ("if");
KeyTerm keyword_else = ToTerm ("else");
KeyTerm keyword_switch = ToTerm ("switch");
KeyTerm keyword_case = ToTerm ("case");
KeyTerm keyword_default = ToTerm ("default");
KeyTerm keyword_while = ToTerm ("while");
KeyTerm keyword_do = ToTerm ("do");
KeyTerm keyword_for = ToTerm ("for");
KeyTerm keyword_each = ToTerm ("each");
KeyTerm keyword_in = ToTerm ("in");
KeyTerm keyword_break = ToTerm ("break");
KeyTerm keyword_continue = ToTerm ("continue");
KeyTerm keyword_null = ToTerm ("null");
KeyTerm keyword_new = ToTerm ("new");
KeyTerm keyword_is = ToTerm ("is");
KeyTerm keyword_as = ToTerm ("as");
// operators (copied from CSharpGrammar)
/*
RegisterOperators (1, "||");
RegisterOperators (2, "&&");
RegisterOperators (3, "|");
RegisterOperators (5, "&");
RegisterOperators (6, "==", "!=");
RegisterOperators (7, "<", ">", "<=", ">=", "is", "as");
RegisterOperators (8, "<<", ">>");
RegisterOperators (9, "++", "--");
RegisterOperators (10, "+", "-");
RegisterOperators (11, "*", "/", "%");
RegisterOperators (12, ".");
*/
var compile_unit = new NonTerminal ("compile_unit");
var package_decls = new NonTerminal ("package_declarations");
var package_decl = new NonTerminal ("package_declaration");
var package_name = new NonTerminal ("package_name");
var package_contents = new NonTerminal ("package_contents");
var namespace_decl = new NonTerminal ("namespace_declaration");
var import = new NonTerminal ("import");
var namespace_uses = new NonTerminal ("namespace_uses");
var namespace_use = new NonTerminal ("namespace_use");
var type_name_wild = new NonTerminal ("type_name_wild");
var class_decl = new NonTerminal ("class_declaration");
var access_modifier = new NonTerminal ("access_modifier");
var opt_extends = new NonTerminal ("opt_extends");
var class_members = new NonTerminal ("class_members");
var class_member = new NonTerminal ("class_member");
var member_header = new NonTerminal ("member_header");
var constant_declaration = new NonTerminal ("constant_declaration");
var field_declaration = new NonTerminal ("field_declaration");
var property_function = new NonTerminal ("property_function");
var property_getter = new NonTerminal ("property_getter");
var property_setter = new NonTerminal ("property_setter");
var general_function = new NonTerminal ("general_function");
var general_function_headless = new NonTerminal ("general_function_headless");
var function_nameless = new NonTerminal ("function_nameless");
var constructor = new NonTerminal ("constructor");
var argument_decls = new NonTerminal ("argument_declarations");
var varargs_decl = new NonTerminal ("varargs_decl");
var named_argument_decls = new NonTerminal ("named_argument_declarations");
var argument_decl = new NonTerminal ("argument_declaration");
var argument_type = new NonTerminal ("argument_type");
var qualified_reference = new NonTerminal ("qualified_reference");
var type_name = qualified_reference;//new NonTerminal ("type_name");
var member_reference = new NonTerminal ("member_reference");
var assignment_opt = new NonTerminal ("assignment_opt");
var lvalue = new NonTerminal ("lvalue");
var function_body = new NonTerminal ("function_body");
var statements = new NonTerminal ("statements");
var statement = new NonTerminal ("statement");
var statement_lacking_colon = new NonTerminal ("statement_lacking_colon");
var local_function_declaration = new NonTerminal ("local_function_declaration");
var assign_statement = new NonTerminal ("assign_statement");
var calc_assign_statement = new NonTerminal ("calc_assign_statement");
var return_statement = new NonTerminal ("return_statement");
var function_call_statement = new NonTerminal ("function_call_statement");
var call_arguments = new NonTerminal ("call_arguments");
var call_argument = new NonTerminal ("call_argument");
var local_var_decl_statement = new NonTerminal ("local_var_decl_statement");
var name_value_pairs = new NonTerminal ("name_value_pairs");
var name_value_pair = new NonTerminal ("name_value_pair");
var if_statement = new NonTerminal ("if_statement");
var else_block = new NonTerminal ("else_block");
var switch_statement = new NonTerminal ("switch_statement");
var switch_cond_blocks = new NonTerminal ("switch_conditional_blocks");
var switch_cond_block = new NonTerminal ("switch_cond_block");
var condition_label = new NonTerminal ("condition_label");
var while_statement = new NonTerminal ("while_statement");
var do_while_statement = new NonTerminal ("do_while_statement");
var for_statement = new NonTerminal ("for_statement");
var for_statement_remaining = new NonTerminal ("for_statement_remaining");
var for_c_style_statement = new NonTerminal ("for_c_style_statement");
var for_in_statement = new NonTerminal ("for_in_statement");
var for_initializers = new NonTerminal ("for_initializers");
var for_assign_statements = new NonTerminal ("for_assign_statements");
var for_iterators = new NonTerminal ("for_iterators");
var for_iterator = new NonTerminal ("for_iterator");
var for_each_statement = new NonTerminal ("for_each_statement");
var for_each_iterator = new NonTerminal ("for_each_iterator");
var break_statement = new NonTerminal ("break_statement");
var continue_statement = new NonTerminal ("continue_statement");
var throw_statement = new NonTerminal ("throw_statement");
var try_statement = new NonTerminal ("try_statement");
var try_block = new NonTerminal ("try_block");
var catch_block = new NonTerminal ("catch_block");
var exception_type_part = new NonTerminal ("exception_type_part");
var finally_block = new NonTerminal ("finally_block");
var block_statement = new NonTerminal ("block_statement");
var expression = new NonTerminal ("expression");
var assignment_expression = new NonTerminal ("assignment_expression");
var conditional_expression = new NonTerminal ("conditional_expression");
var or_expression = new NonTerminal ("or_expression");
var and_expression = new NonTerminal ("and_expression");
var equality_expression = new NonTerminal ("equality_expression");
var relational_expression = new NonTerminal ("relational_expression");
var additive_expression = new NonTerminal ("additive_expression");
var multiplicative_expression = new NonTerminal ("multiplicative_expression");
var shift_expression = new NonTerminal ("shift_expression");
var unary_expression = new NonTerminal ("unary_expression");
var inc_dec_expression = new NonTerminal ("inc_dec_expression");
var union_expression = new NonTerminal ("union_expression");
var iteration_expression = new NonTerminal ("iteration_expression");
var array_access_expression = new NonTerminal ("array_access_expression");
var primary_expression = new NonTerminal ("primary_expression");
var function_call_expression = new NonTerminal ("function_call_expression");
var member_reference_expression = new NonTerminal ("member_reference_expression");
var field_reference_expression = new NonTerminal ("field_reference_expression");
var new_object_expression = new NonTerminal ("new_object_expression");
var literal_array_expression = new NonTerminal ("literal_array_expression");
var array_items = new NonTerminal ("array_items");
var literal_hash_expression = new NonTerminal ("literal_hash_expression");
var hash_items = new NonTerminal ("hash_items");
var hash_item = new NonTerminal ("hash_item");
var as_expression = new NonTerminal ("as_expression");
var embedded_function_expression = new NonTerminal ("embedded_function_expression");
var literal = new NonTerminal ("literal");
// non-terminals
this.Root = compile_unit;
compile_unit.Rule = MakeStarRule (compile_unit, null, (package_decl | import | class_decl));
package_decl.Rule = keyword_package + package_name + "{" + package_contents + "}";
package_name.Rule = qualified_reference;
package_contents.Rule = MakeStarRule (package_contents, null, import | member_header + (namespace_decl | class_decl));
namespace_decl.Rule = keyword_namespace + identifier + ";";
import.Rule = keyword_import + type_name_wild + ";" + ReduceHere ();
namespace_uses.Rule = MakeStarRule (namespace_uses, null, namespace_use);
namespace_use.Rule = keyword_use + keyword_namespace + identifier + ";" + ReduceHere ();
class_decl.Rule = keyword_class + identifier + opt_extends + "{" + namespace_uses + class_members + "}" + ReduceHere ();
opt_extends.Rule = Empty | keyword_extends + identifier;
// class member
access_modifier.Rule = keyword_public | keyword_internal | keyword_private | identifier;
class_members.Rule = MakeStarRule (class_members, null, class_member);
class_member.Rule = constant_declaration | field_declaration | property_function | general_function | constructor ;
member_header.Rule = MakeStarRule (member_header, null, Empty | keyword_static | keyword_dynamic | keyword_override | access_modifier);
// field and constant
constant_declaration.Rule = member_header + keyword_const + identifier + ":" + type_name + "=" + expression + (Empty | ";");
field_declaration.Rule = member_header + keyword_var + name_value_pairs + (Empty | ";");
assignment_opt.Rule = Empty | "=" + expression;
// functions
property_function.Rule = property_getter | property_setter;
property_getter.Rule = member_header + keyword_function + keyword_get + identifier + "(" + ")" + ":" + type_name + "{" + function_body + "}";
property_setter.Rule = member_header + keyword_function + keyword_set + identifier + "(" + identifier + ":" + type_name + ")" + ":" + "void" + "{" + function_body + "}";
function_body.Rule = statements;
general_function.Rule = member_header + general_function_headless;
general_function_headless.Rule = keyword_function + identifier + function_nameless;
function_nameless.Rule = "(" + argument_decls + ")" + (Empty | ":" + type_name_wild) + "{" + function_body + "}";
constructor.Rule = keyword_function + identifier + "(" + argument_decls + ")" + "{" + function_body + "}";
argument_decls.Rule = MakeStarRule (named_argument_decls, ToTerm (","), argument_decl);
argument_decl.Rule = // FIXME: there is an ambiguation issue; on foo.<bar>=baz ">=" conflicts with comparison operator.
identifier + ":" + argument_type + assignment_opt
| varargs_decl
;
varargs_decl.Rule = "..." + identifier;
argument_type.Rule = type_name_wild;
// statements
statements.Rule = MakeStarRule (statements, null, statement);
statement.Rule =
statement_lacking_colon + ";"
| if_statement
| switch_statement
| while_statement
| do_while_statement
| for_statement
| for_each_statement
| block_statement
| try_statement
| local_function_declaration
;
local_function_declaration.Rule = general_function_headless;
statement_lacking_colon.Rule =
assign_statement
| calc_assign_statement
| return_statement
| function_call_statement
| local_var_decl_statement
| break_statement
| continue_statement
| throw_statement
;
assign_statement.Rule = assignment_expression;
calc_assign_statement.Rule =
inc_dec_expression
| lvalue + "+=" + expression
| lvalue + "-=" + expression
| lvalue + "*=" + expression
| lvalue + "/=" + expression
| lvalue + "%=" + expression
| lvalue + "&=" + expression
| lvalue + "|=" + expression
| lvalue + "<<=" + expression
| lvalue + ">>=" + expression
;
return_statement.Rule =
keyword_return
| keyword_return + expression;
function_call_statement.Rule = function_call_expression;
if_statement.Rule =
keyword_if + "(" + expression + ")" + statement + else_block;
else_block.Rule = Empty | PreferShiftHere () + keyword_else + statement;
switch_statement.Rule =
keyword_switch + "(" + expression + ")" + "{" + switch_cond_blocks + "}";
switch_cond_blocks.Rule = MakeStarRule (switch_cond_blocks, null, switch_cond_block);
switch_cond_block.Rule = condition_label + ":" + statements;
condition_label.Rule =
keyword_case + literal
| keyword_case + qualified_reference // identifier, or constant
| keyword_default;
while_statement.Rule = keyword_while + "(" + expression + ")" + statement;
do_while_statement.Rule = keyword_do + statement + keyword_while + "(" + expression + ")" + ";";
for_statement.Rule = keyword_for + "(" + for_statement_remaining;
for_statement_remaining.Rule = for_c_style_statement | for_in_statement;
for_c_style_statement.Rule = for_initializers + ";" + expression + ";" + for_iterators + ")" + statement;
for_in_statement.Rule = for_each_iterator + keyword_in + expression + ")" + statement;
for_initializers.Rule = local_var_decl_statement | for_assign_statements | identifier;
for_assign_statements.Rule = MakeStarRule (for_assign_statements, ToTerm (","), assign_statement);
for_iterators.Rule = MakeStarRule (for_iterators, ToTerm (","), for_iterator);
for_iterator.Rule = assign_statement | calc_assign_statement;
for_each_statement.Rule = keyword_for + keyword_each + "(" + for_each_iterator + keyword_in + expression + ")" + statement;
for_each_iterator.Rule = identifier | keyword_var + identifier + ":" + argument_type;
break_statement.Rule = keyword_break;
continue_statement.Rule = keyword_continue;
throw_statement.Rule = keyword_throw + expression;
try_statement.Rule = try_block + catch_block + finally_block;
try_block.Rule = keyword_try + "{" + statements + "}";
catch_block.Rule = keyword_catch + exception_type_part + "{" + statements + "}";
exception_type_part.Rule = Empty | ToTerm ("(") + identifier + ":" + type_name + ")";
finally_block.Rule = Empty | keyword_finally + "{" + statements + "}";
block_statement.Rule = ToTerm ("{") + statements + "}";
local_var_decl_statement.Rule = keyword_var + name_value_pairs;
name_value_pairs.Rule = MakePlusRule (name_value_pairs, ToTerm (","), name_value_pair);
name_value_pair.Rule = identifier + ":" + argument_type + assignment_opt;
// expressions
expression.Rule =
conditional_expression
| assignment_expression;
assignment_expression.Rule =
lvalue + "=" + expression
| lvalue + "=" + assignment_expression
;
conditional_expression.Rule =
or_expression
| or_expression + "?" + conditional_expression + ":" + conditional_expression;
or_expression.Rule =
and_expression
| or_expression + "||" + and_expression;
and_expression.Rule =
equality_expression
| and_expression + "&&" + equality_expression;
equality_expression.Rule =
relational_expression
| equality_expression + "===" + relational_expression
| equality_expression + "!==" + relational_expression
| equality_expression + "==" + relational_expression
| equality_expression + "!=" + relational_expression
| equality_expression + keyword_is + relational_expression;
relational_expression.Rule =
additive_expression
| relational_expression + "<" + additive_expression
| relational_expression + "<=" + additive_expression
| relational_expression + ">" + additive_expression
| relational_expression + ">=" + additive_expression;
additive_expression.Rule =
multiplicative_expression
| additive_expression + "+" + multiplicative_expression
| additive_expression + "-" + multiplicative_expression;
multiplicative_expression.Rule =
as_expression
| multiplicative_expression + "*" + as_expression
| multiplicative_expression + "/" + as_expression
| multiplicative_expression + "%" + as_expression;
as_expression.Rule =
shift_expression
| shift_expression + keyword_as + type_name;
shift_expression.Rule =
union_expression
| shift_expression + "<<<" + union_expression
| shift_expression + "<<" + union_expression
| shift_expression + ">>>" + union_expression
| shift_expression + ">>" + union_expression;
union_expression.Rule =
unary_expression
| union_expression + "&" + unary_expression
| union_expression + "|" + unary_expression
| union_expression + "^" + unary_expression;
unary_expression.Rule =
iteration_expression
| inc_dec_expression
| ToTerm ("-") + iteration_expression
| ToTerm ("!") + iteration_expression;
inc_dec_expression.Rule =
member_reference_expression + ToTerm ("++")
| member_reference_expression + ToTerm ("--")
| ToTerm ("++") + member_reference_expression
| ToTerm ("--") + member_reference_expression;
iteration_expression.Rule = // weird, but "!x in y" is parsed as "!(x in y)"
array_access_expression
| literal_hash_expression
| array_access_expression + keyword_in + array_access_expression;
array_access_expression.Rule =
primary_expression
| array_access_expression + "[" + expression + "]"
;
primary_expression.Rule =
member_reference_expression
| function_call_expression
| ToTerm ("(") + expression + ")"
| new_object_expression
| literal_array_expression
| literal
| embedded_function_expression;
lvalue.Rule =
member_reference_expression
;
literal.Rule = numeric_literal | string_literal | char_literal | regex_literal | keyword_null;
member_reference_expression.Rule =
field_reference_expression
// This is required for lvalue.
| member_reference_expression + "[" + expression + "]";
field_reference_expression.Rule = member_reference;
function_call_expression.Rule = member_reference_expression + "(" + call_arguments + ")";
call_arguments.Rule = MakeStarRule (call_arguments, ToTerm (","), call_argument);
call_argument.Rule = expression;
member_reference.Rule =
identifier // FIXME: what should I do here? unify with qualified_reference? but some requires expression
| primary_expression + "." + identifier
| primary_expression + "::" + identifier
| primary_expression + ".<" + type_name + ">"
;
new_object_expression.Rule = keyword_new + type_name + "(" + call_arguments + ")";
literal_array_expression.Rule = ToTerm ("[") + array_items + "]";
array_items.Rule = MakeStarRule (array_items, ToTerm (","), expression);
literal_hash_expression.Rule = ToTerm ("{") + hash_items + "}";
hash_items.Rule = MakeStarRule (hash_items, ToTerm (","), hash_item);
hash_item.Rule = (identifier | literal) + ":" + expression;
embedded_function_expression.Rule = keyword_function + function_nameless;
// this contains both type name (which includes generic) and member reference, but it's easier to treat them as identical.
qualified_reference.Rule =
identifier
| qualified_reference + "." + identifier
| qualified_reference + ".<" + type_name + ">";
type_name_wild.Rule = qualified_reference | qualified_reference + ".*" | "*";
//type_name.Rule = qualified_reference;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment