LCOV - code coverage report
Current view: top level - src/regex - lex.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 79 81 97.5 %
Date: 2016-12-21 02:12:01 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /***************************************************************************//**
       2             : 
       3             :   @file         lex.c
       4             : 
       5             :   @author       Stephen Brennan
       6             : 
       7             :   @date         Created Friday, 29 January 2016
       8             : 
       9             :   @brief        All lexer-related functions.
      10             : 
      11             :   @copyright    Copyright (c) 2016, Stephen Brennan.  Released under the Revised
      12             :                 BSD License.  See LICENSE.txt for details.
      13             : 
      14             : *******************************************************************************/
      15             : 
      16             : #include <stdio.h>
      17             : 
      18             : #include "libstephen/re_internals.h"
      19             : 
      20          34 : void escape(Lexer *l)
      21             : {
      22          34 :   switch (InputIdx(l->input, l->index)) {
      23             :   case L'(':
      24           2 :     l->tok = (Token){CharSym, L'('};
      25           2 :     break;
      26             :   case L')':
      27           2 :     l->tok = (Token){CharSym, L')'};
      28           2 :     break;
      29             :   case L'[':
      30           2 :     l->tok = (Token){CharSym, L'['};
      31           2 :     break;
      32             :   case L']':
      33           2 :     l->tok = (Token){CharSym, L']'};
      34           2 :     break;
      35             :   case L'+':
      36           2 :     l->tok = (Token){CharSym, L'+'};
      37           2 :     break;
      38             :   case L'-':
      39           2 :     l->tok = (Token){CharSym, L'-'};
      40           2 :     break;
      41             :   case L'*':
      42           2 :     l->tok = (Token){CharSym, L'*'};
      43           2 :     break;
      44             :   case L'?':
      45           2 :     l->tok = (Token){CharSym, L'?'};
      46           2 :     break;
      47             :   case L'^':
      48           2 :     l->tok = (Token){CharSym, L'^'};
      49           2 :     break;
      50             :   case L'n':
      51           2 :     l->tok = (Token){CharSym, L'\n'};
      52           2 :     break;
      53             :   case L'.':
      54           2 :     l->tok = (Token){CharSym, L'.'};
      55           2 :     break;
      56             :   case L'|':
      57           2 :     l->tok = (Token){CharSym, L'|'};
      58           2 :     break;
      59             :   default:
      60          10 :     l->tok = (Token){Special, InputIdx(l->input, l->index)};
      61          10 :     break;
      62             :   }
      63          34 : }
      64             : 
      65         532 : Token nextsym(Lexer *l)
      66             : {
      67         532 :   if (l->tok.sym == Eof) {
      68          97 :     return l->tok; // eof never ceases to be eof!
      69             :   }
      70             : 
      71             :   // Handle buffered symbols first.
      72         435 :   l->prev = l->tok;
      73         435 :   if (l->nbuf > 0) {
      74          15 :     l->tok = l->buf[0];
      75          27 :     for (size_t i = 0; i < l->nbuf - 1; i++) {
      76          12 :       l->buf[i] = l->buf[i+1];
      77             :     }
      78          15 :     l->nbuf--;
      79             :     //printf(";; nextsym(): unbuffering {%s, '%s'}\n", names[l->tok.sym],
      80             :     //       char_to_string(l->tok.c));
      81          15 :     return l->tok;
      82             :   }
      83             : 
      84         420 :   switch (InputIdx(l->input, l->index)) {
      85             :   case L'(':
      86          13 :     l->tok = (Token){LParen, L'('};
      87          13 :     break;
      88             :   case L')':
      89          13 :     l->tok = (Token){RParen, L')'};
      90          13 :     break;
      91             :   case L'[':
      92          12 :     l->tok = (Token){LBracket, L'['};
      93          12 :     break;
      94             :   case L']':
      95          12 :     l->tok = (Token){RBracket, L']'};
      96          12 :     break;
      97             :   case L'+':
      98          17 :     l->tok = (Token){Plus, L'+'};
      99          17 :     break;
     100             :   case L'-':
     101          24 :     l->tok = (Token){Minus, L'-'};
     102          24 :     break;
     103             :   case L'*':
     104          25 :     l->tok = (Token){Star, L'*'};
     105          25 :     break;
     106             :   case L'?':
     107          19 :     l->tok = (Token){Question, L'?'};
     108          19 :     break;
     109             :   case L'^':
     110           9 :     l->tok = (Token){Caret, L'^'};
     111           9 :     break;
     112             :   case L'|':
     113           9 :     l->tok = (Token){Pipe, L'|'};
     114           9 :     break;
     115             :   case L'.':
     116           9 :     l->tok = (Token){Dot, L'.'};
     117           9 :     break;
     118             :   case L'\\':
     119          34 :     l->index++;
     120          34 :     escape(l);
     121          34 :     break;
     122             :   case L'\0':
     123          97 :     l->tok = (Token){Eof, L'\0'};
     124          97 :     break;
     125             :   default:
     126         127 :     l->tok = (Token){CharSym, InputIdx(l->input, l->index)};
     127         127 :     break;
     128             :   }
     129         420 :   l->index++;
     130             :   //printf(";; nextsym(): {%s, '%s'}\n", names[l->tok.sym], char_to_string(l->tok.c));
     131         420 :   return l->tok;
     132             : }
     133             : 
     134          15 : void unget(Token t, Lexer *l)
     135             : {
     136          15 :   if (l->nbuf >= LEXER_BUFSIZE) {
     137           0 :     fprintf(stderr, "error: maximum lexer buffer size exceeded, dumbass.\n");
     138           0 :     exit(1);
     139             :   }
     140             : 
     141             :   //printf(";; unget(): buffering {%s, '%s'}\n", names[t.sym], char_to_string(t.c));
     142             : 
     143          27 :   for (int i = l->nbuf - 1; i >= 0; i--) {
     144          12 :     l->buf[i+1] = l->buf[i];
     145             :   }
     146          15 :   l->buf[0] = l->tok;
     147          15 :   l->tok = t;
     148          15 :   l->nbuf++;
     149          15 : }

Generated by: LCOV version 1.11