Ejemplo n.º 1
0
 /// <summary>
 /// Creates the union of the current lexical rule and another.
 /// </summary>
 /// <param name="rule">The other lexical rule.</param>
 /// <returns>The union of the current lexical rule and the other.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="rule"/> is <see langword="null"/>.</exception>
 public LexicalRule Or(LexicalRule rule)
 {
     if (rule == null)
     {
         throw new ArgumentNullException();
     }
     else if (this is CharSetLexicalRule && rule is CharSetLexicalRule)
     {
         return(new CharSetLexicalRule(new HashSet <char>(
                                           ((CharSetLexicalRule)this).CharSet.Union(
                                               ((CharSetLexicalRule)rule).CharSet)
                                           )));
     }
     else if (this is NegativeCharSetLexicalRule && rule is NegativeCharSetLexicalRule)
     {
         return(new CharSetLexicalRule(new HashSet <char>(
                                           ((CharSetLexicalRule)this).CharSet.Intersect(
                                               ((CharSetLexicalRule)rule).CharSet)
                                           )));
     }
     else
     {
         return(new AlternateLexicalRule(this, rule));
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a lexeme using the specified identifier and lexical rule.
        /// </summary>
        /// <param name="id">The specified identifier.</param>
        /// <param name="isSkippable">A value that indicates whether the lexeme is skipped when the lexical analysis is performed.</param>
        /// <param name="rule">The specified lexical rule.</param>
        /// <returns>The lexeme created using the specified identifier and lexical rule.</returns>
        /// <exception cref="ArgumentNullException">The parameter is <see langword="null"/>.</exception>
        public Lexeme DefineLexeme(object id, bool isSkippable, LexicalRule rule)
        {
            if (id == null || rule == null)
            {
                throw new ArgumentNullException();
            }
            Lexeme lexeme = new Lexeme(id, isSkippable, rule);

            _lexemes.Add(lexeme);
            return(lexeme);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a lexical rule that matches the specified string literally.
        /// </summary>
        /// <param name="s">The specified string.</param>
        /// <returns>The created lexical rule that matches <paramref name="s"/> literally.</returns>
        /// <exception cref="ArgumentException"><paramref name="s"/> is <see langword="null"/> or an empty string, or it contains <c>'\0'</c>.</exception>
        public static LexicalRule Literal(string s)
        {
            if (string.IsNullOrEmpty(s) || s.IndexOf('\0') >= 0)
            {
                throw new ArgumentException();
            }
            LexicalRule r = Empty;

            foreach (char c in s)
            {
                r = r.Concat(Char(c));
            }
            return(r);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates the concatenation of the current lexical rule and another.
 /// </summary>
 /// <param name="rule">The other lexical rule.</param>
 /// <returns>The concatenation of the current lexical rule and the other.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="rule"/> is <see langword="null"/>.</exception>
 public LexicalRule Concat(LexicalRule rule)
 {
     if (rule == null)
     {
         throw new ArgumentNullException();
     }
     else if (this is EmptyLexicalRule)
     {
         return(rule);
     }
     else if (rule is EmptyLexicalRule)
     {
         return(this);
     }
     else
     {
         return(new ConcatenateLexicalRule(this, rule));
     }
 }
Ejemplo n.º 5
0
 internal ConcatenateLexicalRule(LexicalRule first, LexicalRule second)
 {
     First  = first;
     Second = second;
 }
Ejemplo n.º 6
0
 internal RepeatingLexicalRule(LexicalRule content, int min, int max)
 {
     Content = content;
     Min     = min;
     Max     = max;
 }
Ejemplo n.º 7
0
 internal Lexeme(object id, bool isSkippable, LexicalRule rule)
 {
     Id          = id;
     IsSkippable = isSkippable;
     Rule        = rule;
 }
Ejemplo n.º 8
0
 internal Lexeme(object id, LexicalRule rule)
 {
     Id   = id;
     Rule = rule;
 }
Ejemplo n.º 9
0
        private void InitializeLexer()
        {
            lexb = new LexerBuilder();

            L l_newline
                = L.Chars("\u000D\u000A\u2028\u2029");
            L l_whitespace
                = L.Chars("\u0009\u000B\u000C")
                  | L.CharWhen(c => CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.SpaceSeparator);

            lex_white = lexb.DefineLexeme("blank", true, l_whitespace | l_newline);

            L l_singleLineComment = L.Literal("//") + L.NotChars("\n\r").Repeat() + (L.Chars("\n\r") | L.CharWhen(c =>
            {
                return(c == '\0');
            }));
            L l_delimitedComment = L.Literal("/*") + (L.Char('/') | L.Char('*').Repeat() + L.NotChars("/*")).Repeat() + L.Char('*') + L.Char('/');

            lex_comment = lexb.DefineLexeme("comment", true, l_singleLineComment | l_delimitedComment);

            L l_letter     = L.CharWhen(c => char.IsLetter(c));
            L l_digit      = L.CharWhen(c => char.IsDigit(c));
            L l_identifier = (l_letter | L.Char('_')) + (l_letter | l_digit | L.Char('_')).Repeat();

            lex_identifer = lexb.DefineLexeme("identifier", l_identifier);

            // keywords
            lex_kw_break       = lexb.DefineLexeme("kw_break", L.Literal("break"));
            lex_kw_case        = lexb.DefineLexeme("kw_case", L.Literal("case"));
            lex_kw_continue    = lexb.DefineLexeme("kw_continue", L.Literal("continue"));
            lex_kw_default     = lexb.DefineLexeme("kw_default", L.Literal("default"));
            lex_kw_do          = lexb.DefineLexeme("kw_do", L.Literal("do"));
            lex_kw_else        = lexb.DefineLexeme("kw_else", L.Literal("else"));
            lex_kw_false       = lexb.DefineLexeme("kw_false", L.Literal("false"));
            lex_kw_for         = lexb.DefineLexeme("kw_for", L.Literal("for"));
            lex_kw_goto        = lexb.DefineLexeme("kw_goto", L.Literal("goto"));
            lex_kw_if          = lexb.DefineLexeme("kw_if", L.Literal("if"));
            lex_kw_is          = lexb.DefineLexeme("kw_is", L.Literal("is"));
            lex_kw_new         = lexb.DefineLexeme("kw_new", L.Literal("new"));
            lex_kw_null        = lexb.DefineLexeme("kw_null", L.Literal("null"));
            lex_kw_return      = lexb.DefineLexeme("kw_return", L.Literal("return"));
            lex_kw_switch      = lexb.DefineLexeme("kw_switch", L.Literal("switch"));
            lex_kw_this        = lexb.DefineLexeme("kw_this", L.Literal("this"));
            lex_kw_true        = lexb.DefineLexeme("kw_true", L.Literal("true"));
            lex_kw_while       = lexb.DefineLexeme("kw_while", L.Literal("while"));
            lex_kw_class       = lexb.DefineLexeme("kw_class", L.Literal("class"));
            lex_kw_var         = lexb.DefineLexeme("kw_var", L.Literal("var"));
            lex_kw_function    = lexb.DefineLexeme("kw_function", L.Literal("function"));
            lex_kw_super       = lexb.DefineLexeme("kw_super", L.Literal("super"));
            lex_kw_extends     = lexb.DefineLexeme("kw_extends", L.Literal("extends"));
            lex_kw_public      = lexb.DefineLexeme("kw_public", L.Literal("public"));
            lex_kw_private     = lexb.DefineLexeme("kw_private", L.Literal("private"));
            lex_kw_static      = lexb.DefineLexeme("kw_static", L.Literal("static"));
            lex_kw_constructor = lexb.DefineLexeme("kw_constructor", L.Literal("constructor"));
            lex_kw_protected   = lexb.DefineLexeme("kw_protected", L.Literal("protected"));
            lex_kw_get         = lexb.DefineLexeme("kw_get", L.Literal("get"));
            lex_kw_set         = lexb.DefineLexeme("kw_set", L.Literal("set"));

            lex_kw_future = lexb.DefineLexeme("kw_future",
                                              L.Literal("abstract") | L.Literal("as") | L.Literal("base") | L.Literal("bool")
                                              | L.Literal("byte") | L.Literal("catch") | L.Literal("char") | L.Literal("checked")
                                              | L.Literal("const") | L.Literal("decimal") | L.Literal("delegate")
                                              | L.Literal("double") | L.Literal("enum") | L.Literal("event") | L.Literal("explicit")
                                              | L.Literal("extern") | L.Literal("finally") | L.Literal("fixed") | L.Literal("float")
                                              | L.Literal("foreach") | L.Literal("implicit") | L.Literal("in") | L.Literal("int")
                                              | L.Literal("interface") | L.Literal("internal") | L.Literal("lock")
                                              | L.Literal("long") | L.Literal("namespace") | L.Literal("object") | L.Literal("operator")
                                              | L.Literal("out") | L.Literal("override") | L.Literal("params")
                                              | L.Literal("readonly") | L.Literal("ref")
                                              | L.Literal("sbyte") | L.Literal("sealed") | L.Literal("short") | L.Literal("sizeof")
                                              | L.Literal("stackalloc") | L.Literal("string") | L.Literal("struct")
                                              | L.Literal("throw") | L.Literal("try") | L.Literal("typeof") | L.Literal("uint")
                                              | L.Literal("ulong") | L.Literal("uncheck") | L.Literal("unsafe") | L.Literal("ushort")
                                              | L.Literal("using") | L.Literal("virtual") | L.Literal("void") | L.Literal("volatile")
                                              );

            L l_num_int = l_digit.Repeat(1, 0);
            L l_num_dec = L.Char('.') + l_digit.Repeat(1, 0);
            L l_num_ind = L.Chars("eE") + L.Chars("+-").Optional() + l_digit.Repeat(1, 0);
            L l_num
                = (l_num_int + l_num_dec.Optional() | l_num_dec)
                  .Concat(l_num_ind.Optional());

            lex_li_num = lexb.DefineLexeme("li_number", l_num);
            L l_string1
                = L.Char('\'')
                  + (L.NotChar('\'') | L.Char('\\') + L.AnyChar).Repeat()
                  + L.Char('\'');

            lex_li_string1 = lexb.DefineLexeme("li_string1", l_string1);
            L l_string
                = L.Char('\"')
                  + (L.NotChar('\"') | L.Char('\\') + L.AnyChar).Repeat()
                  + LexicalRule.Char('\"');

            lex_li_string = lexb.DefineLexeme("li_string", l_string);

            // Operators and delimiters
            lex_op_and             = lexb.DefineLexeme("op_&", L.Char('&'));
            lex_op_andAlso         = lexb.DefineLexeme("op_&&", L.Literal("&&"));
            lex_op_andAssign       = lexb.DefineLexeme("op_+=", L.Literal("+="));
            lex_op_assign          = lexb.DefineLexeme("op_=", L.Char('='));
            lex_op_colon           = lexb.DefineLexeme("op_:", L.Char(':'));
            lex_op_comma           = lexb.DefineLexeme("op_,", L.Char(','));
            lex_op_decrement       = lexb.DefineLexeme("op_--", L.Literal("--"));
            lex_op_divide          = lexb.DefineLexeme("op_/", L.Char('/'));
            lex_op_divideAssign    = lexb.DefineLexeme("op_/=", L.Literal("/="));
            lex_op_dot             = lexb.DefineLexeme("op_.", L.Char('.'));
            lex_op_equal           = lexb.DefineLexeme("op_==", L.Literal("=="));
            lex_op_greater         = lexb.DefineLexeme("op_>", L.Char('>'));
            lex_op_greaterEqual    = lexb.DefineLexeme("op_>=", L.Literal(">="));
            lex_op_increment       = lexb.DefineLexeme("op_++", L.Literal("++"));
            lex_op_inverse         = lexb.DefineLexeme("op_~", L.Char('~'));
            lex_op_leftBrace       = lexb.DefineLexeme("op_{", L.Char('{'));
            lex_op_leftBracket     = lexb.DefineLexeme("op_[", L.Char('['));
            lex_op_leftParenthesis = lexb.DefineLexeme("op_(", L.Char('('));
            lex_op_less            = lexb.DefineLexeme("op_<", L.Char('<'));
            lex_op_lessEqual       = lexb.DefineLexeme("op_<=", L.Literal("<="));
            lex_op_minus           = lexb.DefineLexeme("op_-", L.Char('-'));
            lex_op_minusAssign     = lexb.DefineLexeme("op_-=", L.Literal("-="));
            lex_op_mod             = lexb.DefineLexeme("op_%", L.Char('%'));
            lex_op_modAssign       = lexb.DefineLexeme("op_%=", L.Literal("%="));
            lex_op_multiply        = lexb.DefineLexeme("op_*", L.Char('*'));
            lex_op_mutiplyAssign   = lexb.DefineLexeme("op_*=", L.Literal("*="));
            lex_op_not             = lexb.DefineLexeme("op_!", L.Char('!'));
            lex_op_notEqual        = lexb.DefineLexeme("op_!=", L.Literal("!="));
            lex_op_or               = lexb.DefineLexeme("op_|", L.Char('|'));
            lex_op_orAssign         = lexb.DefineLexeme("op_|=", L.Literal("|="));
            lex_op_orElse           = lexb.DefineLexeme("op_||", L.Literal("||"));
            lex_op_plus             = lexb.DefineLexeme("op_+", L.Char('+'));
            lex_op_plusAssign       = lexb.DefineLexeme("op_+=", L.Literal("+="));
            lex_op_lambda           = lexb.DefineLexeme("op_=>", L.Literal("=>"));
            lex_op_question         = lexb.DefineLexeme("op_?", L.Char('?'));
            lex_op_rightBrace       = lexb.DefineLexeme("op_}", L.Char('}'));
            lex_op_rightBracket     = lexb.DefineLexeme("op_]", L.Char(']'));
            lex_op_rightParenthesis = lexb.DefineLexeme("op_)", L.Char(')'));
            lex_op_semicolon        = lexb.DefineLexeme("op_;", L.Char(';'));
            lex_op_shiftLeft        = lexb.DefineLexeme("op_<<", L.Literal("<<"));
            lex_op_shiftLeftAssign  = lexb.DefineLexeme("op_<<=", L.Literal("<<="));
            lex_op_shiftRight       = lexb.DefineLexeme("op_>>", L.Literal(">>"));
            lex_op_shiftRightAssign = lexb.DefineLexeme("op_>>=", L.Literal(">>="));
            lex_op_xor              = lexb.DefineLexeme("op_^", L.Char('^'));
            lex_op_xorAssign        = lexb.DefineLexeme("op_^=", L.Literal("^="));
            lex_op_null             = lexb.DefineLexeme("op_??", L.Literal("??"));
        }