Commit e78d5ac8 authored by POTTIER Francois's avatar POTTIER Francois

Created quicktest/test.sh.

This is a copy of the calc demo, plus a script that runs the parser
in three different modes (code, table, reference interpreter) and
checks the results.
parent 697a8d98
calc
lexer.ml
parser.ml
parser.mli
*.cmi
*.cmo
*.cmx
*.o
*.d
table.out
table.err
code.out
code.err
interpret.out
interpret.err
PGFLAGS := --infer
GENERATED := parser.ml parser.mli lexer.ml
MODULES := parser lexer calc
EXECUTABLE := calc
OCAMLDEPWRAPPER := ../demos/ocamldep.wrapper
include ../demos/Makefile.shared
include ../demos/Makefile.auto
let process (line : string) =
let linebuf = Lexing.from_string line in
try
(* Run the parser on this line of input. *)
Printf.printf "%d\n%!" (Parser.main Lexer.token linebuf)
with
| Lexer.Error msg ->
Printf.fprintf stderr "%s%!" msg
| Parser.Error ->
Printf.fprintf stderr "At offset %d: syntax error.\n%!" (Lexing.lexeme_start linebuf)
let process (optional_line : string option) =
match optional_line with
| None ->
()
| Some line ->
process line
let rec repeat channel =
(* Attempt to read one line. *)
let optional_line, continue = Lexer.line channel in
process optional_line;
if continue then
repeat channel
let () =
repeat (Lexing.from_channel stdin)
Lookahead token is now INT (-1--1)
State 0:
Shifting (INT) to state 3
State 3:
Lookahead token is now PLUS (-1--1)
Reducing production expr -> INT
State 16:
Shifting (PLUS) to state 8
State 8:
Lookahead token is now INT (-1--1)
Shifting (INT) to state 3
State 3:
Lookahead token is now TIMES (-1--1)
Reducing production expr -> INT
State 9:
Shifting (TIMES) to state 5
State 5:
Lookahead token is now INT (-1--1)
Shifting (INT) to state 3
State 3:
Lookahead token is now PLUS (-1--1)
Reducing production expr -> INT
State 6:
Reducing production expr -> expr TIMES expr
State 9:
Reducing production expr -> expr PLUS expr
State 16:
Shifting (PLUS) to state 8
State 8:
Lookahead token is now INT (-1--1)
Shifting (INT) to state 3
State 3:
Lookahead token is now EOL (-1--1)
Reducing production expr -> INT
State 9:
Reducing production expr -> expr PLUS expr
State 16:
Shifting (EOL) to state 17
State 17:
Reducing production main -> expr EOL
State 15:
Accepting
{
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 }
| _
{ raise (Error (Printf.sprintf "At offset %d: unexpected character.\n" (Lexing.lexeme_start lexbuf))) }
%token <int> INT
%token PLUS MINUS TIMES DIV
%token LPAREN RPAREN
%token EOL
%left PLUS MINUS /* lowest precedence */
%left TIMES DIV /* medium precedence */
%nonassoc UMINUS /* highest precedence */
%start <int> main
%%
main:
| e = expr EOL
{ e }
expr:
| i = INT
{ i }
| LPAREN e = expr RPAREN
{ e }
| e1 = expr PLUS e2 = expr
{ e1 + e2 }
| e1 = expr MINUS e2 = expr
{ e1 - e2 }
| e1 = expr TIMES e2 = expr
{ e1 * e2 }
| e1 = expr DIV e2 = expr
{ e1 / e2 }
| MINUS e = expr %prec UMINUS
{ - e }
Lookahead token is now INT (0-3)
State 0:
Shifting (INT) to state 3
State 3:
Lookahead token is now PLUS (4-5)
Reducing production expr -> INT
State 16:
Shifting (PLUS) to state 8
State 8:
Lookahead token is now INT (6-7)
Shifting (INT) to state 3
State 3:
Lookahead token is now TIMES (8-9)
Reducing production expr -> INT
State 9:
Shifting (TIMES) to state 5
State 5:
Lookahead token is now INT (10-11)
Shifting (INT) to state 3
State 3:
Lookahead token is now PLUS (12-13)
Reducing production expr -> INT
State 6:
Reducing production expr -> expr TIMES expr
State 9:
Reducing production expr -> expr PLUS expr
State 16:
Shifting (PLUS) to state 8
State 8:
Lookahead token is now INT (14-17)
Shifting (INT) to state 3
State 3:
Lookahead token is now EOL (17-18)
Reducing production expr -> INT
State 9:
Reducing production expr -> expr PLUS expr
State 16:
Shifting (EOL) to state 17
State 17:
Reducing production main -> expr EOL
State 15:
Accepting
#!/bin/sh
# This script checks that the code back-end, the table back-end, and the
# reference interpreter appear to be working correctly. It uses the calc
# demo for this purpose.
SRC=../src
BUILD=$SRC/_stage1
MENHIR=$BUILD/menhir.native
# Make sure Menhir is up-to-date.
rm -f $SRC/installation.ml
rm -rf $BUILD
echo "Building Menhir..."
if ! make -C $SRC >/dev/null ; then
echo "Could not build Menhir. Stop."
exit 1
fi
echo "Building MenhirLib..."
if ! make -C $SRC library >/dev/null ; then
echo "Could not build MenhirLib. Stop."
exit 1
fi
# Re-install MenhirLib.
ocamlfind remove menhirLib
ocamlfind install menhirLib $SRC/META $BUILD/menhirLib.cmi $BUILD/menhirLib.cmo $BUILD/menhirLib.cmx $BUILD/menhirLib.o
# Build the parser with the code back-end and run it.
echo "Building and running (code)..."
make clean >/dev/null
make MENHIR="$MENHIR --trace" >/dev/null
echo "122 + 2 * 3 + 128" | ./calc > code.out 2> code.err
# Build the parser with the table back-end and run it.
echo "Building and running (table)..."
make clean >/dev/null
make MENHIR="$MENHIR --trace --table" >/dev/null
echo "122 + 2 * 3 + 128" | ./calc > table.out 2> table.err
# Run the reference interpreter.
echo "Running the reference interpreter..."
echo "INT PLUS INT TIMES INT PLUS INT EOL" | $MENHIR --trace --interpret parser.mly > interpret.out 2> interpret.err
echo "Comparing results..."
# Compare the results to the reference outputs.
for mode in code table ; do
if ! diff -q ref.out $mode.out >/dev/null ; then
echo "The $mode parser produces a wrong result!"
echo "Expected:"
cat ref.out
echo "Got:"
cat $mode.out
fi
done
# Compare the logs to the reference logs.
for mode in code table ; do
if ! diff -q ref.err $mode.err >/dev/null ; then
echo "The $mode parser produces a wrong trace!"
diff ref.err $mode.err
fi
done
# Check the results of the reference interpreter.
if ! diff -q interpret-ref.out interpret.out >/dev/null ; then
echo "The reference interpreter produces a wrong result!"
echo "Expected:"
cat interpret-ref.out
echo "Got:"
cat interpret.out
fi
if ! diff -q interpret-ref.err interpret.err >/dev/null ; then
echo "The reference interpreter produces a wrong trace!"
diff interpret-ref.err interpret.err
fi
echo "Done."
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