ARB
aisc_parser.h
Go to the documentation of this file.
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 
23  CT_IF = 1,
33 };
34 
35 struct Code {
37  char *str;
38 
40 
42  const Command *cmd;
43 
44  mutable struct for_data *fd;
45 
46  Code *IF;
52 
53  Code() :
54  next(NULp),
55  str(NULp),
56  // default Location is invalid (ok for default Code)
57  command(NO_COMMAND),
58  cmd(NULp),
59  fd(NULp),
60  IF(NULp),
61  ELSE(NULp),
62  ENDIF(NULp),
63  FOR(NULp),
64  NEXT(NULp),
65  ENDFOR(NULp)
66  {}
67 
68  Code(const Code& other) :
69  next(other.next),
70  str(nulldup(other.str)),
71  source(other.source),
72  command(other.command),
73  cmd(other.cmd),
74  fd(other.fd),
75  IF(other.IF),
76  ELSE(other.ELSE),
77  ENDIF(other.ENDIF),
78  FOR(other.FOR),
79  NEXT(other.NEXT),
80  ENDFOR(other.ENDFOR)
81  {}
82 
84  ~Code() {
85  delete next;
86  free(str);
87  }
88 
89  void set_command(CommandType command_, const char *args) {
90  command = command_;
91  SKIP_SPACE_LF(args);
92  freedup(str, args);
93  }
94 
95  void print_error_internal(const char *err, const char *launcher_file, int launcher_line) const {
96  source.print_error_internal(err, launcher_file, launcher_line);
97  }
98  void print_warning_internal(const char *warn, const char *launcher_file, int launcher_line) const {
99  source.print_warning_internal(warn, launcher_file, launcher_line);
100  }
101 };
102 
103 
104 class Parser : virtual Noncopyable {
105  // used to parse 'Data' and 'Code'
106 
107  int lastchar;
108  const char *last_line_start;
109 
110  Location loc;
111 
112  int error_flag;
113 
114  void get_byte(const char *& io) {
115  lastchar = *(io++);
116  if (is_LF(lastchar)) {
117  last_line_start = io;
118  ++loc;
119  }
120  }
121 
122  const char *currentLocation(const char *io);
123 
124  void p_err(const char *io, const char *error);
125  void p_errf(const char *io, const char *formatString, ...) __ATTR__FORMAT_MEMBER(2);
126 
127  void p_err_empty_braces(const char *io) { p_err(io, "{} found, missing contents"); }
128  void p_err_exp_line_terminator(const char *io) { p_err(io, "missing ',' or ';' or 'newline'"); }
129  void p_err_ill_atWord(const char *io) { p_err(io, "only header definitions may start with '@'"); }
130  void p_err_exp_atWord(const char *io) { p_err(io, "all words in header-definitions have to start with '@'"); }
131 
132  void p_err_expected(const char *io, const char *expect) { p_errf(io, "Expected to see %s", expect); }
133  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); }
134 
135  void p_err_exp_string_but_saw(const char *io, const char *saw) { p_err_exp_but_saw(io, "string", saw); }
136  void p_err_exp_but_saw_EOF(const char *io, const char *expect) { p_err_exp_but_saw(io, expect, "end of file"); }
137 
138  inline void expect_line_terminator(const char *in) {
139  if (!is_SEP_LF_EOS(lastchar)) p_err_exp_line_terminator(in);
140  }
141 
142  void expect_and_skip_closing_brace(const char *& in, const char *openingBraceLocation) {
143  if (lastchar != '}') {
144  p_err_expected(in, "'}'");
145  fprintf(stderr, "%s: opening brace was here\n", openingBraceLocation);
146  }
147  get_byte(in);
148  }
149  void expect_and_skip(const char *& in, char expect) {
150  if (lastchar != expect) {
151  char buf[] = "'x'";
152  buf[1] = expect;
153  p_err_expected(in, buf);
154  }
155  get_byte(in);
156  }
157 
158  void skip_over_spaces(const char *& in) { while (is_SPACE(lastchar)) get_byte(in); }
159  void skip_over_spaces_and_comments(const char *& in) {
160  skip_over_spaces(in);
161  if (lastchar == '#') { // comment -> skip rest of line
162  while (!is_LF_EOS(lastchar)) get_byte(in);
163  }
164  }
165  void skip_over_spaces_and_comments_multiple_lines(const char *& in) {
166  while (1) {
167  skip_over_spaces_and_comments(in);
168  if (!is_LF(lastchar)) break;
169  get_byte(in);
170  }
171  }
172 
173  void copyWordTo(const char*& in, char*& out) {
174  while (!is_SPACE_SEP_LF_EOS(lastchar)) {
175  *(out++) = lastchar;
176  get_byte(in);
177  }
178  }
179 
180  void copyTillQuotesTo(const char*& in, char*& out);
181  char *readWord(const char *& in);
182 
183  char *SETSOURCE(const char *& in, enum TOKEN& foundTokenType);
184  char *parse_token(const char *& in, enum TOKEN& foundTokenType);
185 
186  Token *parseBrace(const char *& in, const char *key);
187  TokenList *parseTokenList(const char *& in, class HeaderList& headerList);
188 
189 public:
190  Parser() {
191  lastchar = ' ';
192  last_line_start = NULp;
193  error_flag = 0;
194  }
195 
196  int get_sourceline() const { return loc.get_linenr(); }
197  const char *get_sourcename() const { return loc.get_path(); }
198  const Location& get_location() const { return loc; }
199 
200  void set_source(const Location& other) {
201  aisc_assert(loc != other);
202  loc = other;
203  }
204  void set_source(const char *path, int linenumber) {
205  set_source(Location(linenumber, path));
206  }
207 
208  void set_line_start(const char *start, int offset_in_line) {
209  last_line_start = start-offset_in_line;
210  lastchar = ' ';
211  }
212 
213  TokenListBlock *parseTokenListBlock(const char *& in);
214  class Code *parse_program(const char *in, const char *filename);
215 };
216 
217 
218 #else
219 #error aisc_parser.h included twice
220 #endif // AISC_PARSER_H
Location source
Definition: aisc_parser.h:39
TOKEN
Definition: aisc_token.h:18
~Code()
Definition: aisc_parser.h:84
void set_source(const char *path, int linenumber)
Definition: aisc_parser.h:204
const char * get_path() const
Definition: aisc_location.h:44
int get_sourceline() const
Definition: aisc_parser.h:196
CONSTEXPR_INLINE bool is_LF(char c)
Definition: aisc_inline.h:23
void set_command(CommandType command_, const char *args)
Definition: aisc_parser.h:89
DECLARE_ASSIGNMENT_OPERATOR(Code)
CONSTEXPR_INLINE bool is_SEP_LF_EOS(char c)
Definition: aisc_inline.h:30
void print_warning_internal(const char *msg, const char *launcher_file, int launcher_line) const
Definition: aisc_location.h:51
Code * ELSE
Definition: aisc_parser.h:47
Code * IF
Definition: aisc_parser.h:46
char * str
Definition: aisc_parser.h:37
const Location & get_location() const
Definition: aisc_parser.h:198
static HelixNrInfo * start
#define __ATTR__FORMAT_MEMBER(pos)
Definition: attributes.h:62
Code * FOR
Definition: aisc_parser.h:49
void print_error_internal(const char *err, const char *launcher_file, int launcher_line) const
Definition: aisc_parser.h:95
static void error(const char *msg)
Definition: mkptypes.cxx:96
const Command * cmd
Definition: aisc_parser.h:42
Code * ENDFOR
Definition: aisc_parser.h:51
Code * next
Definition: aisc_parser.h:36
Code(const Code &other)
Definition: aisc_parser.h:68
CONSTEXPR_INLINE bool is_SPACE_SEP_LF_EOS(char c)
Definition: aisc_inline.h:28
class Code * parse_program(const char *in, const char *filename)
Definition: aisc_parser.c:399
const char * get_sourcename() const
Definition: aisc_parser.h:197
struct for_data * fd
Definition: aisc_parser.h:44
Code()
Definition: aisc_parser.h:53
CommandType
Definition: aisc_parser.h:21
void print_warning_internal(const char *warn, const char *launcher_file, int launcher_line) const
Definition: aisc_parser.h:98
TokenListBlock * parseTokenListBlock(const char *&in)
Definition: aisc_parser.c:380
Code * NEXT
Definition: aisc_parser.h:50
void set_source(const Location &other)
Definition: aisc_parser.h:200
void set_line_start(const char *start, int offset_in_line)
Definition: aisc_parser.h:208
#define NULp
Definition: cxxforward.h:97
CONSTEXPR_INLINE bool is_LF_EOS(char c)
Definition: aisc_inline.h:29
CONSTEXPR_INLINE bool is_SPACE(char c)
Definition: aisc_inline.h:21
CommandType command
Definition: aisc_parser.h:41
int get_linenr() const
Definition: aisc_location.h:45
#define aisc_assert(cond)
Definition: aisc_def.h:11
Code * ENDIF
Definition: aisc_parser.h:48
void print_error_internal(const char *err, const char *launcher_file, int launcher_line) const
Definition: aisc_location.h:47
void SKIP_SPACE_LF(const char *&var)
Definition: aisc_inline.h:32