char* text = scanner_read(p_lexer->scanner);
if (NULL != text) {
p_tok = lexer_make_token(text);
- //if (NULL != p_tok)
- // printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok));
free(text);
}
return p_tok;
lex_tok_t* p_tok = NULL;
if ((0 == strcmp(text,"end") || (text[0] == ';'))) {
p_tok = lex_tok_new(T_END, NULL);
- } else if (lexer_oneof("()[];,'\"", text[0])) {
+ } else if (lexer_oneof("()[]{};,'\"", text[0])) {
p_tok = lexer_punc(text);
} else if (text[0] == '\\') {
p_tok = lexer_char(text);
{
lex_tok_t* p_tok = NULL;
switch (text[0]) {
- case '(': p_tok = lex_tok_new(T_LPAR, NULL); break;
- case ')': p_tok = lex_tok_new(T_RPAR, NULL); break;
- case '{': p_tok = lex_tok_new(T_LBRACE, NULL); break;
- case '}': p_tok = lex_tok_new(T_RBRACE, NULL); break;
- case '[': p_tok = lex_tok_new(T_LBRACK, NULL); break;
- case ']': p_tok = lex_tok_new(T_RBRACK, NULL); break;
- case ';': p_tok = lex_tok_new(T_END, NULL); break;
- case ',': p_tok = lex_tok_new(T_COMMA, NULL); break;
+ case '(': p_tok = lex_tok_new(T_LPAR, NULL); break;
+ case ')': p_tok = lex_tok_new(T_RPAR, NULL); break;
+ case '{': p_tok = lex_tok_new(T_LBRACE, NULL); break;
+ case '}': p_tok = lex_tok_new(T_RBRACE, NULL); break;
+ case '[': p_tok = lex_tok_new(T_LBRACK, NULL); break;
+ case ']': p_tok = lex_tok_new(T_RBRACK, NULL); break;
+ case ';': p_tok = lex_tok_new(T_END, NULL); break;
+ case ',': p_tok = lex_tok_new(T_COMMA, NULL); break;
+ case '\'': p_tok = lex_tok_new(T_SQUOTE, NULL); break;
+ case '"': p_tok = lex_tok_new(T_DQUOTE, NULL); break;
}
return p_tok;
}
return lex_tok_new(T_VAR, lexer_dup(text));
}
-char* lexer_tok_type_str(lex_tok_t* p_tok) {
- switch(p_tok->type) {
- case T_END: return "T_END";
- case T_STRING: return "T_STRING";
- case T_CHAR: return "T_CHAR";
- case T_INT: return "T_INT";
- case T_FLOAT: return "T_FLOAT";
- case T_BOOL: return "T_BOOL";
- case T_LBRACE: return "T_LBRACE";
- case T_RBRACE: return "T_RBRACE";
- case T_LBRACK: return "T_LBRACK";
- case T_RBRACK: return "T_RBRACK";
- case T_LPAR: return "T_LPAR";
- case T_RPAR: return "T_RPAR";
- case T_COMMA: return "T_COMMA";
- case T_VAR: return "T_VAR";
- case T_END_FILE: return "T_END_FILE";
- default: return NULL;
- }
-}
-
static bool lexer_oneof(const char* class, char c) {
bool ret = false;
size_t sz = strlen(class);
} lexer_t;
typedef enum {
- T_END, T_STRING, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_LBRACE, T_RBRACE,
- T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_VAR, T_END_FILE
+ T_VAR, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK,
+ T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_END_FILE
} lex_tok_type_t;
typedef struct {
void lexer_skipline(lexer_t* p_lexer);
-char* lexer_tok_type_str(lex_tok_t* p_tok);
-
char* lexer_dup(const char* p_old);
#endif /* LEXER_H */
void print_tree(tree_t* p_tree, int depth) {
print_indent(depth);
if (p_tree->tag == ATOM) {
- lex_tok_t* p_tok = p_tree->ptr.tok;
- printf("<tok %s>\n", lexer_tok_type_str(p_tok));
+ pprint_token(stdout, p_tree->ptr.tok);
} else {
puts("(tree");
vec_t* p_vec = p_tree->ptr.vec;
lexer_t* p_lexer = lexer_new(NULL, stdin);
lex_tok_t* token;
while(NULL != (token = lexer_read(p_lexer))) {
- printf("<tok %s>\n", lexer_tok_type_str(token));
+ pprint_token(stdout, token);
mem_release(token);
}
mem_release(p_lexer);
--- /dev/null
+/**
+ @file prettyprint.c
+ @brief See header for details
+ $Revision$
+ $HeadURL$
+ */
+#include "pprint.h"
+
+static const char* token_type_to_string(lex_tok_type_t type) {
+ switch(type) {
+ case T_STRING: return "T_STRING";
+ case T_CHAR: return "T_CHAR";
+ case T_INT: return "T_INT";
+ case T_FLOAT: return "T_FLOAT";
+ case T_BOOL: return "T_BOOL";
+ case T_LBRACE: return "T_LBRACE";
+ case T_RBRACE: return "T_RBRACE";
+ case T_LBRACK: return "T_LBRACK";
+ case T_RBRACK: return "T_RBRACK";
+ case T_LPAR: return "T_LPAR";
+ case T_RPAR: return "T_RPAR";
+ case T_COMMA: return "T_COMMA";
+ case T_VAR: return "T_VAR";
+ case T_END: return "T_END";
+ case T_SQUOTE: return "T_SQUOTE";
+ case T_DQUOTE: return "T_DQUOTE";
+ case T_END_FILE: return "T_END_FILE";
+ default: return "???";
+ }
+}
+
+void pprint_token_type(FILE* file, lex_tok_t* token) {
+ fprintf(file, "%s", token_type_to_string(token->type));
+}
+
+void pprint_token_value(FILE* file, lex_tok_t* token) {
+ void* value = token->value;
+ switch(token->type) {
+ case T_STRING: fprintf(file, "'%s'", ((char*)value)); break;
+ case T_CHAR: fprintf(file, "\\%c", ((char)value)); break;
+ case T_INT: fprintf(file, "%d", *((long int*)value)); break;
+ case T_FLOAT: fprintf(file, "%f", *((double*)value)); break;
+ case T_BOOL: fprintf(file, "%b", ((bool)value)); break;
+ case T_VAR: fprintf(file, "%s", ((char*)value)); break;
+ default: fprintf(file, "???"); break;
+ }
+}
+
+void pprint_token(FILE* file, lex_tok_t* token)
+{
+ pprint_token_type(file, token);
+ if (token->type < T_LBRACE) {
+ fprintf(file, ":");
+ pprint_token_value(file, token);
+ }
+ fprintf(file, "\n");
+}
+
+
+void pprint_tree(FILE* file, tree_t* tree)
+{
+
+}
+
--- /dev/null
+/**
+ @file pprint.h
+ @brief TODO: Describe this file
+ $Revision$
+ $HeadURL$
+ */
+#ifndef PPRINT_H
+#define PPRINT_H
+
+#include "parser.h"
+#include "lexer.h"
+
+void pprint_token_type(FILE* file, lex_tok_t* token);
+
+void pprint_token_value(FILE* file, lex_tok_t* token);
+
+void pprint_token(FILE* file, lex_tok_t* token);
+
+void pprint_tree(FILE* file, tree_t* tree);
+
+#endif /* PPRINT_H */
def lexer(input)
out, err, status = Open3.capture3('./build/bin/sclpl-test', '--tokens', :stdin_data => input)
raise "Lexer command returned non-zero status" unless status.success?
- raise "Lexer produced error messages" unless err == ""
+ raise err unless err == ""
out.gsub(/<tok (T_[A-Z]+)>/,'\1').split
end
describe "lexer" do
it "should recognize punctuation" do
- expect(lexer('[](){};\'",')).to eq(
- ["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_VAR", "T_VAR", "T_END"])
+ expect(lexer('[](){}\'",;')).to eq(
+ ["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_LBRACE", "T_RBRACE", "T_SQUOTE", "T_DQUOTE", "T_COMMA", "T_END"])
end
end
+
describe "parser" do
it "should parse a definition" do
- expect(parser('def foo 123;')).to eq([ ['T_VAR', 'T_VAR', 'T_INT'] ])
+ expect(parser('def foo 123;')).to eq([
+ ['T_VAR:def', 'T_VAR:foo', 'T_INT:123'] ])
end
end