ocaml - Error trying to parse imaginary programming language -


i'm working on language interpreter programming language made up. here's example code, should work dies syntax error @ offset 45. when reading testcase.

{   foo = { "min" : 1 ,"max" : 5};   foo["min"] } 

the correct interpretation first line foo create map , store in variable named foo, second line looks value of field min in record foo, , starting/ending curlies semicolon wrap 2 expressions expr_seq (i.e. block) evaluates same thing last expr in it.

a simplified version of parser.mly follows:

%token <int> int %token <string> var %token semi comma colon assign quote %token lbrack rbrack lcurl rcurl %token eof  %start <int> main  %%  main: | eof     { failwith "empty input" } | e = exp eof     { e }  exp: | int     { 0 } | e = exp lbrack v = q_var rbrack     { (* map lookup *) 0 } | v = var assign e = exp     { (* assign var *) 0 } | v = var lbrack f = q_var rbrack assign e = exp     { (* assign map field *) 0 } | v = var     { printf.printf "lookup %s\n" v; 0 } | lcurl e = expr_seq rcurl     { (* block expression *) 0 } | lcurl f = fields rcurl     { (* map literal *)0 }  fields: | v = q_var colon e = exp     { [(v, e)] } | v = q_var colon e = exp comma vt = fields     { (v, e) :: vt }  q_var: | quote v = var quote     { printf.printf "qvar %s\n" v; v }  expr_seq: | e = exp     {[e]} |e1 = exp semi e2 = expr_seq     {e1 :: e2}  

trying debug on own, found if removed following | v = var lbrack f = q_var rbrack assign e = exp parse , run correctly, i'd able set things in maps.

i'm 98% confident problem lies in mly file, simplified version of lexer.mll follows:

{   open parser   open printf }  rule token = parse | [' ' '\t' '\n']     { token lexbuf } | "="     {assign} | ['1'-'9']['0'-'9']*     { int (int_of_string i) } | ['a'-'z']+ v     { printf "var %s\n" v;var v } | '{'     { lcurl } | '}'     { rcurl } | '['     { printf "["; lbrack } | ']'     { printf "]"; rbrack } | ';'     { semi } | ':'     { colon } | ','     { comma } | '"'     { quote } | eof     { eof } | _     { raise (failure (sprintf "at offset %d: unexpected character.\n"                         (lexing.lexeme_start lexbuf))) } 

and simple ml file is:

open core.std open printf  let rec read_all ic =   try     let ln = input_line ic in       ln ^ read_all ic   end_of_file -> "";;  let () =   let linebuf = lexing.from_string (read_all stdin) in   try     parser.main lexer.token linebuf;     printf "done"     | failure msg ->       fprintf stderr "%s%!" msg   | parser.error ->       fprintf stderr "syntax error @ offset %d.\n%!"            (lexing.lexeme_start linebuf) 

edit: here's makefile. parser.mly, lexer.mll, , interpreter.ml second, third, , fourth files above.

all: hb lexer.cmx parser.cmx interpreter.cmx     @true  hb: interpreter.cmx     ocamlfind ocamlopt -o hb -linkpkg -package core -package core_kernel \     -thread -w -10 parser.cmx lexer.cmx interpreter.cmx  interpreter.cmx: lexer.cmx     ocamlfind ocamlopt -package core -package core_kernel -thread -w   -10 \     -c interpreter.ml  lexer.cmx: lexer.ml parser.cmx     ocamlfind ocamlopt    -c lexer.ml  parser.cmx: parser.mly     menhir --ocamlc "ocamlfind ocamlc" --infer --base parser  parser.mly     ocamlfind ocamlc -c parser.mli     ocamlfind ocamlopt -c parser.ml  lexer.ml: lexer.mll     ocamllex lexer.mll  clean:     @rm hb *.o *.cmi *.cmx lexer.ml parser.ml parser.mli 2>/dev/null || true 

and here's making / running it, test.in first 1 above.

$ mk;hb < test.in ocamllex lexer.mll menhir --ocamlc "ocamlfind ocamlc" --infer --base parser  parser.mly 15 states, 286 transitions, table size 1234 bytes warning: 3 states have shift/reduce conflicts. warning: 3 shift/reduce conflicts arbitrarily resolved. ocamlfind ocamlc -c parser.mli ocamlfind ocamlopt -c parser.ml ocamlfind ocamlopt    -c lexer.ml ocamlfind ocamlopt -package core -package core_kernel -thread -w -10 \     -c interpreter.ml ocamlfind ocamlopt -o hb -linkpkg -package core -package core_kernel \     -thread -w -10 parser.cmx lexer.cmx interpreter.cmx syntax error @ offset 45. var foo var min qvar min var max qvar max var foo [var min ]qvar min 

edit 2: ended adding | e = var lbrack v = q_var rbrack { getmap(v,lookupvar(e)) } special case parser. so, problem solved?

i've tried play language, , agree parser, input bad, @ "assign map field" rule:

v = var lbrack f = q_var rbrack assign e = exp 

if remove noisy variables (that don't need use, btw):

var lbrack q_var rbrack assign exp 

that means rule expects:

var, '[' '"' var '"' ']' '=' exp 

for example

foo["min"] = 42 

the following accepted

{   foo = { "min" : 1 ,"max" : 5};   foo["min"] = 42 } 

Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -