$HeadURL$
*/
#include "grammar.h"
+#include "lexer.h"
#include "exn.h"
tree_t* grammar_toplevel(parser_t* p_parser)
size_t mark = parser_mark(p_parser);
parser_expect(p_parser,T_VAR);
if (parser_peek(p_parser)->type == T_LPAR) {
+ parser_insert(p_parser, T_VAR, lexer_dup("fn"));
grammar_fn_stmnt(p_parser);
} else {
grammar_expression(p_parser);
static lex_tok_t* lexer_var(char* text);
static bool lexer_oneof(const char* class, char c);
static bool is_float(char* text);
-static char* lexer_dup(const char* p_old);
static int read_radix(char ch);
static void lex_tok_free(void* p_obj) {
mem_release(p_tok->value);
}
-static lex_tok_t* lex_tok_new(lex_tok_type_t type, void* val) {
+lex_tok_t* lex_tok_new(lex_tok_type_t type, void* val) {
lex_tok_t* p_tok = (lex_tok_t*)mem_allocate(sizeof(lex_tok_t), &lex_tok_free);
p_tok->type = type;
p_tok->value = val;
return false;
}
-static char* lexer_dup(const char* p_old) {
+char* lexer_dup(const char* p_old) {
size_t length = strlen(p_old);
char* p_str = (char*)mem_allocate(length+1, NULL);
memcpy(p_str, p_old, length);
lexer_t* lexer_new(char* p_prompt, FILE* p_input);
+lex_tok_t* lex_tok_new(lex_tok_type_t type, void* val);
+
lex_tok_t* lexer_read(lexer_t* p_lexer);
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 */
return p_tree;
}
+void parser_insert(parser_t* p_parser, lex_tok_type_t type, void* value) {
+ lex_tok_t* p_tok = lex_tok_new(type, value);
+ tree_t* p_tree = parser_tree_new(ATOM, p_tok);
+ vec_push_back(p_parser->p_tok_buf, p_tree);
+}
+
tree_t* parser_get_tree(parser_t* p_parser);
+void parser_insert(parser_t* p_parser, lex_tok_type_t type, void* value);
+
#endif /* PARSER_H */
require 'open3'
-def tokens(input)
+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 == ""
describe "lexer" do
it "should recognize punctuation" do
- expect(tokens('[](){};\'",')).to eq(
+ expect(lexer('[](){};\'",')).to eq(
["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_VAR", "T_VAR", "T_END"])
end
end
+require 'open3'
+def re_structure( token_array, offset = 0 )
+ struct = []
+ while( offset < token_array.length )
+ if(token_array[offset] == "(")
+ # Multiple assignment from the array that re_structure() returns
+ offset, tmp_array = re_structure(token_array, offset + 1)
+ struct << tmp_array
+ elsif(token_array[offset] == ")")
+ break
+ else
+ struct << token_array[offset]
+ end
+ offset += 1
+ end
+ return [offset, struct]
+end
+
+def parser(input)
+ out, err, status = Open3.capture3('./build/bin/sclpl-test', '--ast', :stdin_data => input)
+ raise "Parser command returned non-zero status" unless status.success?
+ raise "Parser produced error messages" unless err == ""
+ out.gsub!(/<tok (T_[A-Z]+)>/,'\1')
+ out.gsub!(/([()])|tree/,' \1 ')
+ off, expr = re_structure(out.split)
+ expr
+end
+
+describe "parser" do
+ it "should parse a definition" do
+ expect(parser('def foo 123;')).to eq([ ['T_VAR', 'T_VAR', 'T_INT'] ])
+ end
+end