Beispiel #1
0
        /// <summary>
        /// Tries to consume a token of the given type
        /// </summary>
        /// <param name="val">The value of the token, can be null to ignore</param>
        /// <param name="type">The type of the token, can be null to ignore</param>
        /// <returns>A bool signifying if the symbol could be matched or not</returns>
        protected bool Match(int p, string val, Lexer.Token.TokenType? type)
        {
            bool ok = true;

            if (val != null && lookahead.Value != val)
                ok = false;
            else if (type.HasValue && lookahead.Type != type.Value)
                ok = false;

            if (!ok && p == 1)
                SyntaxError(string.Format("{0}: expected '{1}', got instead '{2}', a {3}",
                    lookahead.Line, val ?? type.Value.ToString(), lookahead.Value, lookahead.Type.ToString()));

            if (lookahead.Type != Lexer.Token.TokenType.EndOfFile)
                lookahead = lexer.GetNextToken();

            return ok;
        }
Beispiel #2
0
        /// <summary>
        /// The main function. Runs the parser over the stream and 
        /// returns whether or not the stream is valid.
        /// </summary>
        /// <returns>A bool indicating whether or not the stream is valid syntactically</returns>
        public bool Parse()
        {
            // first parse the program
            // phase 1
            CompilerStack.Clear();
            CompilerStack.Push(new StackFrame(this));
            lexer.Reset();
            lookahead = lexer.GetNextToken();
            SemanticInfo si = new SemanticInfo();
            bool ok1 = NTF_Prog(1, si) && Match(1, Lexer.Token.TokenType.EndOfFile);

            ComputeClassSizes();

            // phase 2
            CompilerStack.Clear();
            CompilerStack.Push(new StackFrame(this));
            si = new SemanticInfo();
            lexer.Reset();
            lookahead = lexer.GetNextToken();
            bool ok2 = NTF_Prog(2, si) && Match(2, Lexer.Token.TokenType.EndOfFile);

            si.Code.Insert(0, "stack res 5000\nalign\n");
            si.Code.Append(
            @"
            putint	align
            add	r2,r0,r0		% Initialize buffer's index i
            cge	r3,r1,r0		% True if N >= 0
            bnz	r3,putint1		% Branch if True (N >= 0)
            sub	r1,r0,r1		% N = -N
            putint1	modi	r4,r1,10		% Rightmost digit
            addi	r4,r4,48		% Convert to ch
            divi	r1,r1,10		% Truncate rightmost digit
            sb	putint9(r2),r4		% Store ch in buffer
            addi	r2,r2,1			% i++
            bnz	r1,putint1		% Loop if not finished
            bnz	r3,putint2		% Branch if True (N >= 0)
            addi	r3,r0,45
            sb	putint9(r2),r3		% Store '-' in buffer
            addi	r2,r2,1			% i++
            add	r1,r0,r0		% Initialize output register (r1 = 0)
            putint2	subi	r2,r2,1			% i--
            lb	r1,putint9(r2)		% Load ch from buffer
            putc	r1			% Output ch
            bnz	r2,putint2		% Loop if not finished
            addi r1,r0,13       % load new line
            putc r1             % print it
            addi r1,r0,10       % new feed thingie
            putc r1
            jr	r15			% return to the caller
            putint9	res	12			% loacl buffer (12 bytes)
            align

            getint   add    r1,r0,r0         % n := 0 (result)
             add    r2,r0,r0         % c := 0 (character)
             add    r3,r0,r0         % s := 0 (sign)
            getint1  getc   r2               % read c
             ceqi   r4,r2,32
             bnz    r4,getint1       % skip blanks
             ceqi   r4,r2,43
             bnz    r4,getint2       % branch if c is '+'
             ceqi   r4,r2,45
             bz     r4,getint3       % branch if c is not '-'
             addi   r3,r0,1          % s := 1 (number is negative)
            getint2  getc   r2               % read c
            getint3  ceqi   r4,r2,10
             bnz    r4,getint5       % branch if c is \n
             cgei   r4,r2,48
             bz     r4,getint4       % c < 0
             clei   r4,r2,57
             bz     r4,getint4       % c > 9
             muli   r1,r1,10         % n := 10 * n
             add    r1,r1,r2         % n := n + c
             subi   r1,r1,48         % n := n - '0'
             j      getint2
            getint4  addi   r2,r0,63         % c := '?'
             putc   r2               % write c
             j      getint           % Try again
            getint5  bz     r3,getint6       % branch if s = 0 (number is positive)
             sub    r1,r0,r1         % n := -n
            getint6  jr     r15              % return
            ");

            Log(LogType.Code, si.Code.ToString());

            // then write out the debug information
            Log(LogType.SymbolTable, Global.ToString());

            foreach (string error in Errors)
                Log(LogType.Error, error);

            foreach (string warning in Warnings)
                Log(LogType.Warning, warning);

            // and flush the streams
            foreach (TextWriter tw in Output.Values)
                tw.Flush();

            return ok1 && ok2;
        }
Beispiel #3
0
        /// <summary>
        /// Skips all the errors until the next (maybe valid) token
        /// </summary>
        /// <param name="tokens">The list of "valid" tokens</param>
        /// <returns>true if there has been an error that was skipped, false otherwise</returns>
        protected bool SkipErrors(int p, params object[] tokens)
        {
            if (ValidLookAhead(tokens))
                return false;

            if (p == 1)
                SyntaxError(string.Format("{0}:unexpected token '{1}' of type '{2}'",
                    lookahead.Line, lookahead.Value, lookahead.Type));

            do
            {
                if (lookahead.Type == Lexer.Token.TokenType.EndOfFile)
                    break;
                lookahead = lexer.GetNextToken();
            } while (!ValidLookAhead(tokens));

            if (p == 1)
                Warning(string.Format("{0}:Resuming parsing near the token '{1}' of type '{2}'",
                    lookahead.Line, lookahead.Value, lookahead.Type));

            return true;
        }