source: tags/ms_r16q2/AISC/aisc_parser.h

Last change on this file was 10950, checked in by westram, 10 years ago
  • fix cppcheck warnings
    • renamed enum members hiding variables
    • reintroduced suppressions removed in [10946]
    • renamed function index()
File size: 5.9 KB
Line 
1//   Coded by Ralf Westram (coder@reallysoft.de) in March 2011   //
2//   Institute of Microbiology (Technical University Munich)     //
3//   http://www.arb-home.de/                                     //
4
5#ifndef AISC_PARSER_H
6#define AISC_PARSER_H
7
8#ifndef AISC_TOKEN_H
9#include "aisc_token.h"
10#endif
11#ifndef AISC_LOCATION_H
12#include "aisc_location.h"
13#endif
14#ifndef AISC_INLINE_H
15#include "aisc_inline.h"
16#endif
17#ifndef ATTRIBUTES_H
18#include <attributes.h>
19#endif
20
21enum CommandType {
22    NO_COMMAND, 
23    CT_IF = 1,
24    CT_ENDIF,
25    CT_ELSE,
26    CT_FOR,
27    CT_NEXT,
28    CT_ENDFOR,
29    CT_ELSEIF,
30    CT_FUNCTION,
31    CT_LABEL,
32    CT_OTHER_CMD,
33};
34
35struct Code {
36    Code *next;
37    char *str;
38
39    Location source;
40
41    CommandType    command;
42    const Command *cmd;
43
44    mutable struct for_data *fd;
45
46    Code *IF;
47    Code *ELSE;
48    Code *ENDIF;
49    Code *FOR;
50    Code *NEXT;
51    Code *ENDFOR;
52
53    Code() {
54        memset(this, 0, sizeof(*this));
55    }
56    Code(const Code& other)
57        : next(other.next),
58          str(nulldup(other.str)),
59          source(other.source), 
60          command(other.command),
61          cmd(other.cmd),
62          fd(other.fd),
63          IF(other.IF),
64          ELSE(other.ELSE),
65          ENDIF(other.ENDIF),
66          FOR(other.FOR),
67          NEXT(other.NEXT),
68          ENDFOR(other.ENDFOR)
69    {}
70
71    DECLARE_ASSIGNMENT_OPERATOR(Code);
72    ~Code() {
73        delete next;
74        free(str);
75    }
76
77    void set_command(CommandType command_, const char *args) {
78        command = command_;
79        SKIP_SPACE_LF(args);
80        freedup(str, args);
81    }
82
83    void print_error_internal(const char *err, const char *launcher_file, int launcher_line) const {
84        source.print_error_internal(err, launcher_file, launcher_line);
85    }
86    void print_warning_internal(const char *warn, const char *launcher_file, int launcher_line) const {
87        source.print_warning_internal(warn, launcher_file, launcher_line);
88    }
89};
90
91
92class Parser : virtual Noncopyable {
93    // used to parse 'Data' and 'Code'
94   
95    int         lastchar;
96    const char *last_line_start;
97
98    Location loc;
99
100    int error_flag;
101
102    void get_byte(const char *& io) {
103        lastchar = *(io++);
104        if (is_LF(lastchar)) {
105            last_line_start = io;
106            ++loc;
107        }
108    }
109
110    const char *currentLocation(const char *io);
111
112    void p_err(const char *io, const char *error);
113    void p_errf(const char *io, const char *formatString, ...) __ATTR__FORMAT_MEMBER(2);
114   
115    void p_err_empty_braces(const char *io) { p_err(io, "{} found, missing contents"); }
116    void p_err_exp_line_terminator(const char *io) { p_err(io, "missing ',' or ';' or 'newline'"); }
117    void p_err_ill_atWord(const char *io) { p_err(io, "only header definitions may start with '@'"); }
118    void p_err_exp_atWord(const char *io) { p_err(io, "all words in header-definitions have to start with '@'"); }
119   
120    void p_err_expected(const char *io, const char *expect)                     { p_errf(io, "Expected to see %s", expect); }
121    void p_err_exp_but_saw(const char *io, const char *expect, const char *saw) { p_errf(io, "Expected to see %s, but saw %s", expect, saw); }
122
123    void p_err_exp_string_but_saw(const char *io, const char *saw) { p_err_exp_but_saw(io, "string", saw); }
124    void p_err_exp_but_saw_EOF(const char *io, const char *expect) { p_err_exp_but_saw(io, expect, "end of file"); }
125
126    inline void expect_line_terminator(const char *in) {
127        if (!is_SEP_LF_EOS(lastchar)) p_err_exp_line_terminator(in);
128    }
129
130    void expect_and_skip_closing_brace(const char *& in, const char *openingBraceLocation) {
131        if (lastchar != '}') {
132            p_err_expected(in, "'}'");
133            fprintf(stderr, "%s: opening brace was here\n", openingBraceLocation);
134        }
135        get_byte(in);
136    }
137    void expect_and_skip(const char *& in, char expect) {
138        if (lastchar != expect) {
139            char buf[] = "'x'";
140            buf[1]     = expect;
141            p_err_expected(in, buf);
142        }
143        get_byte(in);
144    }
145
146    void skip_over_spaces(const char *& in) { while (is_SPACE(lastchar)) get_byte(in); }
147    void skip_over_spaces_and_comments(const char *& in) {
148        skip_over_spaces(in);
149        if (lastchar == '#') { // comment -> skip rest of line
150            while (!is_LF_EOS(lastchar)) get_byte(in);
151        }
152    }
153    void skip_over_spaces_and_comments_multiple_lines(const char *& in) {
154        while (1) {
155            skip_over_spaces_and_comments(in);
156            if (!is_LF(lastchar)) break;
157            get_byte(in);
158        }
159    }
160
161    void copyWordTo(const char*& in, char*& out) {
162        while (!is_SPACE_SEP_LF_EOS(lastchar)) {
163            *(out++) = lastchar;
164            get_byte(in);
165        }
166    }
167
168    void  copyTillQuotesTo(const char*& in, char*& out);
169    char *readWord(const char *& in);
170
171    char *SETSOURCE(const char *& in, enum TOKEN& foundTokenType);
172    char *parse_token(const char *& in, enum TOKEN& foundTokenType);
173
174    Token *parseBrace(const char *& in, const char *key);
175    TokenList *parseTokenList(const char *& in, class HeaderList& headerList);
176
177public:
178    Parser() {
179        lastchar = ' ';
180        last_line_start = NULL;
181        error_flag      = 0;
182    }
183
184    int get_sourceline() const { return loc.get_linenr(); }
185    const char *get_sourcename() const { return loc.get_path(); }
186    const Location& get_location() const { return loc; }
187
188    void set_source(const Location& other) {
189        aisc_assert(loc != other);
190        loc = other;
191    }
192    void set_source(const char *path, int linenumber) {
193        set_source(Location(linenumber, path));
194    }
195
196    void set_line_start(const char *start, int offset_in_line) {
197        last_line_start = start-offset_in_line;
198        lastchar        = ' ';
199    }
200
201    TokenListBlock *parseTokenListBlock(const char *& in);
202    class Code *parse_program(const char *in, const char *filename);
203};
204
205
206#else
207#error aisc_parser.h included twice
208#endif // AISC_PARSER_H
Note: See TracBrowser for help on using the repository browser.