public ASLGrammar()
            : base(true)
        {
            var string_lit = TerminalFactory.CreateCSharpString("string");
            var number = TerminalFactory.CreateCSharpNumber("number");
            var identifier = TerminalFactory.CreateCSharpIdentifier("identifier");
            var code = new CustomTerminal("code", MatchCodeTerminal);

            var single_line_comment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
            var delimited_comment = new CommentTerminal("DelimitedComment", "/*", "*/");
            NonGrammarTerminals.Add(single_line_comment);
            NonGrammarTerminals.Add(delimited_comment);

            var state = new KeyTerm("state", "state");
            var init = new KeyTerm("init", "init");
            var exit = new KeyTerm("exit", "exit");
            var update = new KeyTerm("update", "update");
            var start = new KeyTerm("start", "start");
            var split = new KeyTerm("split", "split");
            var reset = new KeyTerm("reset", "reset");
            var startup = new KeyTerm("startup", "startup");
            var shutdown = new KeyTerm("shutdown", "shutdown");
            var isLoading = new KeyTerm("isLoading", "isLoading");
            var gameTime = new KeyTerm("gameTime", "gameTime");
            var comma = ToTerm(",", "comma");
            var semi = ToTerm(";", "semi");

            var root = new NonTerminal("root");
            var state_def = new NonTerminal("stateDef");
            var version = new NonTerminal("version");
            var state_list = new NonTerminal("stateList");
            var method_list = new NonTerminal("methodList");
            var var_list = new NonTerminal("varList");
            var var = new NonTerminal("var");
            var module = new NonTerminal("module");
            var method = new NonTerminal("method");
            var offset_list = new NonTerminal("offsetList");
            var offset = new NonTerminal("offset");
            var method_type = new NonTerminal("methodType");

            root.Rule = state_list + method_list;
            version.Rule = (comma + string_lit) | Empty;
            state_def.Rule = state + "(" + string_lit + version + ")" + "{" + var_list + "}";
            state_list.Rule = MakeStarRule(state_list, state_def);
            method_list.Rule = MakeStarRule(method_list, method);
            var_list.Rule = MakeStarRule(var_list, semi, var);
            module.Rule = (string_lit + comma) | Empty;
            var.Rule = (identifier + identifier + ":" + module + offset_list) | Empty;
            method.Rule = (method_type + "{" + code + "}") | Empty;
            offset_list.Rule = MakePlusRule(offset_list, comma, offset);
            offset.Rule = number;
            method_type.Rule = init | exit | update | start | split | isLoading | gameTime | reset | startup | shutdown;

            Root = root;

            MarkTransient(var_list, method_list, offset, method_type);

            LanguageFlags = LanguageFlags.NewLineBeforeEOF;
        }
        public ASLGrammar()
            : base(true)
        {
            var stringLit = TerminalFactory.CreateCSharpString("string");
            var number = TerminalFactory.CreateCSharpNumber("number");
            var identifier = TerminalFactory.CreateCSharpIdentifier("identifier");
            var code = new CustomTerminal("code", MatchCodeTerminal);
            var singleLineComment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
            var delimitedComment = new CommentTerminal("DelimitedComment", "/*", "*/");
            NonGrammarTerminals.Add(singleLineComment);
            NonGrammarTerminals.Add(delimitedComment);

            var state = new KeyTerm("state", "state");
            var start = new KeyTerm("start", "start");
            var split = new KeyTerm("split", "split");
            var reset = new KeyTerm("reset", "reset");
            var isLoading = new KeyTerm("isLoading", "isLoading");
            var gameTime = new KeyTerm("gameTime", "gameTime");
            var comma = ToTerm(",", "comma");
            var semi = ToTerm(";", "semi");

            var root = new NonTerminal("root");
            var stateDef = new NonTerminal("stateDef");
            var methodList = new NonTerminal("methodList");
            var varList = new NonTerminal("varList");
            var var = new NonTerminal("var");
            var method = new NonTerminal("method");
            var offsetList = new NonTerminal("offsetList");
            var offset = new NonTerminal("offset");
            var methodType = new NonTerminal("methodType");

            root.Rule = stateDef + methodList;
            stateDef.Rule = state + "(" + stringLit + ")" + "{" + varList + "}";
            methodList.Rule = MakeStarRule(methodList, method);
            varList.Rule = MakeStarRule(varList, semi, var);
            var.Rule = (identifier + identifier + ":" + stringLit + comma + offsetList) | Empty;
            method.Rule = (methodType + "{" + code + "}") | Empty;
            offsetList.Rule = MakePlusRule(offsetList, comma, offset);
            offset.Rule = number;
            methodType.Rule = start | split | isLoading | gameTime | reset;

            this.Root = root;

            MarkTransient(varList, methodList, offset, methodType);

            this.LanguageFlags = LanguageFlags.NewLineBeforeEOF;
        }
        public FunctionGrammer()
        {
            //Terminals
            var StringLiteral = TerminalFactory.CreateCSharpString("StringLiteral");
            var CharLiteral = TerminalFactory.CreateCSharpChar("CharLiteral");
            var Number = TerminalFactory.CreateCSharpNumber("Number");
            var identifier = TerminalFactory.CreateCSharpIdentifier("Identifier");
            //var guid_part_8 = new FixedLengthLiteral("guid_part_8", 8, TypeCode.String);
            //var guid_part_4 = new FixedLengthLiteral("guid_part_4", 4, TypeCode.String);
            //var guid_part_12 = new FixedLengthLiteral("guid_part_12", 12, TypeCode.String);
            var guid_variable = new CustomTerminal("guid_variable", delegate(Terminal terminal, ParsingContext context, ISourceStream source)
                {
                    var start = source.PreviewPosition;
                    if (source.PreviewChar == '@'
                        && source.NextPreviewChar == '{'
                        && source.Text.Length - start >= 39) // There are enough characters left to make a guid + @ symbol
                    {
                        Guid parsed_guid;
                        var guid_candidate = source.Text.Substring(start + 1, 38);
                        if (TryStrToGuid(guid_candidate, out parsed_guid))
                        {
                            source.PreviewPosition = source.PreviewPosition + 39;
                            return source.CreateToken(terminal, source.Text.Substring(start, 39));
                        }
                    }
                    return null;
                });

            //Symbols
            KeyTerm colon = ToTerm(":", "colon");
            KeyTerm semi = ToTerm(";", "semi");
            KeyTerm comma = ToTerm(",", "comma");
            KeyTerm Lbr = ToTerm("{");
            KeyTerm Rbr = ToTerm("}");
            KeyTerm Lpar = ToTerm("(");
            KeyTerm Rpar = ToTerm(")");
            KeyTerm qmark = ToTerm("?", "qmark");
            KeyTerm at = ToTerm("@", "At");
            KeyTerm hyphen = ToTerm("-");

            //Nonterminals
            var argument_list = new NonTerminal("argument_list");
            var argument_list_opt = new NonTerminal("argument_list_opt");
            var argument_list_par = new NonTerminal("argument_list_par");
            var argument_list_par_opt = new NonTerminal("argument_list_par_opt");
            var bin_op = new NonTerminal("bin_op", "operator symbol");
            var bin_op_expression = new NonTerminal("bin_op_expression");
            //var conditional_expression = new NonTerminal("conditional_expression");
            var expression = new NonTerminal("expression");
            var function_expression = new NonTerminal("function_expression");
            //var guid = new NonTerminal("guid");
            //var guid_variable = new NonTerminal("guid_variable");
            var literal = new NonTerminal("literal");
            var parenthesized_expression = new NonTerminal("parenthesized_expression");
            var primary_expression = new NonTerminal("primary_expression");
            //var typecast_expression = new NonTerminal("typecast_expression");
            var unary_expression = new NonTerminal("unary_expression");
            var unary_operator = new NonTerminal("unary_operator");
            var qual_name_with_targs = new NonTerminal("qual_name_with_targs");

            #region From CSharpGrammer

            #region operators, punctuation and delimiters
            RegisterOperators(1, "||");
            RegisterOperators(2, "&&");
            RegisterOperators(3, "|");
            RegisterOperators(4, "^");
            RegisterOperators(5, "&");
            RegisterOperators(6, "==", "!=");
            RegisterOperators(7, "<", ">", "<=", ">=", "is", "as");
            RegisterOperators(8, "<<", ">>");
            RegisterOperators(9, "+", "-");
            RegisterOperators(10, "*", "/", "%");
            //RegisterOperators(11, ".");
            // RegisterOperators(12, "++", "--");

            //The following makes sense, if you think about "?" in context of operator precedence.
            // What we say here is that "?" has the lowest priority among arithm operators.
            // Therefore, the parser should prefer reduce over shift when input symbol is "?".
            // For ex., when seeing ? in expression "a + b?...", the parser will perform Reduce:
            //  (a + b)->expr
            // and not shift the "?" symbol.
            // Same goes for ?? symbol
            RegisterOperators(-3, "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=");
            RegisterOperators(-2, "?");
            RegisterOperators(-1, "??");

            this.Delimiters = "{}[](),:;+-*/%&|^!~<>=";
            this.MarkPunctuation(";", ",", "(", ")", "{", "}", "[", "]", ":");
            this.MarkTransient(expression, literal, bin_op, primary_expression, expression);

            this.AddTermsReportGroup("assignment", "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=");
            this.AddTermsReportGroup("typename", "bool", "decimal", "float", "double", "string", "object", "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "char");
            this.AddTermsReportGroup("statement", "if", "switch", "do", "while", "for", "foreach", "continue", "goto", "return", "try", "yield", "break", "throw", "unchecked", "using");
            this.AddTermsReportGroup("type declaration", "public", "private", "protected", "static", "internal", "sealed", "abstract", "partial", "class", "struct", "delegate", "interface", "enum");
            this.AddTermsReportGroup("member declaration", "virtual", "override", "readonly", "volatile", "extern");
            this.AddTermsReportGroup("constant", Number, StringLiteral, CharLiteral);
            this.AddTermsReportGroup("constant", "true", "false", "null");

            this.AddTermsReportGroup("unary operator", "+", "-", "!", "~");

            this.AddToNoReportGroup(comma, semi);
            this.AddToNoReportGroup("var", "const", "new", "++", "--", "this", "base", "checked", "lock", "typeof", "default", "{", "}", "[");

            #endregion
            #endregion

            //Rules
            //guid.Rule = guid_part_8 + hyphen + guid_part_4 + hyphen + guid_part_4 + hyphen + guid_part_4 + hyphen + guid_part_12;
            //guid_variable.Rule = at + Lbr + guid + Rbr;
            bin_op.Rule = ToTerm("<") | "||" | "&&" | "|" | "&" | "==" | "!=" | ">" | "<=" | ">=" | "+" | "-" | "*" | "/" | "%";
            argument_list.Rule = MakePlusRule(argument_list, comma, expression);
            argument_list_opt.Rule = Empty | argument_list;
            argument_list_par.Rule = Lpar + argument_list_opt + Rpar;
            argument_list_par_opt.Rule = Empty | argument_list_par;
            bin_op_expression.Rule = expression + bin_op + expression;
            parenthesized_expression.Rule = Lpar + expression + Rpar;
            //typecast_expression.Rule = parenthesized_expression + primary_expression;
            primary_expression.Rule = literal | unary_expression | parenthesized_expression;
            //conditional_expression.Rule = expression + PreferShiftHere() + qmark + expression + colon + expression;// + ReduceThis();
            unary_expression.Rule = unary_operator + primary_expression;
            expression.Rule = bin_op_expression
                    | primary_expression
                    | function_expression
                    | guid_variable;
                    //| typecast_expression
                    //| conditional_expression;
            literal.Rule = Number | StringLiteral | CharLiteral | "true" | "false" | "True" | "False" | "null";
            unary_operator.Rule = ToTerm("-") | "!"; //ToTerm("+") | "-" | "!" | "~" | "*";
            function_expression.Rule = identifier + argument_list_par;

            //Set grammar root
            this.Root = function_expression;
        }
示例#4
0
    public ClarionGrammar() : base(false) { //case insensitive
      base.GrammarComments = "Clarion grammar for parsing Clarion sources.";

      //Terminals
      var comment = new CommentTerminal("comment", "!", "\n");
      this.NonGrammarTerminals.Add(comment);
      _comment = comment; 
      var identifier = new IdentifierTerminal("identifier", ":", string.Empty);
      var label = new IdentifierTerminal("label", ":", string.Empty);
      label.ValidateToken += label_ValidateToken;
      label.Priority = TerminalPriority.High;
      //Clarion uses suffixes for identifying number base (bin, octal, hex) - unlike Irony's NumberLiteral which supports suffixes.
      // We treat all numbers as hexadecimal with optional prefixes that don't mean anything. We "fix" the value in ValidateToken handler
      var number = new NumberLiteral("number");
      number.Options = NumberOptions.Hex | NumberOptions.DisableQuickParse;
      number.AddSuffix("b", TypeCode.Int64);
      number.AddSuffix("o", TypeCode.Int64);
      number.AddSuffix("h", TypeCode.Int64);
      number.ValidateToken += number_ValidateToken;
     
      var string_lit = new StringLiteral("string_lit", "'", StringOptions.AllowsDoubledQuote | StringOptions.NoEscapes);

      var comma = ToTerm(",");
      var not = ToTerm("NOT");
      
      //Non-terminals
      var source_file = new NonTerminal("source_file");
      var main_file = new NonTerminal("main_file");
      //whitespace - NewLine, Empty line, line with compiler directive, or line with end-tag of Compile(..) directive
      var wspace = new NonTerminal("wspace");
      var ws_lines = new NonTerminal("ws_lines");
      var ws_line = new NonTerminal("ws_line");
      var compiler_dir = new NonTerminal("compiler_dir");
      var compiler_dir_line = new NonTerminal("compiler_dir_line");
      var cdir_compile_end_tag = new CustomTerminal("compile_end_tag", Match_compile_end_tag);

      var cdir_include = new NonTerminal("cdir_include");
      var cdir_equate = new NonTerminal("cdir_equate");
      var cdir_compile_omit = new NonTerminal("cdir_compile_omit");
      var compile_or_omit = new NonTerminal("compile_or_omit");
      var cdir_section = new NonTerminal("cdir_section");
      var once_opt = new NonTerminal("once_opt");
      var const_value = new NonTerminal("const_value");
      var comma_expr_opt = new NonTerminal("comma_expr_opt");
      var comma_string_lit_opt = new NonTerminal("comma_string_lit_opt");


      var member_file = new NonTerminal("member_file");
      var file_hearder = new NonTerminal("file_header");

      var map = new NonTerminal("map");
      var map_opt = new NonTerminal("map_opt");
      var map_elem = new NonTerminal("map_elem");
      var map_elem_list = new NonTerminal("map_elem_list");
      
      var proc_decl_list = new NonTerminal("proc_decl_list");
      var proc_decl = new NonTerminal("proc_decl");
      var proc_impl_list = new NonTerminal("proc_impl_list");
      var proc_impl = new NonTerminal("proc_impl");
      var data_decl_list = new NonTerminal("data_decl_list");
      var data_decl_list_opt = new NonTerminal("data_decl_list_opt");
      var data_decl = new NonTerminal("data_decl");
      var stmt_list = new NonTerminal("stmt_list");
      var stmt_line = new NonTerminal("stmt_line");
      var stmt = new NonTerminal("stmt");
      var assign_stmt = new NonTerminal("assign_stmt");
      var expr = new NonTerminal("expr");
      var expr_opt = new NonTerminal("expr_opt");
      var bin_expr = new NonTerminal("bin_expr");
      var bin_op = new NonTerminal("bin_op");
      var fun_call = new NonTerminal("fun_call");
      var par_expr = new NonTerminal("par_expr");
      var expr_list = new NonTerminal("expr_list");
      var term = new NonTerminal("term");

      var module_decl = new NonTerminal("module_decl");
      var module_header = new NonTerminal("module_ref");
      var data_type = new NonTerminal("data_type");
      var param_init_opt = new NonTerminal("param_init_opt");
      var type_args_opt = new NonTerminal("type_args_opt");
      var type_arg_list = new NonTerminal("type_arg_list");
      var type_arg = new NonTerminal("type_arg"); 

      var label_opt = new NonTerminal("label_opt");
      var param_list = new NonTerminal("param_list"); 
      var param = new NonTerminal("param");
      var param_list_par_opt = new NonTerminal("param_list_par_opt");
      var attr_list_tail_opt = new NonTerminal("attr_list_tail_opt");
      var attr_list = new NonTerminal("attr_list");
      var attr_def = new NonTerminal("attr_def");
      var return_line_opt = new NonTerminal("return_line_opt");
      var end_line = new NonTerminal("end_line");
      
      //Rules 
      base.Root = source_file;
      source_file.Rule = main_file | member_file;

      //whitespace - includes compiler directives
      wspace.Rule = NewLine + ws_lines;// +ReduceHere();
      ws_lines.Rule =  MakeStarRule(ws_lines, ws_line);
      ws_line.Rule = compiler_dir | PreferShiftHere() + NewLine + ReduceHere();
      //compiler_dir_line.Rule = compiler_dir;
      compiler_dir.Rule = cdir_include | cdir_equate | cdir_compile_omit | cdir_section | cdir_compile_end_tag;
      cdir_include.Rule = ToTerm("INCLUDE") + "(" + string_lit + comma_string_lit_opt + ")" + once_opt;
      comma_string_lit_opt.Rule = Empty | comma + string_lit;
      once_opt.Rule = comma + "ONCE" | Empty;
      cdir_equate.Rule = //ShiftIf("EQUATE").ComesBefore(NewLine)  + 
        label + "EQUATE" + "(" + const_value + ")";
      const_value.Rule = number | string_lit;
      cdir_compile_omit.Rule = compile_or_omit + "(" + string_lit + comma_expr_opt + ")";
      comma_expr_opt.Rule = Empty | comma + expr;
      cdir_section.Rule = ToTerm("SECTION") + "(" + string_lit + ")";
      compile_or_omit.Rule = ToTerm("COMPILE") | "OMIT";
      
      //File structure
      main_file.Rule = "PROGRAM" + wspace + map + data_decl_list_opt + wspace +
                     "CODE" + wspace + stmt_list + return_line_opt + proc_impl_list;
      member_file.Rule = "MEMBER" + wspace + map_opt + data_decl_list + proc_impl_list;

      //map
      map_opt.Rule = map | Empty;
      map.Rule = "MAP" + wspace + map_elem_list + end_line;
      map_elem_list.Rule = MakeStarRule(map_elem_list, wspace, map_elem);
      map_elem.Rule = proc_decl | module_header;
      module_decl.Rule = module_header + proc_decl_list + end_line;
      module_header.Rule = ToTerm("MODULE") + "(" + string_lit + ")" + wspace; 

      proc_decl_list.Rule = MakePlusRule(proc_decl_list, proc_decl);
      proc_decl.Rule = label + "PROCEDURE" + param_list_par_opt + attr_list_tail_opt + wspace;
      param_list_par_opt.Rule = Empty | "(" + param_list + ")";
      param_list.Rule = MakePlusRule(param_list, comma, param);
      param.Rule = data_type + identifier + param_init_opt;
      param_init_opt.Rule = Empty | "=" + number;
      data_type.Rule = identifier + type_args_opt; 
      type_args_opt.Rule = Empty | "(" + type_arg_list + ")";
      type_arg_list.Rule = MakePlusRule(type_arg_list, comma, type_arg);
      type_arg.Rule = number | identifier; 
      
      attr_list_tail_opt.Rule = Empty | comma + attr_list;
      attr_list.Rule = MakePlusRule(attr_list, comma, attr_def); 
      attr_def.Rule = identifier + param_list_par_opt;

      data_decl_list.Rule = MakePlusRule(data_decl_list, data_decl);
      data_decl_list_opt.Rule = data_decl_list | Empty; 
      data_decl.Rule = identifier + data_type + wspace;

      proc_impl_list.Rule = MakeStarRule(proc_impl_list, proc_impl);
      proc_impl.Rule = proc_decl + data_decl_list + "CODE" + wspace + stmt_list + return_line_opt + wspace;
      stmt_list.Rule = MakeStarRule(stmt_list, stmt_line);
      stmt_line.Rule = stmt + wspace;
      stmt.Rule = assign_stmt | fun_call;
      assign_stmt.Rule = identifier + "=" + expr;
      expr.Rule = fun_call | par_expr | bin_expr | term;
      par_expr.Rule = "(" + expr + ")";
      bin_expr.Rule = expr + bin_op + expr;
      bin_op.Rule = ToTerm("+") | "-" | "*" | "/" | "^" | "%"
                  | "&"
                  | "=" | "<" | ">" | "~=" | "~<" | "~>" | not + "=" | not + "<" | not + ">"
                  | "<>" | "<=" | "=<" | ">=" | "=>"
                  | "~" | not | "AND" | "OR" | "XOR";
      fun_call.Rule = identifier + "(" + expr_list + ")";
      expr_list.Rule = MakeStarRule(expr_list, comma, expr);
      expr_opt.Rule = expr | Empty;
      term.Rule = identifier | number | string_lit;

      return_line_opt.Rule = "RETURN" + expr_opt | Empty;
      end_line.Rule = "END" + NewLine | "." + NewLine;

      //operator precedence 
      RegisterOperators(10,  "OR", "XOR");
      RegisterOperators(20, "AND");

      RegisterOperators(50, "=", "<", ">", "~=", "~<", "~>", "<>", "<=", "=<", ">=", "=>"); 
      RegisterOperators(100, "+", "-");
      RegisterOperators(110, "*", "/", "%", "&");
      RegisterOperators(120, Associativity.Right, "^");
      RegisterOperators(130, not);
      RegisterOperators(130, "~");

      //punctuation, brace pairs, transient nodes
      MarkPunctuation("(", ")", ",");
      RegisterBracePair("(", ")");
      
      //Reserved words and special words
      var resWordList = "ACCEPT AND BEGIN BREAK BY CASE CHOOSE COMPILE CYCLE DO ELSE ELSIF END EXECUTE EXIT FUNCTION GOTO IF INCLUDE LOOP" +
                        " MEMBER NEW NOT NULL OF OMIT OR OROF PARENT PROCEDURE PROGRAM RETURN ROUTINE SECTION SELF THEN TIMES TO UNTIL WHILE XOR";
      this.MarkReservedWords(resWordList.Split(' '));
      var specialWordsList = "APPLICATION CLASS CODE DATA DETAIL FILE FOOTER FORM GROUP HEADER ITEM ITEMIZE JOIN MAP MENU MENUBAR" + 
                         " MODULE OLECONTROL OPTION QUEUE RECORD REPORT ROW SHEET TAB TABLE TOOLBAR VIEW WINDOW";
      //Initialize special words list (words that cannot be used as proc names); we'll later use them for verifying proc names
      SpecialWords = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
      SpecialWords.UnionWith(specialWordsList.Split(' ')); 
    }