From c134d9be2e63f5f2b0660d19c7c6b8dd6364c9a4 Mon Sep 17 00:00:00 2001 From: Paweł Dybiec Date: Tue, 6 Nov 2018 23:26:16 +0100 Subject: Add support for chars --- source/mod_student/lexer.mll | 27 +++++++++++++++++++-------- source/mod_student/parser.mly | 20 ++++++++++++-------- 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 -- cgit 1.4.1