lexer.h

#ifndef LEXER_H
#define LEXER_H
 
#include <fstream>
#include <string>
using namespace std;
 
enum TokenKind { ident, number, text, separator, eos };
 
class Lexer
{
private:
    ifstream f;
    char ch;
    void nextChar ();
 
public:
    TokenKind kind;
    string token;
    void nextToken ();
    void error (string msg);
 
public:
    bool isSeparator (char c);
    void checkSeparator (char c);
 
    double readNumber ();
 
public:
    Lexer (string fileName);
    ~Lexer ();
};
 
#endif // LEXER_H

lexer.cpp

#include "lexer.h"
 
#include <iostream>
using namespace std;
 
const char zero = 0;
 
Lexer::Lexer (string fileName)
{
    f.open (fileName);
    if (not f.good ())
        error ("Cannot open file: " + fileName);
 
    ch = zero;
    nextChar ();
    nextToken ();
}
 
Lexer::~Lexer ()
{
    if (f.good ())
        f.close ();
}
 
void Lexer::error (string msg)
{
    cerr << "Error: " << msg << ", token=" << token << endl;
    exit (1);
}
 
void Lexer::nextChar ()
{
    f >> ch;
    if (!f.good ())
        ch = zero;
}
 
void Lexer::nextToken ()
{
    token = "";
    while (ch != zero && ch <= ' ')
        nextChar ();
 
    if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
    {
        kind = ident;
        while (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
        {
            token = token + ch;
            nextChar ();
        }
    }
    else if (ch >= '0' && ch <= '9')
    {
        kind = number;
        while (ch >= '0' && ch <= '9')
        {
            token = token + ch;
            nextChar ();
        }
    }
    else if (ch != zero)
    {
        kind = separator;
        token = string (1, ch);
        nextChar ();
    }
    else
    {
        kind = eos;
    }
}
 
bool Lexer::isSeparator (char c)
{
    return kind == separator && token == string (1, c);
}
 
void Lexer::checkSeparator (char c)
{
    if (!isSeparator (c))
        error (string (1, c) + " expected");
    nextToken ();
}
 
double Lexer::readNumber ()
{
    if (kind != number)
        error ("Number expected");
 
    double result = 0;
 
    /*
    for (int i = 0 ; i < token.length() ; i++)
    {
        char c = token [i];
        ...
    }
    */
 
    for (char c : token)
    {
        result = 10 * result + (c - '0');
    }
 
    nextToken ();
    return result;
}

Hlavní program

 
#include <iostream>
using namespace std;
#include "lexer.h"
 
const int R = 3;
const int S = 4;
typedef double Matice [R] [S];
 
void readMat (Lexer & inp, Matice m)
{
    inp.checkSeparator ('{');
    int i = 0;
    while (!inp.isSeparator ('}'))
    {
        inp.checkSeparator ('[');
        if (i >= R) inp.error ("Too many lines");
        int k = 0;
        while (!inp.isSeparator (']'))
        {
            double num = inp.readNumber ();
            if (k >= S) inp.error ("Too many columns");
            m [i][k] = num;
            k++;
 
            if (!inp.isSeparator (']'))
                inp.checkSeparator (',');
        }
        inp.checkSeparator (']');
        if (k != S) inp.error ("Missing column");
 
        i++;
 
        if (inp.isSeparator (','))
            inp.nextToken ();
    }
    inp.checkSeparator ('}');
    if (i != R) inp.error ("Missing line");
}
 
void printMat (Matice m)
{
    for (int i = 0; i < R; i++)
    {
        for (int k = 0; k < S; k++)
        {
            cout << m [i][k];
            if (k < S-1) cout << ", ";
        }
        cout << endl;
    }
    cout << endl;
}
 
int main()
{
    Matice a, b;
 
    Lexer lex ("abc.txt");
    readMat (lex, a);
 
    char op = ' ';
    if (lex.isSeparator ('+'))
    {
        op = lex.token [0];
        lex.nextToken ();
    }
    else
    {
        lex.error ("Unknown op");
    }
 
    readMat (lex, b);
 
    printMat (a);
    printMat (b);
 
    /*
    while (lex.kind != eos)
    {
        cout << lex.token << endl;
        lex.nextToken ();
    }
    */
 
    /*
    lex.checkSeparator ('{');
    while (!lex.isSeparator ('}'))
    {
        lex.checkSeparator ('[');
        while (!lex.isSeparator (']'))
        {
            double num = lex.readNumber ();
            cout << num;
 
            if (!lex.isSeparator (']'))
            {
                lex.checkSeparator (',');
                cout << ',';
            }
        }
        lex.checkSeparator (']');
        cout << endl;
 
        if (lex.isSeparator (','))
            lex.nextToken ();
    }
    lex.checkSeparator ('}');
    */
 
    return 0;
}

Soubor abc.txt se vstupními daty

 
{
 
   [ 1, 2, 3, 4 ],
   [ 10, 20, 30, 40 ],
   [ 100, 200, 300, 400 ]
}
 
+
 
{
 
   [ 11, 22, 33, 44 ],
   [ 10, 20, 30, 40 ],
   [ 100, 200, 300, 400 ]
}
 
zpro/lexer_st.txt · Last modified: 2020/12/09 17:17 by 88.103.111.44
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki