Skip to content

Commit

Permalink
Merge dev
Browse files Browse the repository at this point in the history
fix #14
  • Loading branch information
Lelio-Brun committed Jul 2, 2024
1 parent 94a976a commit de76980
Show file tree
Hide file tree
Showing 34 changed files with 877 additions and 528 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## v0.7.0 - 2024=07-03
- support for EBNF output ([#14](https://github.com/Lelio-Brun/Obelisk/issues/14))
- rewriting of the printers
- switch to Github Actions for CI

## v0.6.0 - 2021-02-09
This version adds support for the Menhir standard rules `endrule`, `midrule`, `rev`, `flatten` and `append`.

Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ PREFIX=my
MAIN=main
EXE=dune exec $(SRC)/main.exe --

.PHONY: all latex htmlcss html default reco readme tests clean
.PHONY: all latex htmlcss html default ebnf reco readme tests clean

all:
@dune build
Expand All @@ -16,7 +16,7 @@ all:
@$(EXE) latex -prefix $(PREFIX) -$* $(PARSER) -o $@

%.pdf: %.tex
@pdflatex -interaction batchmode $<
pdflatex -interaction batchmode $<

%.png: %.pdf
@convert -quiet -density 150 $< -format png $(MISC)/$@
Expand All @@ -38,13 +38,21 @@ default:
@printf "\nDefault output on $(PARSER):\n"
@$(EXE) $(PARSER)

ebnf:
@printf "\nEBNF output on $(PARSER):\n"
@$(EXE) ebnf $(PARSER)

reco:
@printf "Default output on $(RECO):\n"
@$(EXE) $(RECO)
@printf "Default output on $(RECO) with '-i' switch:\n"
@$(EXE) -i $(RECO)
@printf "EBNF output on $(RECO):\n"
@$(EXE) ebnf $(RECO)
@printf "EBNF output on $(RECO) with '-i' switch:\n"
@$(EXE) ebnf -i $(RECO)

readme: latex htmlcss html default reco
readme: latex htmlcss html default ebnf reco

tests:
@dune test
Expand Down
150 changes: 136 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<<<<<<< HEAD
# Obelisk ![Build Status](https://github.com/Lelio-Brun/Obelisk/actions/workflows/main.yml/badge.svg?branch=master) [![Mentioned in Awesome OCaml](https://awesome.re/mentioned-badge.svg)](https://github.com/rizo/awesome-ocaml)
**Obelisk** is a simple tool that produces pretty-printed output from a [Menhir] parser file (_.mly_).
=======
# Obelisk [![Mentioned in Awesome OCaml](https://awesome.re/mentioned-badge.svg)](https://github.com/rizo/awesome-ocaml) ![workflow badge](https://github.com/Lelio-Brun/Obelisk/actions/workflows/workflow.yml/badge.svg?branch=dev)
**Obelisk** is a simple tool which produces pretty-printed output from a [Menhir] parser file (_.mly_).
>>>>>>> origin/dev
It is inspired from [yacc2latex] and is also written in [OCaml], but is aimed at supporting features from Menhir instead of only those of [ocamlyacc].

Expand All @@ -11,10 +16,12 @@ It is inspired from [yacc2latex] and is also written in [OCaml], but is aimed at
* [Usage](#usage)
+ [Pattern recognition](#pattern-recognition)
+ [Multi-format output](#multi-format-output)
- [EBNF](#ebnf)
- [LaTeX](#latex)
- [HTML](#html)
+ [Example](#example)
- [Default](#default)
- [EBNF](#ebnf-1)
- [LaTeX](#latex-1)
* [Tabular](#tabular)
* [Syntax](#syntax)
Expand Down Expand Up @@ -61,7 +68,7 @@ dune install [--prefix <the destination directory>]

## Usage
```
obelisk [latex|html] [options] <files>
obelisk [ebnf|latex|html] [options] <files>
```

If multiple files are specified, **Obelisk** will output a concatenated result without consistency checks.
Expand Down Expand Up @@ -100,14 +107,14 @@ my_separated_list(X,S):
| {}
| my_separated_nonempty_list(X,S) {}
my_rule(E,F,S1,S2):
my_rule:
| my_option(E, F) {}
| my_list(E) {}
| my_nonempty_list(F) {}
| my_separated_nonempty_list(E,S1) {}
| my_separated_list(F,S2) {}
```
**Obelisk** outputs:
**Obelisk** (`obelisk misc/reco.mly`) outputs:
```
<my_option(X, Y)> ::= [Y X]
Expand All @@ -119,26 +126,66 @@ my_rule(E,F,S1,S2):
<my_separated_list(X, S)> ::= [X (S X)*]
<my_rule(E, F, S1, S2)> ::= <my_option(E, F)>
| <my_list(E)>
| <my_nonempty_list(F)>
| <my_separated_nonempty_list(E, S1)>
| <my_separated_list(F, S2)>
<my_rule> ::= <my_option(E, F)>
| <my_list(E)>
| <my_nonempty_list(F)>
| <my_separated_nonempty_list(E, S1)>
| <my_separated_list(F, S2)>
```
And with the `-i` switch:
And with the `-i` switch (`obelisk -i misc/reco.mly`):
```
<my_rule(E, F, S1, S2)> ::= [F E]
| E*
| F+
| E (S1 E)*
| [F (S2 F)*]
<my_rule> ::= [F E]
| E*
| F+
| E (S1 E)*
| [F (S2 F)*]
```

### Multi-format output
<<<<<<< HEAD
By default, the output format is a simple text format that is close to the BNF syntax.
You can use the subcommands `latex` or `html` to get a LaTeX (resp. HTML) file.

In default and HTML mode, the option `-noaliases` avoids printing token aliases in the output.
=======
By default the output format is a simple text format close to the BNF syntax.
You can use the subcommands `ebnf`, `latex` or `html` to get respectively an EBNF text output, LaTeX output or HTML output.

In default, EBNF and HTML mode, the option `-noaliases` avoid printing token aliases in the output.

#### EBNF
In EBNF mode, parameterized rules are specialized into dedicated regular rules.
On the example above (`obelisk ebnf misc/reco.mly`):

```
my_rule ::= my_option_0
| my_list_0
| my_nonempty_list_0
| my_separated_nonempty_list_0
| my_separated_list_0
my_option_0 ::= (F E)?
my_nonempty_list_0 ::= F+
my_separated_nonempty_list_1 ::= F (S2 F)*
my_separated_list_0 ::= (F (S2 F)*)?
my_separated_nonempty_list_0 ::= E (S1 E)*
my_list_0 ::= E*
```
And with the `-i` switch (`obelisk ebnf -i misc/reco.mly`):

```
my_rule ::= (F E)?
| E*
| F+
| E (S1 E)*
| (F (S2 F)*)?
```
>>>>>>> origin/dev
#### LaTeX
Use the following options to tweak the LaTeX:
Expand Down Expand Up @@ -252,6 +299,81 @@ Here are the outputs of the different formats obtained by **Obelisk** from its o
| QID
```

#### EBNF

```
specification ::= rule* EOF
rule ::= old_rule
| new_rule
old_rule ::= flags? ident ATTRIBUTE* parameters_0 COLON optional_bar group
(BAR group)* SEMICOLON*
flags ::= PUBLIC
| INLINE
| PUBLIC INLINE
| INLINE PUBLIC
optional_bar ::= BAR?
group ::= production (BAR production)* ACTION precedence?
production ::= producer* precedence?
producer ::= (LID EQ)? actual ATTRIBUTE* SEMICOLON*
actual ::= generic_actual_0
lax_actual ::= generic_actual_0
| group (BAR group)*
new_rule ::= PUBLIC? LET LID ATTRIBUTE* parameters_0 binder expression
binder ::= COLONEQ
| EQEQ
expression ::= optional_bar seq_expression (BAR seq_expression)*
seq_expression ::= (pattern EQ)? symbol_expression SEMICOLON seq_expression
| symbol_expression
| action_expression
symbol_expression ::= ident parameters_2
| symbol_expression modifier
action_expression ::= action
| action precedence
| precedence action
action ::= ACTION
| POINTFREEACTION
pattern ::= LID
| UNDERSCORE
| TILDE
| LPAR (pattern (COMMA pattern)*)? RPAR
modifier ::= OPT
| PLUS
| STAR
precedence ::= PREC ident
ident ::= UID
| LID
| QID
generic_actual_0 ::= ident parameters_1
| actual modifier
parameters_1 ::= (LPAR (lax_actual (COMMA lax_actual)*)? RPAR)?
parameters_0 ::= (LPAR (ident (COMMA ident)*)? RPAR)?
parameters_2 ::= (LPAR (expression (COMMA expression)*)? RPAR)?
```

#### LaTeX
##### Tabular
![Tabular](misc/tabular.png)
Expand Down
4 changes: 2 additions & 2 deletions dune-project
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(lang dune 2.0)

(name obelisk)
(version 0.6.0)
(version 0.7.0)

(using menhir 2.0)
(generate_opam_files true)
Expand All @@ -11,7 +11,7 @@
(documentation https://github.com/Lelio-Brun/Obelisk/blob/master/README.md)
(license MIT)
(authors "Lélio Brun")
(maintainers "Lélio Brun <lelio.brun@inria.fr>")
(maintainers "Lélio Brun <lb@leliobrun.net>")

(package
(name obelisk)
Expand Down
Binary file modified misc/backnaur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified misc/html.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified misc/htmlcss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion misc/reco.mly
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ my_separated_list(X,S):
| {}
| my_separated_nonempty_list(X,S) {}

my_rule(E,F,S1,S2):
my_rule:
| my_option(E, F) {}
| my_list(E) {}
| my_nonempty_list(F) {}
Expand Down
Binary file modified misc/syntax.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified misc/tabular.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions obelisk.opam
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
version: "0.6.0"
version: "0.7.0"
synopsis: "Pretty-printing for Menhir files"
description: """
Obelisk is a simple tool which produces pretty-printed output from a Menhir parser file (.mly).
It is inspired from yacc2latex and is also written in OCaml, but is aimed at supporting features from Menhir instead of only those of ocamlyacc."""
maintainer: ["Lélio Brun <lelio.brun@inria.fr>"]
maintainer: ["Lélio Brun <lb@leliobrun.net>"]
authors: ["Lélio Brun"]
license: "MIT"
homepage: "https://github.com/Lelio-Brun/Obelisk"
Expand Down
12 changes: 12 additions & 0 deletions src/common.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
(** Some common facilities. *)

(** Find a rule by its left-hand side (name) in the grammar. *)
let find_rule r rules =
let open ExtendedAst in
List.find_opt (fun { name; _ } -> name = r) rules

(** The signature for the set of symbols appearing in a grammar. *)
module type SYMBOLS = sig
(** The set of symbols. *)
Expand Down Expand Up @@ -41,6 +46,9 @@ module type SYMBOLS = sig
See {!defined}. *)
val is_defined: string -> t -> string list option

(** Test if the given symbol actually appears as a symbol. *)
val is_symbol: string -> t -> bool

end

(** The actual implementation for the set of symbols, see {!SYMBOLS}. *)
Expand Down Expand Up @@ -116,4 +124,8 @@ module Symbols : SYMBOLS = struct
end
with Not_found -> None

(** See {!SYMBOLS.is_symbol}. *)
let is_symbol x m =
M.mem x m

end
2 changes: 1 addition & 1 deletion src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(name main)
(public_name obelisk)
(package obelisk)
(modules_without_implementation ast extendedAst helper printer)
(modules_without_implementation ast helper printer)
(libraries re))

(include_subdirs unqualified)
Expand Down
43 changes: 43 additions & 0 deletions src/extendedAst.mli → src/extendedAst.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,46 @@ and pattern =
| NEList of actual (** [nonempty_list(x)] *)
| SepList of actual * actual (** [separated_list(x)] *)
| SepNEList of actual * actual (** [separated_nonempty_list(sep, x)] *)

let fold_map_pattern f acc = function
| Option x ->
let acc, x = f acc x in
acc, Option x
| Pair (x, y) ->
let acc, x = f acc x in
let acc, y = f acc y in
acc, Pair (x, y)
| SepPair (x, sep, y) ->
let acc, x = f acc x in
let acc, sep = f acc sep in
let acc, y = f acc y in
acc, SepPair (x, sep, y)
| Preceded (o, x) ->
let acc, o = f acc o in
let acc, x = f acc x in
acc, Preceded (o, x)
| Terminated (x, c) ->
let acc, x = f acc x in
let acc, c = f acc c in
acc, Terminated (x, c)
| Delimited (o, x, c) ->
let acc, o = f acc o in
let acc, x = f acc x in
let acc, c = f acc c in
acc, Delimited (o, x, c)
| List x ->
let acc, x = f acc x in
acc, List x
| NEList x ->
let acc, x = f acc x in
acc, NEList x
| SepList (sep, x) ->
let acc, sep = f acc sep in
let acc, x = f acc x in
acc, SepList (sep, x)
| SepNEList (sep, x) ->
let acc, sep = f acc sep in
let acc, x = f acc x in
acc, SepNEList (sep, x)

let map_pattern f p = fold_map_pattern (fun o p -> o, f p) None p |> snd
Loading

0 comments on commit de76980

Please sign in to comment.