;; -----------------------------------------------------------------------------

;; Constructing the lexer, parser, and executable.

(ocamllex
  (modules lexer)
)

;; Several rules in this file and in the Makefile invoke Menhir. They must
;; share the same flags, at least as far as the flags that influence the
;; construction of the automaton are concerned, so that they all work with
;; the same automaton.

;; The following rule uses Menhir's code back-end to obtain the module Parser.

(menhir
  (modules parser)
  (flags -lg 1 -la 1 -lc 2)
)

;; The link_deps field requires running the completeness check (see below).

(executable
  (name calc)
  (flags -w A-4-70)
  (libraries menhirLib)
  (link_deps parserMessages.check)
)

;; The following two rules create a copy of the file parser.mly named
;; unitActionsParser.mly. This is a copy of the grammar where the semantic
;; actions have been removed and replaced with unit values. It is compiled
;; by Menhir's table back-end to obtain the module UnitActionsParser.

;; The use of [--external-tokens Parser] is required for the two parsers
;; to share a single [token] type. This makes them usable with the same
;; lexer.

(rule
  (action
    (with-stdout-to unitActionsParser.mly
      (run menhir
        %{dep:parser.mly}
        --only-preprocess-u
))))

(menhir
  (modules unitActionsParser)
  (flags --table --external-tokens Parser)
)

;; -----------------------------------------------------------------------------

;; This section deals with the .messages file.

;; The following rule generates "parserMessages.ml" based on the source file
;; "parserMessages.messages". It requires the completeness check to have been
;; performed first. (If desired, this check could be disabled.)

(rule
  (deps parserMessages.check)
  (action (with-stdout-to parserMessages.ml
    (run menhir
      %{dep:parser.mly}
      --compile-errors %{dep:parserMessages.messages}
    )
  ))
)

;; This rule generates a file "parserMessages.auto.messages" that contains a
;; list of all error states. It is used by the completeness check.

(rule
  (with-stdout-to parserMessages.auto.messages
    (run menhir
       %{dep:parser.mly}
       --list-errors
    )
  )
)

;; This rule implements the completeness check. It checks that every error
;; state listed in the auto-generated file "parserMessages.auto.messages"
;; is also listed in the file "parserMessages.messages" that is maintained
;; by the programmer.

(rule
  (with-stdout-to parserMessages.check
  (run menhir
    %{dep:parser.mly}
    --compare-errors %{dep:parserMessages.auto.messages}
    --compare-errors %{dep:parserMessages.messages}
  ))
)

;; -----------------------------------------------------------------------------

;; Tests.

(rule
  (with-outputs-to calc00.out
  (with-accepted-exit-codes 0
    (run ./calc.exe %{dep:calc00.in})
)))

(rule
  (alias test)
  (action (diff calc00.exp calc00.out))
)

(rule
  (with-outputs-to calc01.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc01.in})
)))

(rule
  (alias test)
  (action (diff calc01.exp calc01.out))
)

(rule
  (with-outputs-to calc02.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc02.in})
)))

(rule
  (alias test)
  (action (diff calc02.exp calc02.out))
)

(rule
  (with-outputs-to calc03.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc03.in})
)))

(rule
  (alias test)
  (action (diff calc03.exp calc03.out))
)

(rule
  (with-outputs-to calc04.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc04.in})
)))

(rule
  (alias test)
  (action (diff calc04.exp calc04.out))
)

(rule
  (with-outputs-to calc05.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc05.in})
)))

(rule
  (alias test)
  (action (diff calc05.exp calc05.out))
)

(rule
  (with-outputs-to calc06.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc06.in})
)))

(rule
  (alias test)
  (action (diff calc06.exp calc06.out))
)

(rule
  (with-outputs-to calc07.out
  (with-accepted-exit-codes 1
    (run ./calc.exe %{dep:calc07.in})
)))

(rule
  (alias test)
  (action (diff calc07.exp calc07.out))
)
