summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaweł Dybiec <pdybiec@stud.cs.uni.wroc.pl>2018-11-06 23:26:16 +0100
committerPaweł Dybiec <pdybiec@stud.cs.uni.wroc.pl>2018-11-06 23:26:16 +0100
commitc134d9be2e63f5f2b0660d19c7c6b8dd6364c9a4 (patch)
tree99244c445cb582228065d669efadb2e252d79967
parentAdd more expressions and statements (diff)
Add support for chars
-rw-r--r--source/mod_student/lexer.mll27
-rw-r--r--source/mod_student/parser.mly20
2 files changed, 31 insertions, 16 deletions
diff --git a/source/mod_student/lexer.mll b/source/mod_student/lexer.mll
index d26912f..2a4b116 100644
--- a/source/mod_student/lexer.mll
+++ b/source/mod_student/lexer.mll
@@ -32,14 +32,23 @@ let implode l =
 
   let unescape str =
     let rec aux x= match x with
-      | ['"'] -> []
-      | '\\'::'\\'::xs ->'\\'::(aux xs)
-      | '\\'::'n'::xs ->'\n'::(aux xs)
-      | '\\'::'"'::xs ->'"'::(aux xs)
+      | [] -> []
+      | '\\'::'\\'::xs -> '\\'::(aux xs)
+      | '\\'::'n'::xs  -> '\n'::(aux xs)
+      | '\\'::'"'::xs  -> '"'::(aux xs)
+      | '\\'::x::xs  -> failwith "unsupported escape sequence"
       | x::xs ->x::(aux xs)
-      | [] -> failwith "missing \" in escaped string"
-    in implode (aux (List.tl (explode str) ) )  ;;
+    in implode (aux  (explode str) )  ;;
       
+  let unescape_chr chr =
+      match (explode chr) with
+      | '\\'::'\\'::[] -> '\\'
+      | '\\'::'n' ::[] -> '\n'
+      | '\\'::'\''::[] -> '\''
+      | '\\'::c::_  -> failwith "unsupported escape sequence"
+      | c::[] ->c
+      | [] -> failwith "empty char literal"
+      | _ -> failwith "too long character literal"
 
   (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      ----------------------------------------------------------------------------- *)
@@ -52,7 +61,8 @@ let implode l =
 
   let identifier    = ['a'-'z' '_' 'A' - 'Z']['_' 'A' - 'Z' 'a'-'z' '0'-'9']*
   let integer       = ['0'-'9']+
-  let str           = "\""(([^ '\n''"''\\'])|('\\'['n''\\''"']))*"\""
+  let str           = (([^ '\n''"''\\'])|('\\'['n''\\''"']))*
+  let chr           = (([^ '\n' '\'' '\\'])|('\\'['n' '\\' '\'']))
   
   (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      ----------------------------------------------------------------------------- *)
@@ -76,7 +86,8 @@ let implode l =
       (* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
        * Miejsce na twoje reguły
        *)
-      | str as e  { STRING (unescape e) }
+      | '"' str as e '"'  { STRING (unescape e) }
+      | "'" (chr as e) "'"  { CHAR (unescape_chr e) }
       | ","       { COMMA }
       | "("       { LPAREN }
       | ")"       { RPAREN }
diff --git a/source/mod_student/parser.mly b/source/mod_student/parser.mly
index f516a9a..b039478 100644
--- a/source/mod_student/parser.mly
+++ b/source/mod_student/parser.mly
@@ -164,19 +164,26 @@ expression_highest_prec:
     | node=expression_call { node }
     | node=expression_length { node }
 expression_base:
-    | node=expression_integer { node }
     | node=expression_identifier { node }
+    | node=expression_integer { node }
+    | node=expression_char { node }
     | node=expression_string { node }
     | LPAREN node=expression RPAREN { node }
     (* TODO Add calls and arrays and other constants   *)
-expression_integer:
-    | value=INT  { EXPR_Int {tag= mkTag ();loc=mkLocation $startpos;
-                              value=Int32.of_int value} }
 expression_identifier:
     | id=identifier  { EXPR_Id {tag= mkTag ();loc=mkLocation $startpos;
                               id=id} }
+expression_integer:
+    | value=INT  { EXPR_Int {tag= mkTag ();loc=mkLocation $startpos;
+                              value=Int32.of_int value} }
+expression_char:
+    | value=CHAR  { EXPR_Char {tag= mkTag ();loc=mkLocation $startpos;
+                              value=value} }
 expression_string:
-    | value=str  { EXPR_String {tag= mkTag ();loc=mkLocation $startpos;
+    | value=STRING  { EXPR_String {tag= mkTag ();loc=mkLocation $startpos;
+                              value=value} }
+expression_bool:
+    | value=BOOL  { EXPR_Bool {tag= mkTag ();loc=mkLocation $startpos;
                               value=value} }
 expression_call:
     | value=call  { EXPR_Call value }
@@ -213,9 +220,6 @@ lvalue:
 identifier:
     |  IDENTIFIER
     { Identifier $1 }
-str:
-    |  STRING
-    {  $1 }
 
 (* 
    ** przykład użycia mkLocation