]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Added parser spec
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 9 Oct 2014 01:43:18 +0000 (21:43 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 9 Oct 2014 01:43:18 +0000 (21:43 -0400)
source/sclpl/grammar.c
source/sclpl/lexer.c
source/sclpl/lexer.h
source/sclpl/parser.c
source/sclpl/parser.h
spec/lexer_spec.rb
spec/parser_spec.rb

index 5dd497a020de375a4871ae9fd599d5e97b334011..a36d394fdbc45cfe1eb6ab42ddfffe0ea2e0f92e 100644 (file)
@@ -5,6 +5,7 @@
   $HeadURL$
   */
 #include "grammar.h"
+#include "lexer.h"
 #include "exn.h"
 
 tree_t* grammar_toplevel(parser_t* p_parser)
@@ -39,6 +40,7 @@ void grammar_definition(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);
index dc0f6aeda1488c84196d75a1dcd01043f34f94c2..19780d55c5d332ad664361e6a732fd20af6262c3 100644 (file)
@@ -21,7 +21,6 @@ static lex_tok_t* lexer_bool(char* text);
 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) {
@@ -30,7 +29,7 @@ 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;
@@ -209,7 +208,7 @@ static bool is_float(char* text) {
     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);
index 40d65fa559f4adc97c4b796cd0e1e33ebb3b35ed..8e06e986884226610ff6bc69b8260cc24d257b92 100644 (file)
@@ -31,10 +31,14 @@ typedef struct {
 
 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 */
index 804416f98762ec7c37e44c601465f51dc2cee42f..5bbf9e514fbfc79ec872dd7d61e304de00fb15f3 100644 (file)
@@ -149,3 +149,9 @@ tree_t* parser_get_tree(parser_t* p_parser) {
     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);
+}
+
index 2dc1624ed1c93b49b6b5006bb4e2a28f25da2543..cc6d15cd918c873683f2436c996fda520cd9af8e 100644 (file)
@@ -57,4 +57,6 @@ void parser_reduce(parser_t* p_parser, size_t mark);
 
 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 */
index cd7b4fbf095ee61d290a3b26507fca597c22dd73..01465198942e9629cd1b54f333eb3c07a52fe231 100644 (file)
@@ -1,6 +1,6 @@
 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 == ""
@@ -9,7 +9,7 @@ end
 
 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
index 8b137891791fe96927ad78e64b0aad7bded08bdc..1c86affb7f20c050c80bfbe71aa5839bfbc0e9ef 100644 (file)
@@ -1 +1,34 @@
+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