Created
November 21, 2009 11:02
-
-
Save atsushieno/240096 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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