Commit e1422da5 authored by POTTIER Francois's avatar POTTIER Francois
Browse files

Preparing a new test in positions/.

parent 9bace029
.PHONY: all clean test
# Find Menhir.
ifndef MENHIR
MENHIR := $(shell ../../demos/find-menhir.sh)
endif
MENHIRFLAGS := --infer
OCAMLBUILD := ocamlbuild -use-ocamlfind
MAIN := calc
all:
$(OCAMLBUILD) -build-dir _ocamlyacc $(MAIN).native
$(OCAMLBUILD) -build-dir _menhir -tag fancy $(MAIN).native \
-use-menhir -menhir "$(MENHIR) $(MENHIRFLAGS)"
clean:
rm -f *~ .*~
$(OCAMLBUILD) -build-dir _ocamlyacc -clean
$(OCAMLBUILD) -build-dir _menhir -clean
test: all
echo "(1 + 2 * 10) * 2" | _ocamlyacc/$(MAIN).native
echo "(1 + 2 * 10) * 2" | _menhir/$(MAIN).native
open Lexing
let print nt startpos endpos =
Printf.printf "%s: startpos = %s/%03d, endpos = %s/%03d\n"
nt
startpos.pos_fname
startpos.pos_cnum
endpos.pos_fname
endpos.pos_cnum
open Lexing
let process (line : string) =
let linebuf = from_string line in
linebuf.lex_curr_p <- { pos_fname = "-"; pos_lnum = 1; pos_bol = 0; pos_cnum = 0 };
try
(* Run the parser on this line of input. *)
Parser.main Lexer.token linebuf
with
| Lexer.Error msg ->
Printf.fprintf stderr "%s%!" msg
| Parsing.Parse_error ->
Printf.fprintf stderr "At offset %d: syntax error.\n%!" (lexeme_start linebuf)
let process (optional_line : string option) =
match optional_line with
| None ->
()
| Some line ->
process line
let rec repeat lexbuf =
(* Attempt to read one line. *)
let optional_line, continue = Lexer.line lexbuf in
process optional_line;
if continue then
repeat lexbuf
let () =
repeat (from_channel stdin)
{
open Parser
exception Error of string
}
(* This rule looks for a single line, terminated with '\n' or eof.
It returns a pair of an optional string (the line that was found)
and a Boolean flag (false if eof was reached). *)
rule line = parse
| ([^'\n']* '\n') as line
(* Normal case: one line, no eof. *)
{ Some line, true }
| eof
(* Normal case: no data, eof. *)
{ None, false }
| ([^'\n']+ as line) eof
(* Special case: some data but missing '\n', then eof.
Consider this as the last line, and add the missing '\n'. *)
{ Some (line ^ "\n"), false }
(* This rule analyzes a single line and turns it into a stream of
tokens. *)
and token = parse
| [' ' '\t']
{ token lexbuf }
| '\n'
{ EOL }
| ['0'-'9']+ as i
{ INT (int_of_string i) }
| '+'
{ PLUS }
| '-'
{ MINUS }
| '*'
{ TIMES }
| '/'
{ DIV }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| '.'
{ DOT }
| _
{ raise (Error (Printf.sprintf "At offset %d: unexpected character.\n" (Lexing.lexeme_start lexbuf))) }
open Ocamlbuild_plugin
open Command
(* Dealing with the two parsers. *)
let fancy () : bool =
mark_tag_used "fancy";
Tags.mem "fancy" (tags_of_pathname "")
let parser_configuration () =
(* Create [parser.mly] by copying the appropriate source file. *)
copy_rule "create parser.mly"
(* source: *)
(if fancy() then "parser-menhir.mly" else "parser-ocamlyacc.mly")
(* target: *)
"parser.mly"
let () =
dispatch (function After_rules ->
parser_configuration();
| _ -> ()
)
%token <int> INT
%token PLUS MINUS TIMES DIV
%token LPAREN RPAREN
%token EOL
%token DOT
%left PLUS MINUS /* lowest precedence */
%left TIMES DIV /* medium precedence */
%nonassoc UMINUS /* highest precedence */
%start<unit> main
%%
main:
| nothing expr EOL
{}
/* Added just to exercise productions with an empty right-hand side. */
nothing:
| /* nothing */
{ Aux.print "nothing" $startpos $endpos }
/* Added just to exercise productions with an empty right-hand side, in a choice. */
optional_dot:
| nothing
| DOT
{ Aux.print "optional_dot" $startpos $endpos}
%inline operator:
PLUS | MINUS | TIMES | DIV {}
raw_expr:
| INT
| LPAREN nothing expr RPAREN
| expr operator optional_dot expr
| MINUS expr %prec UMINUS
{}
expr:
raw_expr
{ Aux.print "expr" $startpos $endpos }
%token <int> INT
%token PLUS MINUS TIMES DIV
%token LPAREN RPAREN
%token EOL
%token DOT
%left PLUS MINUS /* lowest precedence */
%left TIMES DIV /* medium precedence */
%nonassoc UMINUS /* highest precedence */
%type<unit> main
%start main
%%
main:
| nothing expr EOL
{}
/* Added just to exercise productions with an empty right-hand side. */
nothing:
| /* nothing */
{ Aux.print "nothing" (Parsing.symbol_start_pos()) (Parsing.symbol_end_pos()) }
/* Added just to exercise productions with an empty right-hand side, in a choice. */
optional_dot:
| nothing
{ Aux.print "optional_dot" (Parsing.symbol_start_pos()) (Parsing.symbol_end_pos())}
| DOT
{ Aux.print "optional_dot" (Parsing.symbol_start_pos()) (Parsing.symbol_end_pos())}
raw_expr:
| INT
{}
| LPAREN nothing expr RPAREN
{}
| expr PLUS optional_dot expr
{}
| expr MINUS optional_dot expr
{}
| expr TIMES optional_dot expr
{}
| expr DIV optional_dot expr
{}
| MINUS expr %prec UMINUS
{}
expr:
raw_expr
{ Aux.print "expr" (Parsing.symbol_start_pos()) (Parsing.symbol_end_pos()) }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment