From fb3b76ee78bb4dcb00e1e86d2d3242f2ea95573d Mon Sep 17 00:00:00 2001 From: Toshio Sekiya Date: Wed, 3 Mar 2021 23:45:54 +0900 Subject: [PATCH] Add mktbl. Change line numbering in html and latex. write sec23 but halfway. --- .gitignore | 2 + Rakefile | 22 +- Readme.md | 1 + doc/Readme_for_developers.md | 119 ++++- gfm/sec12.md | 2 +- gfm/sec19.md | 2 +- gfm/sec23.md | 380 ++++++++++++++ image/color_square.png | Bin 0 -> 45632 bytes image/color_square.xcf | Bin 0 -> 346122 bytes image/turtle_compile_process.png | Bin 0 -> 30101 bytes image/turtle_compile_process.xcf | Bin 0 -> 98133 bytes image/turtle_parser_tree.png | Bin 0 -> 23978 bytes image/turtle_parser_tree.xcf | Bin 0 -> 49799 bytes lib/lib_add_head_tail_html.rb | 67 ++- lib/lib_gen_main_tex.rb | 25 +- lib/lib_mktbl.rb | 262 ++++++++++ lib/lib_src2md.rb | 259 +++++---- sample.html | 110 ++++ sample.md | 18 + src/mktbl.rb | 32 ++ src/sec12.src.md | 2 +- src/sec14.src.md | 12 + src/sec19.src.md | 18 +- src/sec23.src.md | 869 +++++++++++++++++++++++++++++++ src/sec6.src.md | 2 +- src/sec9.src.md | 2 +- src/turtle/meson.build | 2 +- src/turtle/turtle.lex | 4 +- src/turtle/turtle.y | 22 +- src/turtle/turtle_doc.md | 33 +- test/test_lib_mktbl.rb | 4 + test/test_lib_src2md.rb | 233 ++++++++- test/test_mktbl.rb | 62 +++ 33 files changed, 2365 insertions(+), 201 deletions(-) create mode 100644 gfm/sec23.md create mode 100644 image/color_square.png create mode 100644 image/color_square.xcf create mode 100644 image/turtle_compile_process.png create mode 100644 image/turtle_compile_process.xcf create mode 100644 image/turtle_parser_tree.png create mode 100644 image/turtle_parser_tree.xcf create mode 100644 lib/lib_mktbl.rb create mode 100644 sample.html create mode 100644 sample.md create mode 100644 src/mktbl.rb create mode 100644 src/sec23.src.md create mode 100644 test/test_lib_mktbl.rb create mode 100644 test/test_mktbl.rb diff --git a/.gitignore b/.gitignore index f938ff3..8ed22e9 100755 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ src/toi.rb src/misc/a.out src/misc/cairo2.c src/misc/cairo2.pdf +src/misc/color_square.c +src/misc/color_square.png src/tfv/a.out src/tfe/a.out src/tfe/hello.txt diff --git a/Rakefile b/Rakefile index 3e6ef30..12c1f9a 100644 --- a/Rakefile +++ b/Rakefile @@ -35,7 +35,7 @@ task md: ["Readme.md"] file "Readme.md" => mdfilenames do buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ] - src2md "src/abstract.src.md", "gfm/abstract.md", -1 + src2md "src/abstract.src.md", "gfm/abstract.md" File.open("gfm/abstract.md") do |file| file.readlines.each do |line| buf << line @@ -53,7 +53,7 @@ end 0.upto(srcfiles.size - 1) do |i| file "gfm/#{srcfiles[i].to_md}" => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, "gfm/#{srcfiles[i].to_md}", -1 + src2md srcfiles[i].path, "gfm/#{srcfiles[i].to_md}" if srcfiles.size == 1 nav = "Up: [Readme.md](../Readme.md)\n" elsif i == 0 @@ -74,7 +74,7 @@ task html: ["html/index.html"] file "html/index.html" => htmlfilenames+["html/tfetextview_doc.html"] do buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ] - src2md "src/abstract.src.md", "html/abstract.md", -1 + src2md "src/abstract.src.md", "html/abstract.md" File.open("html/abstract.md") do |file| file.readlines.each do |line| buf << line @@ -105,7 +105,7 @@ end html_md = "html/#{srcfiles[i].to_md}" html_html = "html/#{srcfiles[i].to_html}" file html_html => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, html_md, -1 + src2md srcfiles[i].path, html_md if srcfiles.size == 1 nav = "Up: [index.html](index.html)\n" elsif i == 0 @@ -129,8 +129,8 @@ end end task pdf: "latex" do - sh "cd latex; pdflatex main.tex" - sh "cd latex; pdflatex main.tex" + sh "cd latex; lualatex main.tex" + sh "cd latex; lualatex main.tex" sh "mv latex/main.pdf latex/gtk4_tutorial.pdf" end @@ -141,19 +141,19 @@ file "latex/main.tex" => ["latex/abstract.tex", "latex/tfetextview_doc.tex"] + t end file "latex/abstract.tex" => "src/abstract.src.md" do - src2md "src/abstract.src.md", "latex/abstract.md", 86 - sh "pandoc -o latex/abstract.tex latex/abstract.md" + src2md "src/abstract.src.md", "latex/abstract.md" + sh "pandoc --listings -o latex/abstract.tex latex/abstract.md" File.delete("latex/abstract.md") end file "latex/tfetextview_doc.tex" => "src/tfetextview/tfetextview_doc.md" do - sh "pandoc -o latex/tfetextview_doc.tex src/tfetextview/tfetextview_doc.md" + sh "pandoc --listings -o latex/tfetextview_doc.tex src/tfetextview/tfetextview_doc.md" end 0.upto(srcfiles.size - 1) do |i| file "latex/#{srcfiles[i].to_tex}" => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, "latex/#{srcfiles[i].to_md}", 86 - sh "pandoc -o latex/#{srcfiles[i].to_tex} latex/#{srcfiles[i].to_md}" + src2md srcfiles[i].path, "latex/#{srcfiles[i].to_md}" + sh "pandoc --listings -o latex/#{srcfiles[i].to_tex} latex/#{srcfiles[i].to_md}" File.delete("latex/#{srcfiles[i].to_md}") end end diff --git a/Readme.md b/Readme.md index fc56811..6c823f5 100644 --- a/Readme.md +++ b/Readme.md @@ -36,3 +36,4 @@ You can read it without download. 1. [Template XML](gfm/sec20.md) 1. [GtkDrawingArea and Cairo](gfm/sec21.md) 1. [Combine GtkDrawingArea and TfeTextView](gfm/sec22.md) +1. [Tiny turtle graphics interpreter](gfm/sec23.md) diff --git a/doc/Readme_for_developers.md b/doc/Readme_for_developers.md index 8e8bdb8..bb4e06a 100644 --- a/doc/Readme_for_developers.md +++ b/doc/Readme_for_developers.md @@ -70,17 +70,33 @@ lib_src2md.rb @@@ ~~~ -The inserted text becomes fence code block. +The inserted text is converted to fence code block. +If the target markdown is GFM, then an info string follows the beginning fence. +The following example shows the command includes a C source file "sample.c". + $ cat src/sample.c + int + main (int argc, char **argv) { + ... ... + } + $cat src/sample.src.md + ... ... + @@@include -N + sample.c + @@@ + ... ... + $ ruby src2md.rb src/sample.src.md gfm/sample.md + $ cat gfm/sample.md + ... ... ~~~C int main (int argc, char **argv) { ... ... } ~~~ + ... ... -The string ("C" in the example above) follows the first fence is called info string. -Info string is usually a language like C, ruby, xml and so on. +Info strings are usually language like C, ruby, xml and so on. This string is decided with the filename extension. A line number is inserted at the top of each line in the code block. @@ -91,7 +107,62 @@ Options: - "-n": Inserts a line number at the top of each line (default). - "-N": No line number is inserted. -This command have two advantages. + $cat src/sample.src.md + ... ... + @@@include + sample.c + @@@ + ... ... + $ ruby src2md.rb src/sample.src.md gfm/sample.md + $ cat gfm/sample.md + ... ... + ~~~C + 1 int + 2 main (int argc, char **argv) { + ... ... + 14 } + ~~~ + ... ... + +If the target markdown is an intermediate file to html, then another type of info string follows the beginning fence. +If @@@include command doesn't have -N option, then the generated markdown is: + + ~~~{.C .numberLines} + int + main (int argc, char **argv) { + ... ... + } + ~~~ +The info string `.C` specifies C language. +The info string `.numberLines` is a class of the pandoc markdown. +If the class is given, pandoc generates CSS to insert line numbers to the source code in the html file. +That's why the fence code block in the markdown doesn't have line numbers, which is different from gfm markdown. +If "-N" option is given, then the info string is `{.C}` only. + +If the target markdown is an intermediate file to latex, then an info string follows the beginning fence. + + ~~~{.C .numberLines} + int + main (int argc, char **argv) { + ... ... + } + ~~~ + +Rake uses pandoc with --listings option when it converts markdown to latex. +The generated latex file uses listings package to list source files instead of verbatim environment. +The markdwon above is converted to the following latex source file. + + \begin{lstlisting}[language=C, numbers=left] + int + main (int argc, char **argv) { + ... ... + } + \end{lstlisting} + +Listing package can color or emphasize keywords, strings, comments and directives. +But it doesn't analyze the syntax or token of the language, so the kind of emphasis target is limited. + +@@@include command have two advantages. 1. Less typing. 2. You don't need to modify your src.md file, even if the C source file is modified. @@ -167,6 +238,46 @@ It is based on the state diagram below. ![state diagram](../image/state_diagram.png) +## mktbl.rb script + +The script "mktbl.rb" is in `src` directory. +This script makes a table easy to read. +For example, a text file "sample.md" has a table like this: + +~~~ +Price list + +@@@table +|item|price| +|:-:|:-:| +|mouse|$10| +|PC|$500| +@@@ +~~~ + +Run the script. + +~~~ +$ ruby mktbl.rb sample.md +~~~ + +Then, the file is changed to: + +~~~ +Price list + +|item |price| +|:---:|:---:| +|mouse| $10 | +| PC |$500 | +~~~ + +The script makes a backup file "sample.md.bak". + +The task of the script seems easy, but the program is not so simple. +The script "mktbl.rb" uses a library script "lib/lib\_mktbl.rb" +This script is independent from "src2md.rb". + ## Directory structure There are six directories under `gtk4_tutorial` directory. diff --git a/gfm/sec12.md b/gfm/sec12.md index 1fbb348..339fcc8 100644 --- a/gfm/sec12.md +++ b/gfm/sec12.md @@ -4,7 +4,7 @@ Up: [Readme.md](../Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13] In this section I will explain functions in TfeTextView object. -### tfe.h and tfetextview.h +## tfe.h and tfetextview.h `tfe.h` is a top header file and it includes `gtk.h` and all the header files. C source files `tfeapplication.c` and `tfenotebook.c` include `tfe.h` at the beginning. diff --git a/gfm/sec19.md b/gfm/sec19.md index 1fc2ce9..bdfaa7a 100644 --- a/gfm/sec19.md +++ b/gfm/sec19.md @@ -1111,7 +1111,7 @@ After compilation, you can test your application like this: $ GSETTINGS_SCHEMA_DIR=_build:$GSETTINGS_SCHEMA_DIR _build/tfe ~~~ -### GSettings object and g_setting_bind +### GSettings object and g\_settings\_bind Write gsettings related codes to `tfeapplication.c'. diff --git a/gfm/sec23.md b/gfm/sec23.md new file mode 100644 index 0000000..8bcaa4d --- /dev/null +++ b/gfm/sec23.md @@ -0,0 +1,380 @@ +Up: [Readme.md](../Readme.md), Prev: [Section 22](sec22.md) + +# Tiny turtle graphics interpreter + +A program `turtle` is an example with the combination of TfeTextView and GtkDrawingArea objects. +It is a very small interpreter but it provides a way to draw fractal curves. +The following diagram is a Koch curve, which is a famous example of fractal curves. + +![Kocho curve](../src/turtle/image/turtle_koch.png) + +This program uses flex and bison. +Flex is a lexical analyzer. +Bison is a parser generator. +These two programs are similar to lex and yacc which are proprietary software developed in Bell Laboratry. +However, flex and bison are open source software. +I will write about how to use those software, but they are not topics about gtk. +So, readers can skip that part of this sections. + +## How to use turtle + +The documentation of turtle is [here](../src/turtle/turtle_doc.md). +I'll show you a simple example. + +~~~ +fc (1,0,0) # Foreground color is red, rgb = (1,0,0). +pd # Pen down. +fd 100 # Go forward by 100 pixels. +tr 90 # Turn right by 90 degrees. +fd 100 +tr 90 +fd 100 +tr 90 +fd 100 +tr 90 +~~~ + +1. Compile and install `turtle` (See the documentation above). +Then, run `turtle`. +2. Type the program above in the editor (left part of the window). +3. Click on the `Run` button, then a red square appears on the right part of the window. +The side of the square is 100 pixels long. + +In the same way, you can draw other curves. +The documentation above shows some fractal curves such as tree, snow and square-koch. +The source code in turtle language is located at [src/turtle/example](../src/turtle/example) directory. +You can read these files by clicking on the `Open` button. + +## Combination of TfeTextView and GtkDrawingArea objects + +Turtle uses TfeTextView and GtkDrawingArea. +It is similar to `color` program in the previous section. + +The body of the interpreter is written with flex and bison. +The codes are not thread safe. +So the handler of "clicked" signal of the `Run` button prevents from reentering. + +~~~C + 1 void + 2 run_cb (GtkWidget *btnr) { + 3 GtkTextBuffer *tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); + 4 GtkTextIter start_iter; + 5 GtkTextIter end_iter; + 6 char *contents; + 7 int stat; + 8 static gboolean busy = FALSE; + 9 +10 /* yyparse() and run() are NOT thread safe. */ +11 /* The variable busy avoids reentry. */ +12 if (busy) +13 return; +14 busy = TRUE; +15 gtk_text_buffer_get_bounds (tb, &start_iter, &end_iter); +16 contents = gtk_text_buffer_get_text (tb, &start_iter, &end_iter, FALSE); +17 if (surface) { +18 init_flex (contents); +19 init_parse (); +20 stat = yyparse (); +21 #ifdef debug +22 g_print ("yyparse returned %d.\n", stat); +23 #endif +24 if (stat == 0) /* No error */ { +25 run (); +26 } +27 finalize_flex (); +28 } +29 gtk_widget_queue_draw (GTK_WIDGET (da)); +30 busy = FALSE; +31 } +32 +33 static void +34 resize_cb (GtkDrawingArea *drawing_area, int width, int height, gpointer user_data) { +35 if (surface) +36 cairo_surface_destroy (surface); +37 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); +38 } +~~~ + +- 8-13: The static value `busy` holds a status of the interpreter. +If it is `TRUE`, the interpreter is running and it is not possible to call the interpreter again because it's not a re-entrant program. +If it is `FALSE`, it is safe to call the interpreter. +- 14: Now it is about to call the interpreter so let `busy` variable to be TRUE. +- 15-16: Gets the contents of GtkTextBuffer. +- 17: The varable `surface` is a static variable. +It points to a `cairo_surface_t` object. +It is generated when the GtkDrawingArea object is realized and the each time it is resized. +Therefore, `surface` isn't NULL usually. +But if it is NULL, the interpreter won't be called. +- 18-19: Initializes lexcal analyzer, then parser. +- 20: Calls parser. +Parser analyze the program codes syntactically and generate a tree structured data. +- 24-26: If the parser succesfully parsed, it calls `run` which is the interpreter. +`Run` executes the tree-structured program. +- 27: finalize the lexical analyzer. +- 29: Add the drawing area object to the queue to draw. +- 30: The interpreter program has finished so `busy` is now FALSE. +- 33-38: A handler of "resized" signal. +It generates or regenerates a surface object. + +Other part of `turtleapplication.c` is almost same as the codes of `colorapplication.c` in the previous section. +The codes of `turtleapplication.c` is in the [turtle directory](../src/turtle). + +## What does the interpreter do? + +Suppose that the turtle runs with the following program. +The following is the description how turtle recognizes the program and does the work. + +~~~ +distance = 100 +fd distance*2 +~~~ + +- Generally, a program consists of tokens. +Tokens are "distance", "=", "100", "fd", "*" and "2" in the above example.. +- The interpreter `turtle` calls `yylex` to read a token in the source file. +The `yylex` returns a code which is called "token kind" and sets a global variable `yylval` with a value, which is called a semantic value. +The type of `yylval` is union and `yylval.ID` is string and `yylval.NUM` is double. +There are seven tokens in the program so `yylex` is called seven times. + +| |token kind|yylval.ID|yylval.NUM| +|:-:|:--------:|:-------:|:--------:| +| 1 | ID |distance | | +| 2 | = | | | +| 3 | NUM | | 100 | +| 4 | FD | | | +| 5 | ID |distance | | +| 6 | * | | | +| 7 | NUM | | 2 | + +`yylex` returns a token kind every time, but it doesn't set `yylval.ID` or `yylval.NUM` every time. +It is because keywords (`FD`) and symbols (`=` and `*`) don't have any semantic values. +The function `yylex` is called lexical analyzer or scanner. +- `turtle` makes a tree structured data. +This part of `turtle` is called parser. + +![turtle parser tree](../src/turtle_parser_tree_png) + +- `turtle` analyzes the tree and executes it. +This part of `turtle` is called runtime routine. +The tree consists of line segments and rectangles between line segments. +The rectangles are called nodes. +For example, N\_PROGRAM, N\_ASSIGN, N\_FD and N\_MUL are nodes. + 1. Goes down from N\_PROGRAM to N\_ASSIGN. + 2. At N_ASSIGN node, `turtle` checks if the first child is ID, that means the left side is a variable. +If it's ID, then `turtle` looks for the variable in the variable table. +If it doesn't exist, it registers the ID (`distance`) to the table. +Then go back to the N\_ASSIGN node. + 3. `turtle` calculates the second child. +In this case its a number 100. +Saves 100 to the variable table at the `distance` record. + 4. `turtle` goes back to N\_PROGRAM then go to the next node N\_FD. +It has only one child. +Goes down to the child N\_MUL. + 5. The first child is ID (distance). +Looks for the varable distance in the variable table and gets the value 100. +The second child is a number 2. +Multiplies 100 by 2 and gets 200. +Then `turtle` goes back to N_FD. + 6. Now `turtle` knows the distance is 200. +It moves the cursor forward by 200. + 8. There are no node follows. +Runtime routine returns to the main routine. +-`turtle` draws GtkDrawingArea then stops. + +Actually most programs are more complicated than the example above. +So, `turtle` does much more work to interpret programs. +However, basically it works by the same way above. +Interpritation consists of three parts. + +- Lexical analysis +- Syntax Parsing and tree generation +- Execution by the tree + +## Compilation flow + +The source files are: + +- flex source file ~> turtle.lex +- bison source file => turtle.y +- C header file => turtle.h, turtle_lex.h +- C source file => turtleapplication.c +- other files => turtle.ui, turtle.gresources.xml, meson.build + +The compilation process is a bit complicated. + +1. glib-compile-resources compiles `turtle.ui` to `resources.c` according to `turtle.gresource.xml`. +It also generates `resources.h`. +2. bison compiles `turtle.y` to `turtle\_parser.c` and generates `turtle\_parser.h` +3. flex compiles `turtle.lex` to `turtle\_lex.c`. +4. gcc compiles `application.c`, `resources.c`, `turtle\_parser.c` and `turtle\_lex.c` with `turtle.h`, `resources.h` and `turtle\_parser.h`. +It generates an executable file `turtle`. + +![compile process](../image/turtle_compile_process.png) + +Meson controls the process and the instruction is described in meson.build. + +~~~meson + 1 project('turtle', 'c') + 2 + 3 compiler = meson.get_compiler('c') + 4 mathdep = compiler.find_library('m', required : true) + 5 + 6 gtkdep = dependency('gtk4') + 7 + 8 gnome=import('gnome') + 9 resources = gnome.compile_resources('resources','turtle.gresource.xml') +10 +11 flex = find_program('flex') +12 bison = find_program('bison') +13 turtleparser = custom_target('turtleparser', input: 'turtle.y', output: ['turtle_parser.c', 'turtle_parser.h'], command: [bison, '-d', '-o', 'turtle_parser.c', '@INPUT@']) +14 turtlelexer = custom_target('turtlelexer', input: 'turtle.lex', output: 'turtle_lex.c', command: [flex, '-o', '@OUTPUT@', '@INPUT@']) +15 +16 sourcefiles=files('turtleapplication.c', '../tfetextview/tfetextview.c') +17 +18 executable('turtle', sourcefiles, resources, turtleparser, turtlelexer, turtleparser[1], dependencies: [mathdep, gtkdep], export_dynamic: true, install: true) +19 +~~~ + +- 3: Gets C compiler. +It is usually `gcc` in linux. +- 4: Gets math library. +This program uses trigonometry functions. +They are defined in the math library, but the library is optional. +So, it is necessary to include the library by `#include ` and also link the library with the linker. +- 6: Gets gtk4 library. +- 8: Gets gnome module. +Module is a system provided by meson. +See [Meson build system website](https://mesonbuild.com/Gnome-module.html#gnome-module) for further information. +- 9: Compiles ui file to C source file according to the XML file `turtle.gresource.xml`. +- 11: Gets flex. +- 12: Gets bison. +- 13: Compiles `turtle.y` to `turtle_parser.c` and `turtle_parser.h` by bison. +The function `custom_target`creates a custom top level target. +See [Meson build system website](https://mesonbuild.com/Reference-manual.html#custom_target) for further information. +- 14: Compiles `turtle.lex` to `turtle_lex.c` by flex. +- 16: Specifies C surce files. +- 18: Compiles C source files including generated files by glib^compile-resources, bison and flex. +The argument `turtleparser[1]` refers to `tirtle_parser.h` which is the secound output in the line 13. + +## Turtle.lex + +This subsection and the following subsection are description about flex and bison. +If you want to focus on gtk4, you can skip these subsections. + +### What does flex do? + +Flex creates lexical analizer from flex source file. +Flex source file is a text file and its syntactic rule will be explained later. +Generated lexical analyzer is a C source file. +It is also called scanner. +It reads a text file, which is a source file of a program language, and gets variable names, numbers and symbols. +Suppose here is a text file. + +~~~ +fc (1,0,0) # Foreground color is red, rgb = (1,0,0). +pd # Pen down. +distance = 100 +angle = 90 +fd distance # Go forward by distance (100) pixels. +tr angle # Turn right by angle (90) degrees. +~~~ + +The content of the textfile is separated into `fc`, `(`, `1`, `,` and so on. +The words `fc`, `pd`, `distance` and `100` are called token. +The characters `(`, `<` and `=` are called symbol. +( Sometimes those symbols called token, too.) + +A scanner has `yylex` function and `yytext` variable. +The function returns a type of token and set `yytext` to contain the name of the token. +Each time `yylexc` is called, it returns the followings. + + +Turtle.lex isn't so big program. + +~~~lex + 1 %top{ + 2 #include + 3 #include "turtle.h" + 4 + 5 static int nline = 1; + 6 static int ncolumn = 1; + 7 static void get_location (char *text); + 8 + 9 /* Dinamically allocated memories are added to the single list. They will be freed in the finalize function. */ +10 extern GSList *list; +11 } +12 +13 %option noyywrap +14 +15 DIGIT [0-9] +16 REAL_NUMBER (0|[1-9][0-9]*)(\.[0-9]+)? +17 IDENTIFIER [a-zA-Z][a-zA-Z0-9]* +18 %% +19 /* rules */ +20 #.*\n nline++; ncolumn = 1; /* comment */ +21 #.* ; /* comment in the last line */ +22 [ ] ncolumn++; +23 \t ncolumn += 8; /* assume that tab is 8 spaces. */ +24 \n nline++; ncolumn = 1; +25 /* reserved keywords */ +26 pu get_location (yytext); return PU; /* pen up */ +27 pd get_location (yytext); return PD; /* pen down */ +28 pw get_location (yytext); return PW; /* pen width = line width */ +29 fd get_location (yytext); return FD; /* forward */ +30 tr get_location (yytext); return TR; /* turn right */ +31 bc get_location (yytext); return BC; /* background color */ +32 fc get_location (yytext); return FC; /* foreground color */ +33 dp get_location (yytext); return DP; /* define procedure */ +34 if get_location (yytext); return IF; /* if statement */ +35 rt get_location (yytext); return RT; /* return statement */ +36 rs get_location (yytext); return RS; /* reset the status */ +37 /* constant */ +38 {REAL_NUMBER} get_location (yytext); yylval.NUM = atof (yytext); return NUM; +39 /* identifier */ +40 {IDENTIFIER} { get_location (yytext); yylval.ID = g_strdup(yytext); +41 list = g_slist_prepend (list, yylval.ID); +42 return ID; +43 } +44 "=" get_location (yytext); return '='; +45 ">" get_location (yytext); return '>'; +46 "<" get_location (yytext); return '<'; +47 "+" get_location (yytext); return '+'; +48 "-" get_location (yytext); return '-'; +49 "*" get_location (yytext); return '*'; +50 "/" get_location (yytext); return '/'; +51 "(" get_location (yytext); return '('; +52 ")" get_location (yytext); return ')'; +53 "{" get_location (yytext); return '{'; +54 "}" get_location (yytext); return '}'; +55 "," get_location (yytext); return ','; +56 . ncolumn++; return YYUNDEF; +57 %% +58 +59 static void +60 get_location (char *text) { +61 yylloc.first_line = yylloc.last_line = nline; +62 yylloc.first_column = ncolumn; +63 yylloc.last_column = (ncolumn += strlen(text)) - 1; +64 } +65 +66 static YY_BUFFER_STATE state; +67 +68 void +69 init_flex (const char *text) { +70 state = yy_scan_string (text); +71 } +72 +73 void +74 finalize_flex (void) { +75 yy_delete_buffer (state); +76 } +77 +~~~ + + + + +## Turtle.y source file compiled by bison + + +Up: [Readme.md](../Readme.md), Prev: [Section 22](sec22.md) diff --git a/image/color_square.png b/image/color_square.png new file mode 100644 index 0000000000000000000000000000000000000000..0a87c82975b6242b91a760105e82bdbbfded992a GIT binary patch literal 45632 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 literal 0 HcmV?d00001 diff --git a/image/turtle_compile_process.xcf b/image/turtle_compile_process.xcf new file mode 100644 index 0000000000000000000000000000000000000000..fd6f538dac0f77fb96c4d2973cd2417696589c12 GIT binary patch literal 98133 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 literal 0 HcmV?d00001 diff --git a/image/turtle_parser_tree.png b/image/turtle_parser_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..503e11931a5e6a6b1779651d8e79553fe0f8fc45 GIT binary patch literal 23978 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 ywLEu~GcP|sLQ~)e)m5)v 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 E2Xv|E3;+NC literal 0 HcmV?d00001 diff --git a/lib/lib_add_head_tail_html.rb b/lib/lib_add_head_tail_html.rb index b4c0eb3..d2a27ac 100644 --- a/lib/lib_add_head_tail_html.rb +++ b/lib/lib_add_head_tail_html.rb @@ -3,27 +3,57 @@ def add_head_tail_html html_file -head=<<'EOS' - - - - - - +sample_md = <<'EOS' +--- +title: 'Gtk4 tutorial for beginners' +--- - +# sample header - gtk4 tutorial - - +Main contents begin here. + +~~~{.C .numberLines} +int main(int argc, char **argv) { +} +~~~ + +|English|Japanese| +|:-----:|:------:| +|potato|jagaimo| +|carrot|ninjin| +|onion|tamanegi| EOS + File.write "sample.md", sample_md + if (! system("pandoc", "-s", "-o", "sample.html", "sample.md")) + raise ("add_head_tail_html: pandoc retuns error status #{$?}.\n") + end + sample_html = File.read("sample.html") + sample_html.gsub!(//,'') + + head = [] + sample_html.each_line do |l| + if l =~ /<\/head>/ + break + elsif l != "\n" + head << l + end + end + i = head.find_index { |line| line =~ /<\/style>/} + raise "No tag in sample.html which is generated by pandoc." unless i.instance_of?(Integer) + head.insert(i, " body {width: 1080px; margin: 0 auto; font-size: large;}\n") + head.insert(i, " h2 {padding: 10px; background-color: #d0f0d0; }\n") + head.insert(i, " div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}\n") + head.insert(i, " pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}\n") + head.insert(i, " table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}\n") + head.insert(i, " th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}\n") + head.insert(i, " td {padding: 2px 6px; border: 1px solid;}\n") + head.insert(i, " img {display: block; margin-left: auto; margin-right: auto;}\n") + head.insert(i, " figcaption {text-align: center;}\n") + head << "\n" + head << "\n" + head = head.join + tail=<<'EOS' @@ -31,4 +61,5 @@ EOS body = File.read(html_file) File.write(html_file, head+body+tail) -end +end + diff --git a/lib/lib_gen_main_tex.rb b/lib/lib_gen_main_tex.rb index f9e1272..aceb99a 100644 --- a/lib/lib_gen_main_tex.rb +++ b/lib/lib_gen_main_tex.rb @@ -7,7 +7,7 @@ def gen_main_tex directory, texfilenames, appendixfilenames # ------ Generate helper.tex ------ # Get preamble from a latex file generated by pandoc. - # 1. Generate sample latex file by `pandoc -s -o sample.tex sample.md` + # 1. Generate sample latex file by `pandoc -s --listings -o sample.tex sample.md` # 2. Extract the preamble of sample.tex. # 3. Add geometry package. @@ -20,10 +20,17 @@ line1 int main(int argc, char **argv) { } ~~~ + +|English|Japanese| +|:-----:|:------:| +|potato|jagaimo| +|carrot|ninjin| +|onion|tamanegi| + EOS File.write "sample.md", sample_md - if (! system("pandoc", "-s", "-o", "sample.tex", "sample.md")) + if (! system("pandoc", "-s", "--listings", "-o", "sample.tex", "sample.md")) raise ("pandoc retuns error status #{$?}.\n") end sample_tex = File.read("sample.tex") @@ -43,6 +50,20 @@ EOS end preamble << "\\usepackage[margin=2.4cm]{geometry}\n" preamble << "\\usepackage{graphicx}\n" + preamble << "\\lstdefinelanguage[]{turtle}{\n" + preamble << " keywords={pu, pd, pw, fd, tr, bc, fc, if, rt, rs, dp},\n" + preamble << " comment=[l]\\#\n" + preamble << "}\n" + preamble << "[keywords, comments]\n" + preamble << "\\lstset {\n" + preamble << " extendedchars=true,\n" + preamble << " basicstyle=\\small\\ttfamily,\n" + preamble << " keywordstyle=\\color{red},\n" + preamble << " commentstyle=\\color{gray},\n" + preamble << " stringstyle=\\color{blue},\n" + preamble << " breaklines=true,\n" + preamble << " breakatwhitespace=true\n" + preamble << "}\n" File.write("#{directory}/helper.tex",preamble.join) File.delete("sample.md") File.delete("sample.tex") diff --git a/lib/lib_mktbl.rb b/lib/lib_mktbl.rb new file mode 100644 index 0000000..d1a95f4 --- /dev/null +++ b/lib/lib_mktbl.rb @@ -0,0 +1,262 @@ +# mktbl.rb -- make table easy to read + +def usage + print "ruby mktbl.rb file\n" + exit +end + +def get_sep line + unless line.instance_of?(String) && line =~ /^\|(:?-+:?\|)+$/ + raise "Ilegal parameter" + end + line = line.chomp.sub(/^\|/,"") + a = [] + while line.length >= 1 + if line =~ /^(:?-+:?)\|(.*)$/ + pat = $1 + line = $2 + if pat[0] == ":" && pat[-1] == ":" + a << :c + elsif pat[0] == ":" + a << :l + elsif pat[-1] == ":" + a << :r + else #default + a << :l + end + else + raise "Unexpected error. line is \"#{line}\"" + end + end + a +end + +def line2cells line + unless line.instance_of?(String) + raise "Argument must be String" + end + unless line.length < 1000 + raise "String too long" + end + a = [] + line = line.chomp.sub(/^\s*\|/,"").sub(/\s*$/, "") + i = 0 + while i < line.length + cell = "" + while i < line.length && (c = line[i]) != "|" + if c != "\\" && c != "|" + cell << c + i += 1 + elsif i+1 < line.length && line[i+1] == "|" + cell << "\\|" + i += 2 + else + cell << "\\" + i += 1 + end + end + unless i < line.length + raise "String format error in #{line}." + end + cell = cell.sub(/^\s*/,"").sub(/\s*$/, "") + a << cell + i += 1 + end + return a +end + +def get_tbl buf + t = [] + buf.each do |line| + t << line2cells(line) + end + n = t[0].size + t.each do |a| + raise "Each row must have the same number of columns." unless a.size == n + end + t +end + +def get_width tbl, sep + n = sep.size + tbl.each do |a| + raise "Each row must have the same number of columns." unless a.size == n + end + width = [] + 0.upto(n-1) do |i| + max = 0 + tbl.each do |a| + max = max < a[i].length ? a[i].length : max + end + if sep[i] == :l || sep[i] == :r + max = max < 2 ? 2 : max + elsif sep[i] == :c + max = max < 3 ? 3 : max + else + raise "Separater format error." + end + width << max + end + width +end + +def mk_sep_l sep, width + raise "Size of sep and width is different." unless sep.size == width.size + n = sep.size + line = "|" + 0.upto(n-1) do |i| + if sep[i] == :l + line << ":"+"-"*(width[i]-1)+ "|" + elsif sep[i] == :r + line << "-"*(width[i]-1) + ":|" + elsif sep[i] == :c + line << ":" + "-"*(width[i]-2) + ":|" + else + raise "Separater format error." + end + end + line +end + +def mk_tbl_l tbl, sep, width + n = width.size + raise "mk_tbl_l: Each row must have the same number of columns." unless sep.size == n + tbl.each do |a| + raise "mk_tbl_l: Each row must have the same number of columns." unless a.size == n + 0.upto(n-1) do |i| + raise "mk_tbl_l: table data [#{i}] has wider width than expected (#{width[i]})." if a[i].size > width[i] + end + end + tbl_l = [] + tbl.each do |row| + line = "|" + 0.upto(n-1) do |i| + space = width[i]-row[i].length + if sep[i] == :l + line << row[i] + " "*space + "|" + elsif sep[i] == :r + line << " "*space + row[i] + "|" + elsif sep[i] == :c + left = space / 2 + right = space - left + line << " "*left + row[i] + " "*right + "|" + else + raise "mk_tbl_l: Separater format error." + end + end + tbl_l << line + end + tbl_l +end + +def mktbl buf + raise "The data not a table." unless buf.size >= 3 # table must have header, separator, body + sep = get_sep buf[1] # Sep is an array contains ALIGNMENT (LEFT, CENTER or RIGHT) information of each column. + buf.delete_at 1 + tbl = get_tbl buf # Tbl is a two dimensional array of the table. Each element is a cell of the table. + width = get_width tbl, sep # Width is an array. Each element is the maximum width of the cells in the column corresponds to the element. + sep_l = mk_sep_l sep, width # Make a text of the separator. Each column in the text has a width given by the second argument. + tbl_l = mk_tbl_l tbl, sep, width # Make an array of texts. Each column in the text has a width given by the second argument. + tbl_l.insert(1, sep_l) + tbl_l +end + +# ---- test ---- +def test_sep + s = "|:-:|:---|---:|-|\n" + sep = get_sep s + raise "test_sep: Error." unless sep == [:c, :l, :r, :l] +end + +def test_tbl + t = "| a | bc|def | gh i | \\|kl|\n" + tbl = line2cells t + raise "test_tbl: Error." unless tbl == ["a", "bc", "def", "gh i", "\\|kl"] +end + +def test_get_tbl + buf = [ "||book|author|price|\n", + "| 1 | Calculus | T. Takagi | \\3,600 |\n", + "|2|Algebra|S. Lang|$50|\n" + ] + tbl = get_tbl buf + tbl_expected = [["", "book", "author", "price"], + ["1", "Calculus", "T. Takagi", "\\3,600"], + ["2", "Algebra", "S. Lang", "$50"] + ] + raise "test_get_tbl: Error" unless tbl == tbl_expected +end + +def test_get_width + tbl = [["", "book", "author", "price"], + ["1", "Calculus", "T. Takagi", "\\3,600"], + ["2", "Algebra", "S. Lang", "$50"] + ] + sep = [:c, :c, :c, :c] + width = get_width tbl, sep + width_expected = [3, 8, 9, 6] + raise "test_get_width: Error" unless width == width_expected +end + +def test_mk_sep_l + sep = [:l, :c, :r, :c] + width = [3, 8, 9, 6] + sep_l = mk_sep_l sep, width + sep_l_expected = "|:--|:------:|--------:|:----:|" + raise "test_mk_sep_l: Error" unless sep_l == sep_l_expected +end + +def test_mk_tbl_l + sep = [:l, :c, :r, :c] + width = [3, 8, 9, 6] + tbl = [["", "book", "author", "price"], + ["1", "Calculus", "T. Takagi", "\\3,600"], + ["2", "Algebra", "S. Lang", "$50"] + ] + tbl_l = mk_tbl_l tbl, sep, width + tbl_l_expected = ["| | book | author|price |", + "|1 |Calculus|T. Takagi|\\3,600|", + "|2 |Algebra | S. Lang| $50 |" + ] + raise "test_mk_tbl_l: Error" unless tbl_l == tbl_l_expected +end + +def test_mktbl + buf = <<'EOS'.split("\n") +| |token kind | yylval.ID | yylval.NUM | +|:-:|:-|-:|:-:| +|1|ID|distance| | +|2|=||| +|3|NUM||100| +|4|FD||| +|5|ID|distance|| +|6|*||| +|7|NUM||2| +EOS + + tbl_l = mktbl buf + + tbl_l_expected = <<'EOS'.split("\n") +| |token kind|yylval.ID|yylval.NUM| +|:-:|:---------|--------:|:--------:| +| 1 |ID | distance| | +| 2 |= | | | +| 3 |NUM | | 100 | +| 4 |FD | | | +| 5 |ID | distance| | +| 6 |* | | | +| 7 |NUM | | 2 | +EOS + raise "test_mktbl: Error" unless tbl_l == tbl_l_expected +end + +def test + test_sep + test_tbl + test_get_tbl + test_get_width + test_mk_sep_l + test_mk_tbl_l + test_mktbl +end + diff --git a/lib/lib_src2md.rb b/lib/lib_src2md.rb index d91f93e..bd78ad7 100644 --- a/lib/lib_src2md.rb +++ b/lib/lib_src2md.rb @@ -1,8 +1,8 @@ # lib_src2md.rb require 'pathname' -# The method 'src2md' convert .src.md file into .md file. -# The output .md file is fit for the final format, which is one of markdown, html and latex. +# The method 'src2md' converts .src.md file into .md file. +# The outputed .md file is fit for the final format, which is one of markdown, html and latex. # - Links to relative URL are removed for latex. Otherwise, it remains. # See "Hyperref and relative link" below for further explanation. # - Width and height for images are removed for markdown and html. it remains for latex. @@ -40,114 +40,52 @@ require 'pathname' # If the target is full URL, which means absolute URL begins with "http", no problem happens. -# This script just remove the links if its target is relative URL. +# This script just remove the links if its target is relative URL if the target is latex. # If you want to revive the link with relative URL, refer the description above. -# ---- Folding verbatim lines ---- -# When C sourcefiles or subshell output are included, the lines are folded to fit in 'width'. -# Width must be positive integer. -# Otherwise the lines are not folded. - # This script uses "fenced code blocks" for verbatim lines. # It is available in GFM and pandoc's markdown but not in original markdown. # Two characters backtick (`) and tilde (~) are possible for fences. # This script uses tilde because info string cannot contain any backticks for the backtick code fence. # Info string follows opening fence and it is usually a language name. + +# GFM has fence code block as follows. # ~~~C # int main (int argc, char **argv) { # ........ # ~~~ # Then the contents are highlighted based on C language syntax. -# This script find the language by the suffix of the file name. +# This script finds the language by the suffix of the file name. # .c => C, .h => C, .rb => ruby, Rakefile, => ruby, .xml => xml, .ui => xml, .y => bison, .lex => lex, .build => meson, .md => markdown # Makefile => makefile -def src2md srcmd, md, width +# Pandoc's markdown is a bit different. +# ~~~{.C .numberLines} +# int main (int argc, char **argv) { +# ........ +# ~~~ +# Then the contents are highlighted based on C language syntax and line numbers are added. +# Pandoc supports C, ruby, xml, bison, lex, markdown and makefile languages, but doesn't meson. +# +# After a markdown file is converted to a latex file, listings package is used by lualatex to convert it to a pdf file. +# Listings package supports only C, ruby, xml and make. +# Bison, lex, markdown and meson aren't supported. + +def src2md srcmd, md # parameters: # srcmd: .src.md file's path. source # md: .md file's path. destination -# width: maximum width of lines in fence code block src_buf = IO.readlines srcmd src_dir = File.dirname srcmd md_dir = File.dirname md type = File.basename md_dir # type of the target. gfm, html or latex +# phase 1 +# @@@if - @@@elif - @@@else - @@@end md_buf = [] - include_flag = "" - shell_flag = false if_stat = 0 src_buf.each do |line| - if include_flag == "-N" || include_flag == "-n" - if line == "@@@\n" - include_flag = false - elsif line =~ /^ *(\S*) *(.*)$/ - c_file = $1 - c_functions = $2.strip.split(" ") - if c_file =~ /^\// # absolute path - c_file_buf = File.readlines(c_file) - else #relative path - c_file_buf = File.readlines(src_dir+"/"+c_file) - end - if c_functions.empty? # no functions are specified - tmp_buf = c_file_buf - else - tmp_buf = [] - spc = false - c_functions.each do |c_function| - from = c_file_buf.find_index { |line| line =~ /^#{c_function} *\(/ } - if ! from - warn "ERROR in #{srcmd}: Didn't find #{c_function} in #{c_file}." - break - end - to = from - while to < c_file_buf.size do - if c_file_buf[to] == "}\n" - break - end - to += 1 - end - n = from-1 - if spc - tmp_buf << "\n" - else - spc = true - end - while n <= to do - tmp_buf << c_file_buf[n] - n += 1 - end - end - end - md_buf << "~~~#{lang(c_file)}\n" - ln_width = tmp_buf.size.to_s.length - n = 1 - tmp_buf.each do |l| - if include_flag == "-n" - l = sprintf("%#{ln_width}d %s", n, l) - end - fold(l, width).each_line do |l2| - md_buf << l2 - end - n += 1 - end - md_buf << "~~~\n" - end - elsif shell_flag - if line == "@@@\n" - shell_flag = false - else - md_buf << "~~~\n" - fold("$ #{line}", width).each_line do |l2| - md_buf << l2 - end - `cd #{src_dir}; #{line.chomp}`.each_line do |l| - fold(l, width).each_line do |l2| - md_buf << l2 - end - end - md_buf << "~~~\n" - end - elsif line =~ /^@@@if *(\w+)/ && if_stat == 0 + if line =~ /^@@@if *(\w+)/ && if_stat == 0 if_stat = type == $1 ? 1 : -1 elsif line =~ /^@@@elif *(\w+)/ if if_stat == 1 @@ -176,21 +114,133 @@ def src2md srcmd, md, width elsif line =~ /^@@@end/ if_stat = 0 elsif if_stat >= 0 - if line == "@@@include\n" || line =~ /^@@@include *-n/ - include_flag = "-n" - elsif line =~ /^@@@include *-N/ - include_flag = "-N" - elsif line == "@@@shell\n" - shell_flag = true - else - line = change_rel_link(line, src_dir, md_dir) - if type == "latex" # remove relative link - line.gsub!(/(^|[^!])\[([^\]]*)\]\((?~http)\)/,"\\1\\2") - else # type == "gfm" or "html", then remove size option from link to image files. - line.gsub!(/(!\[[^\]]*\]\([^\)]*\)) *{width *= *\d*(|\.\d*)cm *height *= *\d*(|\.\d*)cm}/,"\\1") + md_buf << line + end + end + +# phase 2 +# @@@include and @@@shell + src_buf = md_buf + md_buf = [] + include_flag = "" + shell_flag = false + src_buf.each do |line| + if include_flag == "-N" || include_flag == "-n" + if line == "@@@\n" + include_flag = "" + elsif line =~ /^\s*(\S*)\s*(.*)$/ + c_file = $1 + c_functions = $2.strip.split(" ") + if c_file =~ /^\// # absolute path + c_file_buf = File.readlines(c_file) + else #relative path + c_file_buf = File.readlines(src_dir+"/"+c_file) end - md_buf << line + if c_functions.empty? # no functions are specified + tmp_buf = c_file_buf + else + tmp_buf = [] + spc = false + c_functions.each do |c_function| + from = c_file_buf.find_index { |line| line =~ /^#{c_function} *\(/ } + if ! from + warn "lib_src2md: ERROR in #{srcmd}: Didn't find #{c_function} in #{c_file}." + break + end + to = from + while to < c_file_buf.size do + if c_file_buf[to] == "}\n" + break + end + to += 1 + end + if to >= c_file_buf.size + warn "lib_src2md: ERROR in #{srcmd}: function #{c_function} didn't end in #{c_file}." + break + end + n = from-1 + if spc + tmp_buf << "\n" + else + spc = true + end + while n <= to do + tmp_buf << c_file_buf[n] + n += 1 + end + end + end + if type == "gfm" + md_buf << "~~~#{lang(c_file, "gfm")}\n" + elsif type == "html" + language = lang(c_file, "pandoc") + if include_flag == "-n" + if language != "" + md_buf << "~~~{.#{language} .numberLines}\n" + else + md_buf << "~~~{.numberLines}\n" + end + else + if lang(c_file, "pandoc") != "" + md_buf << "~~~{.#{language}}\n" + else + md_buf << "~~~\n" + end + end + elsif type =="latex" + language = lang(c_file, "pandoc") + if include_flag == "-n" + if language == "C" || language == "ruby" || language == "xml" || language == "makefile" + md_buf << "~~~{.#{language} .numberLines}\n" + else + md_buf << "~~~{.numberLines}\n" + end + else + if language == "C" || language == "ruby" || language == "xml" || language == "makefile" + md_buf << "~~~{.#{language}}\n" + else + md_buf << "~~~\n" + end + end + else # This can't happen. + md_buf << "~~~" + end + ln_width = tmp_buf.size.to_s.length + n = 1 + tmp_buf.each do |l| + if type == "gfm" && include_flag == "-n" + l = sprintf("%#{ln_width}d %s", n, l) + end + md_buf << l + n += 1 + end + md_buf << "~~~\n" end + elsif shell_flag + if line == "@@@\n" + md_buf << "~~~\n" + shell_flag = false + else + md_buf << "$ #{line}" + `cd #{src_dir}; #{line.chomp}`.each_line do |l| + md_buf << l + end + end + elsif line == "@@@include\n" || line =~ /^@@@include *-n/ + include_flag = "-n" + elsif line =~ /^@@@include *-N/ + include_flag = "-N" + elsif line == "@@@shell\n" + md_buf << "~~~\n" + shell_flag = true + else + line = change_rel_link(line, src_dir, md_dir) + if type == "latex" # remove relative link + line.gsub!(/(^|[^!])\[([^\]]*)\]\((?~http)\)/,"\\1\\2") + else # type == "gfm" or "html", then remove size option from link to image files. + line.gsub!(/(!\[[^\]]*\]\([^\)]*\)) *{width *= *\d*(|\.\d*)cm *height *= *\d*(|\.\d*)cm}/,"\\1") + end + md_buf << line end end IO.write(md,md_buf.join) @@ -217,17 +267,7 @@ def change_rel_link line, org_dir, new_dir left + right end -def fold line, width - if line.instance_of?(String) && width.instance_of?(Integer) && width > 0 - n = (line.chomp.length - 1) / width - n.downto(1) do |i| - line.insert width*i, "\n" - end - end - line -end - -def lang file +def lang file, type_of_md tbl = {".c" => "C", ".h" => "C", ".rb" => "ruby", ".xml" => "xml", ".ui" => "xml", ".y" => "bison", ".lex" => "lex", ".build" => "meson", ".md" => "markdown" } name = File.basename file @@ -239,7 +279,8 @@ def lang file suffix = File.extname name tbl.each do |key, val| if suffix == key - return val + return val if type_of_md == "gfm" + return val if type_of_md == "pandoc" && val != "meson" end end end diff --git a/sample.html b/sample.html new file mode 100644 index 0000000..09e1c81 --- /dev/null +++ b/sample.html @@ -0,0 +1,110 @@ + + + + + + + Gtk4 tutorial for beginners + + + +
+

Gtk4 tutorial for beginners

+
+

sample header

+

Main contents begin here.

+
int main(int argc, char **argv) {
+}
+ + + + + + + + + + + + + + + + + + + + + +
EnglishJapanese
potatojagaimo
carrotninjin
oniontamanegi
+ + diff --git a/sample.md b/sample.md new file mode 100644 index 0000000..13d35e4 --- /dev/null +++ b/sample.md @@ -0,0 +1,18 @@ +--- +title: 'Gtk4 tutorial for beginners' +--- + +# sample header + +Main contents begin here. + +~~~{.C .numberLines} +int main(int argc, char **argv) { +} +~~~ + +|English|Japanese| +|:-----:|:------:| +|potato|jagaimo| +|carrot|ninjin| +|onion|tamanegi| diff --git a/src/mktbl.rb b/src/mktbl.rb new file mode 100644 index 0000000..4003272 --- /dev/null +++ b/src/mktbl.rb @@ -0,0 +1,32 @@ +require_relative '../lib/lib_mktbl.rb' + +file = ARGV[0] +old = File.readlines file +in_stat = false +new = [] +changed = false +tmp = [] +old.each do |line| + if in_stat + if line == "@@@\n" + in_stat = false + new += mktbl tmp + else + tmp << line + end + elsif line == "@@@table\n" + changed = true + in_stat = true + tmp = [] + else + new << line + end +end +new.each do |line| + if line[-1] != "\n" + line.sub!(/\z/,"\n") + end +end +exit unless changed +File.write file+".bak", old.join +File.write file, new.join diff --git a/src/sec12.src.md b/src/sec12.src.md index c94a463..d2faa98 100644 --- a/src/sec12.src.md +++ b/src/sec12.src.md @@ -2,7 +2,7 @@ In this section I will explain functions in TfeTextView object. -### tfe.h and tfetextview.h +## tfe.h and tfetextview.h `tfe.h` is a top header file and it includes `gtk.h` and all the header files. C source files `tfeapplication.c` and `tfenotebook.c` include `tfe.h` at the beginning. diff --git a/src/sec14.src.md b/src/sec14.src.md index c11efeb..b3d355e 100644 --- a/src/sec14.src.md +++ b/src/sec14.src.md @@ -60,7 +60,11 @@ It implies that CSS can also be applied to GTK windowing system. The syntax of CSS is as follows. +@@@if gfm ~~~css +@@@else +~~~ +@@@end selector { color: yellow; padding-top: 10px; ...} ~~~ @@ -68,7 +72,11 @@ Every widget has CSS node. For example GtkTextView has `textview` node. If you want to set style to GtkTextView, substitute "textview" for the selector. +@@@if gfm ~~~css +@@@else +~~~ +@@@end textview {color: yellow; ...} ~~~ @@ -77,7 +85,11 @@ Refer [GTK4 API reference](https://gnome.pages.gitlab.gnome.org/gtk/gtk/theming. In line 30, the CSS is a string. +@@@if gfm ~~~css +@@@else +~~~ +@@@end textview {padding: 10px; font-family: monospace; font-size: 12pt;} ~~~ diff --git a/src/sec19.src.md b/src/sec19.src.md index dc63ea9..ae7180b 100644 --- a/src/sec19.src.md +++ b/src/sec19.src.md @@ -863,7 +863,11 @@ Meson provides `gnome.compile_schemas` method to compile XML file in the build d This is used to test the application. Write the following to the `meson.build` file. +@@@if gfm ~~~meson +@@@else +~~~ +@@@end gnome.compile_schemas(build_by_default: true, depend_files: 'com.github.ToshioCP.tfe.gschema.xml') ~~~ @@ -880,7 +884,7 @@ After compilation, you can test your application like this: $ GSETTINGS_SCHEMA_DIR=_build:$GSETTINGS_SCHEMA_DIR _build/tfe ~~~ -### GSettings object and g_setting_bind +### GSettings object and g\_settings\_bind Write gsettings related codes to `tfeapplication.c'. @@ -928,7 +932,11 @@ $ meson --prefix=$HOME/local _build Modify `meson.build` abd add install option and set it true in executable function. +@@@if gfm ~~~meson +@@@else +~~~ +@@@end executable('tfe', sourcefiles, resources, dependencies: gtkdep, export_dynamic: true, install: true) ~~~ @@ -942,7 +950,11 @@ However, you need to do one more thing. Copy your XML file to `$HOME/local/share/glib-2.0/schemas/`, which is specified in `GSETTINGS_SCHEMA_DIR` environment variable, and run `glib-compile-schemas` on that directory. +@@@if gfm ~~~meson +@@@else +~~~ +@@@end schema_dir = get_option('prefix') / get_option('datadir') / 'glib-2.0/schemas/' install_data('com.github.ToshioCP.tfe.gschema.xml', install_dir: schema_dir) ~~~ @@ -956,7 +968,11 @@ So, `$HOME/local/share/glib-2.0/schemas` is assigned to the varable `schema_dir` Meson can runs a post compile script. +@@@if gfm ~~~meson +@@@else +~~~ +@@@end meson.add_install_script('glib-compile-schemas', schema_dir) ~~~ diff --git a/src/sec23.src.md b/src/sec23.src.md new file mode 100644 index 0000000..9cc3b9c --- /dev/null +++ b/src/sec23.src.md @@ -0,0 +1,869 @@ +# Tiny turtle graphics interpreter + +A program `turtle` is an example with the combination of TfeTextView and GtkDrawingArea objects. +It is a very small interpreter but it provides a way to draw fractal curves. +The following diagram is a Koch curve, which is a famous example of fractal curves. + +![Koch curve](turtle/image/turtle_koch.png){width=8cm height=5.11cm} + +This program uses flex and bison. +Flex is a lexical analyzer. +Bison is a parser generator. +These two programs are similar to lex and yacc which are proprietary software developed in Bell Laboratry. +However, flex and bison are open source software. +I will write about how to use those software, but they are not topics about gtk. +So, readers can skip that part of this sections. + +## How to use turtle + +The documentation of turtle is [here](turtle/turtle_doc.md). +I'll show you a simple example. + +~~~ +fc (1,0,0) # Foreground color is red, rgb = (1,0,0). +pd # Pen down. +fd 100 # Go forward by 100 pixels. +tr 90 # Turn right by 90 degrees. +fd 100 +tr 90 +fd 100 +tr 90 +fd 100 +tr 90 +~~~ + +1. Compile and install `turtle` (See the documentation above). +Then, run `turtle`. +2. Type the program above in the editor (left part of the window). +3. Click on the `Run` button, then a red square appears on the right part of the window. +The side of the square is 100 pixels long. + +In the same way, you can draw other curves. +The documentation above shows some fractal curves such as tree, snow and square-koch. +The source code in turtle language is located at [src/turtle/example](turtle/example) directory. +You can read these files by clicking on the `Open` button. + +## Combination of TfeTextView and GtkDrawingArea objects + +Turtle uses TfeTextView and GtkDrawingArea. +It is similar to `color` program in the previous section. + +The body of the interpreter is written with flex and bison. +The codes are not thread safe. +So the handler of "clicked" signal of the `Run` button prevents from reentering. + +@@@include +turtle/turtleapplication.c run_cb resize_cb +@@@ + +- 8-13: The static value `busy` holds a status of the interpreter. +If it is `TRUE`, the interpreter is running and it is not possible to call the interpreter again because it's not a re-entrant program. +If it is `FALSE`, it is safe to call the interpreter. +- 14: Now it is about to call the interpreter so let `busy` variable to be TRUE. +- 15-16: Gets the contents of GtkTextBuffer. +- 17: The varable `surface` is a static variable. +It points to a `cairo_surface_t` object. +It is generated when the GtkDrawingArea object is realized and the each time it is resized. +Therefore, `surface` isn't NULL usually. +But if it is NULL, the interpreter won't be called. +- 18-19: Initializes lexcal analyzer, then parser. +- 20: Calls parser. +Parser analyze the program codes syntactically and generate a tree structured data. +- 24-26: If the parser succesfully parsed, it calls `run` which is the interpreter. +`Run` executes the tree-structured program. +- 27: finalize the lexical analyzer. +- 29: Add the drawing area object to the queue to draw. +- 30: The interpreter program has finished so `busy` is now FALSE. +- 33-38: A handler of "resized" signal. +It generates or regenerates a surface object. + +Other part of `turtleapplication.c` is almost same as the codes of `colorapplication.c` in the previous section. +The codes of `turtleapplication.c` is in the [turtle directory](turtle). + +## What does the interpreter do? + +Suppose that the turtle runs with the following program. + +~~~ +distance = 100 +fd distance*2 +~~~ + +The turtle recognizes the program above and works as follows. + +- Generally, a program consists of tokens. +Tokens are "distance", "=", "100", "fd", "*" and "2" in the above example.. +- The interpreter `turtle` calls `yylex` to read a token in the source file. +The `yylex` returns a code which is called "token kind" and sets a global variable `yylval` with a value, which is called a semantic value. +The type of `yylval` is union and `yylval.ID` is string and `yylval.NUM` is double. +There are seven tokens in the program so `yylex` is called seven times. + +| |token kind|yylval.ID|yylval.NUM| +|:-:|:--------:|:-------:|:--------:| +| 1 | ID |distance | | +| 2 | = | | | +| 3 | NUM | | 100 | +| 4 | FD | | | +| 5 | ID |distance | | +| 6 | * | | | +| 7 | NUM | | 2 | + +- `yylex` returns a token kind every time, but it doesn't set `yylval.ID` or `yylval.NUM` every time. +It is because keywords (`FD`) and symbols (`=` and `*`) don't have any semantic values. +The function `yylex` is called lexical analyzer or scanner. +- `turtle` makes a tree structured data. +This part of `turtle` is called parser. + +![turtle parser tree](../image/turtle_parser_tree.png){width=12cm height=5.34cm} + +- `turtle` analyzes the tree and executes it. +This part of `turtle` is called runtime routine. +The tree consists of line segments and rectangles between line segments. +The rectangles are called nodes. +For example, N\_PROGRAM, N\_ASSIGN, N\_FD and N\_MUL are nodes. + 1. Goes down from N\_PROGRAM to N\_ASSIGN. + 2. N_ASSIGN node has two children, ID and NUM. +This node comes from "distance = 100" which is "ID = NUM" syntactically. +First, `turtle` checks if the first child is ID. +If it's ID, then `turtle` looks for the variable in the variable table. +If it doesn't exist, it registers the ID (`distance`) to the table. +Then go back to the N\_ASSIGN node. + 3. `turtle` calculates the second child. +In this case its a number 100. +Saves 100 to the variable table at the `distance` record. + 4. `turtle` goes back to N\_PROGRAM then go to the next node N\_FD. +It has only one child. +Goes down to the child N\_MUL. + 5. The first child is ID (distance). +Searches the variable table for the varable `distance` and gets the value 100. +The second child is a number 2. +Multiplies 100 by 2 and gets 200. +Then `turtle` goes back to N_FD. + 6. Now `turtle` knows the distance is 200. +It moves the cursor forward by 200. + 8. There are no node follows. +Runtime routine returns to the main routine. +-`turtle` draws a segment on GtkDrawingArea then stops. + +Actually most programs are more complicated than the example above. +So, `turtle` does much more work to interpret programs. +However, basically it works by the same way above. +Interpritation consists of three parts. + +- Lexical analysis +- Syntax Parsing and tree generation +- Interprit the tree and execute commands. + +## Compilation flow + +The source files are: + +- flex source file ~> turtle.lex +- bison source file => turtle.y +- C header file => turtle.h, turtle_lex.h +- C source file => turtleapplication.c +- other files => turtle.ui, turtle.gresources.xml, meson.build + +The compilation process is a bit complicated. + +1. glib-compile-resources compiles `turtle.ui` to `resources.c` according to `turtle.gresource.xml`. +It also generates `resources.h`. +2. bison compiles `turtle.y` to `turtle_parser.c` and generates `turtle_parser.h` +3. flex compiles `turtle.lex` to `turtle_lex.c`. +4. gcc compiles `application.c`, `resources.c`, `turtle_parser.c` and `turtle_lex.c` with `turtle.h`, `resources.h` and `turtle_parser.h`. +It generates an executable file `turtle`. + +![compile process](../image/turtle_compile_process.png){width=12cm height=9cm} + +Meson controls the process and the instruction is described in meson.build. + +@@@include +turtle/meson.build +@@@ + +- 3: Gets C compiler. +It is usually `gcc` in linux. +- 4: Gets math library. +This program uses trigonometric functions. +They are defined in the math library, but the library is optional. +So, it is necessary to include the library by `#include ` and also link the library with the linker. +- 6: Gets gtk4 library. +- 8: Gets gnome module. +Module is a system provided by meson. +See [Meson build system website](https://mesonbuild.com/Gnome-module.html#gnome-module) for further information. +- 9: Compiles ui file to C source file according to the XML file `turtle.gresource.xml`. +- 11: Gets flex. +- 12: Gets bison. +- 13: Compiles `turtle.y` to `turtle_parser.c` and `turtle_parser.h` by bison. +The function `custom_target`creates a custom top level target. +See [Meson build system website](https://mesonbuild.com/Reference-manual.html#custom_target) for further information. +- 14: Compiles `turtle.lex` to `turtle_lex.c` by flex. +- 16: Specifies C surce files. +- 18: Compiles C source files including generated files by glib-compile-resources, bison and flex. +The argument `turtleparser[1]` refers to `tirtle_parser.h` which is the secound output in the line 13. + +## Turtle.lex + +### What does flex do? + +Flex creates lexical analizer from flex source file. +Flex source file is a text file and its syntactic rule will be explained later. +Generated lexical analyzer is a C source file. +It is also called scanner. +It reads a text file, which is a source file of a program language, and gets variable names, numbers and symbols. +Suppose here is a turtle source file. + +~~~ +fc (1,0,0) # Foreground color is red, rgb = (1,0,0). +pd # Pen down. +distance = 100 +angle = 90 +fd distance # Go forward by distance (100) pixels. +tr angle # Turn right by angle (90) degrees. +~~~ + +The content of the text file is separated into `fc`, `(`, `1`, `,` and so on. +The words `fc`, `pd`, `distance` and `100` are called tokens. +The characters `(`, `<` and `=` are called symbols. +( Sometimes those symbols called token, too.) + +Flex reads `turtle.lex` and generates a scanner. +The file `turtle.lex` specifies tokens, symbols and the behavior which corresponds to each token or symbol. +Turtle.lex isn't a big program. + +@@@include +turtle/turtle.lex +@@@ + +The file consists of three sections which are separated by "%%" (line 19 and 58). +They are definitions, rules and user code sections. + +### Definitions section + +First, look at the definitions section. + +- 1-12: Lines between "%top{" and "}" are C source codes. +They will be copied to the top of the generated C source file. +- 2-3: The function `strlen`, in line 64, is defined in `string.h` +The function `atof`, in line 39, is defined in `stdlib.h`. +- 6-8: The current input position is pointed by `nline` and `ncolumn`. +The function `get_location` (line 60-65) sets `yylloc`to point the start and end point of `yytext` in the buffer. +This function is declared here so that it can be called before the function is defined. +- 11: GSlist is used to keep allocated memories. +- 14: This option (`%option noyywrap`) must be specified when you have only single source file to the scanner. Reffur to "9 The Generated Scanner" in the flex documentation in your distribution for further information. +(The documentation is not on the internet.) +- 16-17: `REAL_NUMBER` and `IDENTIFIER` are names. +A name begins with a letter or an underscore followed by zero or more letters, digits, underscores (`_`) or dashes (`-`). +They are followed by regular expressions which are the definition of them. +They will be used in rules section and will expand to the definition. +You can leave out such definitions here and use regular expressions in rules section directly. + +### Rules section + +This section is the most important part. +Rules consist of patterns and actions. +For example, line 37 is a rule. + +- `{REAL_NUMBER}` is a pattern +- `get_location (yytext); yylval.NUM = atof (yytext); return NUM;` is an action. + +`{REAL_NUMBER}` is defined in the 16th line, so it expands to `(0|[1-9][0-9]*)(\.[0-9]+)?`. +This regular expression matches numbers like `0`, `12` and `1.5`. +If the input is a number, it matches the pattern in line 37. +Then the matched text is assigned to `yytext` and corresponding action is executed. +A function `get_location` changes the location variables. +It assigns `atof( yytext)`, which is double sized number converted from `yytext`, to `yylval.NUM` and return `NUM`. +`NUM` is an integer defined by `turtle.y`. + +The scanner generated by flex and C compiler has `yylex` function. +If `yylex` is called and the input is "123.4", then it works as follows. + +1. A string "123.4" matches `{REAL_NUMBER}`. +2. Update the location variable `ncolumn` and `yylloc`. +3. `atof` converts the string "123.4" to double sized floating point number 123.4. +4. It is assigned to `yylval.NUM`. +5. `yylex` returns `NUM` to the caller. + +Then the caller knows the input is `NUM` (number), and its value is 123.4. + +- 19-55: Rules section. +- 20: Comment begins `#` followed by any characters except newline. +No action happens. +- 21: White space just increases a varable `ncolumn` by one. +- 22: Tab is assumed to be equal to eight spaces. +- 23: New line increases a variable `nline` by one and resets `ncolumn`. +- 25-35: Keywords just updates the location variables `ncolumn` and `yylloc`, and return the codes of the keywords. +- 37: Real number constant. +- 38: Identifier is defined in line 17. +It begins alphabet followed by zero or more alphabet or digit. +The location variables are updated and the name of the identifier is assigned to `yylval.ID`. +The memory of the name is allocated by the function `g_strdup`. +The memory is registerd to the list (GSlist type list). +The memory will be freed after the runtime routine finishes. +Returns `ID`. +- 43-54: Symbols just update the location variable and return the codes. +The code is the same as the symbol itself. +- 55: If the input doesn't match above patterns, then it is error. +Returns `YYUNDEF`. + +### User code section + +This section is just copied to C source file. + +- 58-63: A function `get_location`. +The location of the input is recorded to `nline` and `ncolumn`. +These two variables are for the scanner. +A variable `yylloc` is shared by the scanner and the parser. +It is a C structure and has four members, `first_line`, `first_column`, `last_line` and `last_column`. +They point the start and end of the current input text. +- 65: `YY_BUFFER_STATE` is a type of the pointer points the input buffer. +- 67-70: `init_flex` is called by `run_cb` signal handler, which is called when `Run` button is clicked on. +`run_cb` has one argument which is the copy of the content of GtkTextBuffer. +`yy_scan_string` sets the input buffer to read from the text. +- 72-75: `finalize_flex` is called after runtime routine finishes. +It deletes the input buffer. + +## Turtle.y + +Turtle.y has more than 800 lines so it is difficult to explain all the source code. +So I will explain the key points and leave out other less important parts. + +### What does bison do? + +Bison creates C source file of a parser from bison source file. +Bison source file is a text file. +A parser analyzes a program source code according to its grammar. +Suppose here is a turtle source file. + +~~~ +fc (1,0,0) # Foreground color is red, rgb = (1,0,0). +pd # Pen down. +distance = 100 +angle = 90 +fd distance # Go forward by distance (100) pixels. +tr angle # Turn right by angle (90) degrees. +~~~ + +The parser calls `yylex` to get a token. +The token consists of its type (token kind) and value (semantic value). +So, the parser gets items in the following table whenever it calls `yylex`. + +| |token kind|yylval.ID|yylval.NUM| +|:-:|:--------:|:-------:|:--------:| +| 1 | FC | | | +| 2 | ( | | | +| 3 | NUM | | 1.0 | +| 4 | , | | | +| 5 | NUM | | 0.0 | +| 6 | , | | | +| 7 | NUM | | 0.0 | +| 8 | ) | | | +| 9 | PD | | | +|10 | ID |distance | | +|11 | = | | | +|12 | NUM | | 100.0 | +|13 | ID | angle | | +|14 | = | | | +|15 | NUM | | 90.0 | +|16 | FD | | | +|17 | ID |distance | | +|18 | TR | | | +|19 | ID | angle | | + +Bison source code specifies the grammar rules of turtle language. +For example, `fc (1,0,0)` is called primary procedure. +A procedure is like a void type function in C source code. +It doesn't return any values. +Programmers can define their own procedures. +On the other hand, `fc` is a built-in procedure. +Such procedures are called primary procedures. +It is described in Bison source code like: + +~~~ +primary_procedure: FC '(' expression ',' expression ',' expression ')'; +expression: ID | NUM; +~~~ + +This means: + +- Primary procedure is FC followed by '(', expression, ',', expression, ',', expression and ')'. +- expression is ID or NUM. + +The description above is called BNF (Backus-Naur form). +More precisely, it is similar to BNF. + +The first line is: + +~~~ +FC '(' NUM ',' NUM ',' NUM ')'; +~~~ + +You can find this is a primary_procedure easily. +The parser of the turtle language analyzes the turtle source code in the same way. + +The grammar of turtle is described in the [document](turtle/turtle_doc.md). +The following is an extract from the document. + +~~~ +program: + statement +| program statement +; + +statement: + primary_procedure +| procedure_definition +; + +primary_procedure: + PU +| PD +| PW expression +| FD expression +| TR expression +| BC '(' expression ',' expression ',' expression ')' +| FC '(' expression ',' expression ',' expression ')' +| ID '=' expression +| IF '(' expression ')' '{' primary_procedure_list '}' +| RT +| RS +| ID '(' ')' +| ID '(' argument_list ')' +; + +procedure_definition: + DP ID '(' ')' '{' primary_procedure_list '}' +| DP ID '(' parameter_list ')' '{' primary_procedure_list '}' +; + +parameter_list: + ID +| parameter_list ',' ID +; + +argument_list: + expression +| argument_list ',' expression +; + +primary_procedure_list: + primary_procedure +| primary_procedure_list primary_procedure +; + +expression: + expression '=' expression +| expression '>' expression +| expression '<' expression +| expression '+' expression +| expression '-' expression +| expression '*' expression +| expression '/' expression +| '-' expression %prec UMINUS +| '(' expression ')' +| ID +| NUM +; +~~~ + +The grammar rule defines `program` first. + +- program is a statement or a program followed by a statement. + +The definition is recursive. + +- `statement` is program. +- `statement statement` is `program statemet`. +Therefore, it is program. +- `statement statement statement` is `program statemet`. +Therefore, it is program. + +You can find that a list of statements is program like this. + +`program` and `statement` aren't tokens. +They don't appear in the input. +They are called non terminal symbols. +On the other hand, tokens are called terminal symbols. +The word "token" used here has wide meaning, it includes tokens and symbols which appear in the input. +Non terminal symbols are often shortend to nterm. + +Let's analyze the program above as bison does. + +| |token kind|yylval.ID|yylval.NUM|parse |S/R| +|:-:|:--------:|:-------:|:--------:|:-----------------------------------|:-:| +| 1 | FC | | |FC | S | +| 2 | ( | | |FC( | S | +| 3 | NUM | | 1.0 |FC(NUM | S | +| | | | |FC(expression | R | +| 4 | , | | |FC(expression, | S | +| 5 | NUM | | 0.0 |FC(expression,NUM | S | +| | | | |FC(expression,expression | R | +| 6 | , | | |FC(expression,expression, | S | +| 7 | NUM | | 0.0 |FC(expression,expression,NUM | S | +| | | | |FC(expression,expression,expression | R | +| 8 | ) | | |FC(expression,expression,expression)| S | +| | | | |primary_procedure | R | +| | | | |statement | R | +| | | | |program | R | +| 9 | PD | | |program PD | S | +| | | | |program primary_procedure | R | +| | | | |program statement | R | +| | | | |program | R | +|10 | ID |distance | |program ID | S | +|11 | = | | |program ID= | S | +|12 | NUM | | 100.0 |program ID=NUM | S | +| | | | |program ID=expression | R | +| | | | |program primary_procedure | R | +| | | | |program statement | R | +| | | | |program | R | +|13 | ID | angle | |program ID | S | +|14 | = | | |program ID= | S | +|15 | NUM | | 90.0 |program ID=NUM | S | +| | | | |program ID=expression | R | +| | | | |program primary_procedure | R | +| | | | |program statement | R | +| | | | |program | R | +|16 | FD | | |program FD | S | +|17 | ID |distance | |program FD ID | S | +| | | | |program FD expression | R | +| | | | |program primary_procedure | R | +| | | | |program statement | R | +| | | | |program | R | +|18 | TR | | |program TR | S | +|19 | ID | angle | |program TR ID | S | +| | | | |program TR expression | R | +| | | | |program primary_procedure | R | +| | | | |program statement | R | +| | | | |program | R | + +The right most column shows shift/reduce. +Shift is appending an input to the buffer. +Reduce is substituing a higher nterm for the pattern in the buffer. +For example, NUM is replaced by expression in the forth row. +This substitution is "reduce". + +Bison repeats shift and reduction until the end of the input. +If the result is reduced to `program`, the input is syntactically valid. +Bison executes an action whenever reduction occers. +Actions build a tree. +The tree is analyzed and executed by runtime routine . + +Bison source files are called bison grammar files. +A bison grammar file consists of four sections, prologue, declarations, rules and epilogue. +The format is as follows. + +~~~ +%{ +prologue +%} +declarations +%% +rules +%% +epilogue +~~~ + +### Prologue + +Prologue section consists of C codes and the codes are copied to the parser implementation file. +You can use `%code` directives to qualify the prologue and identifies the purpose explisitely. +The following is an extract from `turtle.y`. + +@@@if gfm +~~~bison +@@@elif html +~~~{.bison} +@@@else +~~~ +@@@end +%code top{ + #include + #include + #include + #include "turtle.h" + + /* error reporting */ + static void yyerror (char const *s) { /* for syntax error */ + g_print ("%s from line %d, column %d to line %d, column %d\n",s, yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column); + } + /* Node type */ + enum { + N_PU, + N_PD, + N_PW, + ... ... ... + }; +} +~~~ + +The directove `%code top` copies its contents to the top of the parser implementation file. +It usually includes `#include` directives, declarations of functions and definitions of constants. +A function `yyerror` reports a syntax error and is called by the parser. +Node type identifies a node in the tree. + +Another directive `%code requires` copies its contents to both the parser implementation file and header file. +The header file is read by the scanner C source file and other files. + +@@@if gfm +~~~bison +@@@elif html +~~~{.bison} +@@@else +~~~ +@@@end +%code requires { + int yylex (void); + void init_parse (void); + int yyparse (void); + void run (void); + + /* semantic value type */ + typedef struct _node_t node_t; + struct _node_t { + int type; + union { + struct { + node_t *child1; + node_t *child2; + node_t *child3; + } child; + char *name; + double value; + } content; + }; +} +~~~ + +The contents of this directive are used by the other files. + +- `yylex` is shared by parser implemetation file and scanner file. +- `init_parse`, `yyparse` and `run` is called by `run_cb' in `turtleapplication.c`. +- `node_t` is the type of the semantic value of nterms. +The header file defines `YYSTYPE`, which is the semantic value type, with all the token and nterm value types. +The following is extracted from the header file. + +~~~ +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ + char * ID; /* ID */ + double NUM; /* NUM */ + node_t * program; /* program */ + node_t * statement; /* statement */ + node_t * primary_procedure; /* primary_procedure */ + node_t * primary_procedure_list; /* primary_procedure_list */ + node_t * procedure_definition; /* procedure_definition */ + node_t * parameter_list; /* parameter_list */ + node_t * argument_list; /* argument_list */ + node_t * expression; /* expression */ +}; +~~~ + +Other useful macros and declarations are put into the `%code` directive. + +~~~ +%code { +/* The following macro is convenient to get the member of the node. */ + #define child1(n) (n)->content.child.child1 + #define child2(n) (n)->content.child.child2 + #define child3(n) (n)->content.child.child3 + #define name(n) (n)->content.name + #define value(n) (n)->content.value + + /* start of nodes */ + static node_t *node_top = NULL; + /* functions to generate trees */ + static node_t *tree1 (int type, node_t *child1, node_t *child2, node_t *child3); + static node_t *tree2 (int type, double value); + static node_t *tree3 (int type, char *name); +} +~~~ + +### Bison declarations + +Bison declarations defines terminal and nonterminal symbols. +It also specifies some directives. + +~~~ +%locations +%define api.value.type union /* YYSTYPE, the type of semantic values, is union of following types */ + /* key words */ +%token PU +%token PD +%token PW +%token FD +%token TR +%token BC +%token FC +%token DP +%token IF +%token RT +%token RS + /* constant */ +%token NUM + /* identirier */ +%token ID + /* non terminal symbol */ +%nterm program +%nterm statement +%nterm primary_procedure +%nterm primary_procedure_list +%nterm procedure_definition +%nterm parameter_list +%nterm argument_list +%nterm expression + /* logical relation symbol */ +%left '=' '<' '>' + /* arithmetic symbol */ +%left '+' '-' +%left '*' '/' +%precedence UMINUS /* unary minus */ +~~~ + +`%locations` directive inserts the location structure into the header file. +It is like this. + +~~~ +typedef struct YYLTYPE YYLTYPE; +struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +~~~ + +This type is shared by the scanner file and the parser implementation file. +The error report function `yyerror` uses it so that it can inform the location that error occers. + +`%define api.value.type union` generates semantic value type with tokens and nterms and inserts it to the header file. +The inserted part is shown in the previous section as the extracts that shows the value type (YYSTYPE). + +`%token` and `%nterm` directives define tokens and directives respectively. + +~~~ +%token PU +... ... +%token NUM +~~~ + +These directives define a token `PU` and NUM. +The values of token kinds `PU` and `NUM` are defined as an enumeration constant in the header file. + +~~~ + enum yytokentype + { + ... ... ... + PU = 258, /* PU */ + ... ... ... + NUM = 269, /* NUM */ + ... ... ... + }; + typedef enum yytokentype yytoken_kind_t; +~~~ + +In addition, the type of the semantic value of NUM is defined as double in the header file because of `` tag. + +~~~ +union YYSTYPE +{ + char * ID; /* ID */ + double NUM; /* NUM */ + ... ... +} +~~~ + +All the nterm symbols have the same type `* node_t` of the semantic value. + +`%left` and `%precedence` directives define the precedence of operation symbols. + +~~~ + /* logical relation symbol */ +%left '=' '<' '>' + /* arithmetic symbol */ +%left '+' '-' +%left '*' '/' +%precedence UMINUS /* unary minus */ +~~~ + +`%left` directive defines the following symbols as left-associated operator. +If an operator `+` is left-associated, then + +~~~ +A + B + C = (A + B) + C +~~~ + +That is, the calculation is carried out the left operator first, then the right operator. +If an operator `*` is right-assiciated, then: + +~~~ +A * B * C = A * (B * C) +~~~ + +The definition above decides the behavior of the parser. +Addition and multiplication hold associative law so the result of `(A+B)+C` and `A+(B+C)` are equal in terms of mathematics. +However, the parser will be confused if left (or right) assosiativity is not specified. + +`%left` and `%precedence` directive show the precedence of operators. +Later declared operators have higher precedence than former declared ones. +The declaration above says, for example, + +~~~ +v=w+z*5+7 is the same as v=((w+(z*5))+7) +~~~ + +Be careful. +The operator `=` is a logical equal operator, not assignment operator. +Assignment is not expression in turtle language. +It is primary_procedure. +Therefore, if `=` appears in an expression, it is *NOT* an assignment. + +### Grammar rules + +Grammar rules section defines the syntactic grammar of the language. +It is similar to BNF form. + +~~~ +result: components { action }; +~~~ + +- result is a nterm. +- components are list of tokens or nterms. +- action is C codes. It is executed whenever the components are reduced to the result. +Action can be left out. + +The following is the first eleven lines of the grammar rule in `turtle.y`. + +~~~ +program: + statement { node_top = $$ = $1; } +| program statement { + node_top = $$ = tree1 (N_program, $1, $2, NULL); + } +; + +statement: + primary_procedure +| procedure_definition +; +~~~ + +The first six lines show that `program` is `statement` or `program` followed by `statement`. + +- Whenever `statement` is reduced to `program`, an action `node_top=$$=$1;` is executed. +- In the same way, whenever `program` followed by `statment is reduced to `program`, +`node_top=$$=tree1(N_program,$1,$2,NULL);` is executed. +- `node_top` is a static variable. +It points the top node of the tree. +- `$$` is a semantic value of the result, which is `program` in the example above. +The semantic value of `program` is a pointer to `node_t` type structure. +It was defined in the declaration section. +- `$1` is a semantic value of the first component, which is `statement` in the example. +The semantic value of `statement` is also a pointer to `node_t`. +- The function `tree1` generates tree node. + + + +### Epilogue diff --git a/src/sec6.src.md b/src/sec6.src.md index aff18e7..0f3e8ea 100644 --- a/src/sec6.src.md +++ b/src/sec6.src.md @@ -27,7 +27,7 @@ gtk_application_new (const gchar *application_id, GApplicationFlags flags); This flag is described in the GApplication section in GIO API reference. -~~~C +~~~ GApplicationFlags' Members G_APPLICATION_FLAGS_NONE Default. (No argument allowed) diff --git a/src/sec9.src.md b/src/sec9.src.md index f453f20..3261dd6 100644 --- a/src/sec9.src.md +++ b/src/sec9.src.md @@ -84,7 +84,7 @@ It is an old and widely used program. Make analyzes Makefile and executes compilers. All instructions are written in Makefile. -~~~Makefile +~~~makefile sample.o: sample.c gcc -o sample.o sample.c ~~~ diff --git a/src/turtle/meson.build b/src/turtle/meson.build index 7b4df83..9477a15 100644 --- a/src/turtle/meson.build +++ b/src/turtle/meson.build @@ -15,5 +15,5 @@ turtlelexer = custom_target('turtlelexer', input: 'turtle.lex', output: 'turtle_ sourcefiles=files('turtleapplication.c', '../tfetextview/tfetextview.c') -executable('turtle', sourcefiles, resources, turtleparser, turtlelexer, turtleparser[1], dependencies: [mathdep, gtkdep], export_dynamic: true) +executable('turtle', sourcefiles, resources, turtleparser, turtlelexer, turtleparser[1], dependencies: [mathdep, gtkdep], export_dynamic: true, install: true) diff --git a/src/turtle/turtle.lex b/src/turtle/turtle.lex index f182eb7..1edd9e0 100644 --- a/src/turtle/turtle.lex +++ b/src/turtle/turtle.lex @@ -1,4 +1,5 @@ %top{ +#include #include #include "turtle.h" @@ -12,12 +13,11 @@ %option noyywrap -DIGIT [0-9] REAL_NUMBER (0|[1-9][0-9]*)(\.[0-9]+)? IDENTIFIER [a-zA-Z][a-zA-Z0-9]* %% /* rules */ -#.*\n nline++; ncolumn = 1; /* comment */ +#.* ; /* comment. Be careful. Dot symbol (.) matches any character but new line. */ [ ] ncolumn++; \t ncolumn += 8; /* assume that tab is 8 spaces. */ \n nline++; ncolumn = 1; diff --git a/src/turtle/turtle.y b/src/turtle/turtle.y index de21bf4..7ad4538 100644 --- a/src/turtle/turtle.y +++ b/src/turtle/turtle.y @@ -16,10 +16,8 @@ /* error reporting */ static void yyerror (char const *s) { /* for syntax error */ - g_print ("%s\n",s); + g_print ("%s from line %d, column %d to line %d, column %d\n",s, yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column); } - static void runtime_error (char *format, ...); - /* Node type */ enum { N_PU, @@ -97,7 +95,7 @@ int yyparse (void); void run (void); - /* node type */ + /* semantic value type */ typedef struct _node_t node_t; struct _node_t { int type; @@ -122,14 +120,13 @@ #define value(n) (n)->content.value /* start of nodes */ - node_t *node_top = NULL; + static node_t *node_top = NULL; /* functions to generate trees */ - node_t *tree1 (int type, node_t *child1, node_t *child2, node_t *child3); - node_t *tree2 (int type, double value); - node_t *tree3 (int type, char *name); + static node_t *tree1 (int type, node_t *child1, node_t *child2, node_t *child3); + static node_t *tree2 (int type, double value); + static node_t *tree3 (int type, char *name); } -%defines %locations %define api.value.type union /* YYSTYPE, the type of semantic values, is union of following types */ /* key words */ @@ -188,11 +185,13 @@ primary_procedure: | TR expression { $$ = tree1 (N_TR, $2, NULL, NULL); } | BC '(' expression ',' expression ',' expression ')' { $$ = tree1 (N_BC, $3, $5, $7); } | FC '(' expression ',' expression ',' expression ')' { $$ = tree1 (N_FC, $3, $5, $7); } + /* assignment */ | ID '=' expression { $$ = tree1 (N_ASSIGN, tree3 (N_ID, $1), $3, NULL); } + /* control flow */ | IF '(' expression ')' '{' primary_procedure_list '}' { $$ = tree1 (N_IF, $3, $6, NULL); } | RT { $$ = tree1 (N_RT, NULL, NULL, NULL); } | RS { $$ = tree1 (N_RS, NULL, NULL, NULL); } - /* procedure call */ + /* user defined procedure call */ | ID '(' ')' { $$ = tree1 (N_procedure_call, tree3 (N_ID, $1), NULL, NULL); } | ID '(' argument_list ')' { $$ = tree1 (N_procedure_call, tree3 (N_ID, $1), $3, NULL); } ; @@ -239,6 +238,9 @@ expression: %% +/* Declaration of the runtime error function */ +static void runtime_error (char *format, ...); + /* Dinamically allocated memories are added to the single list. They will be freed in the finalize function. */ GSList *list = NULL; diff --git a/src/turtle/turtle_doc.md b/src/turtle/turtle_doc.md index 6cbd79d..7ffa36c 100644 --- a/src/turtle/turtle_doc.md +++ b/src/turtle/turtle_doc.md @@ -12,18 +12,19 @@ You need: - gtk4 It is easy to compile the source file of turtle. +If you have installed gtk4 with an option `--prefix=$HOME/local`, put the same option to meson so that you can install `turtle` under the directory `$HOME/local/bin`. The instruction is: ~~~ -$ meson _build +$ meson --prefix=$HOME/local _build $ ninja -C _build +$ ninja -C _build install ~~~ -Then, the executable file _build/turtle is generated. Type the following command then turtle shows the following window. ~~~ -$ _build/turtle +$ turtle ~~~ ![Screenshot just after it's executed](image/turtle1.png) @@ -36,7 +37,7 @@ Write turtle language in the text editor and click on `run` button, then the pro ![Tree](image/turtle_tree.png) If you add the following line in `turtle.h`, then codes to inform the status will also be compiled. -However, the speed will be quite slow because of the output message. +However, the speed will be quite slow because of the output messages. ~~~ # define debug 1 @@ -80,7 +81,7 @@ fd 100 ~~~ The command `tr` is "Turn Right". -The argument is angle with degree. +The argument is angle with degrees. Therefore, `tr 90` means "Turn right by 90 degrees". If you click on `run`button, then two line segment appears. One is vertical and the other is horizontal. @@ -128,6 +129,7 @@ Statements are executed in the order from the top to the end ## Comment and spaces Characters between `#` (hash mark) and `\n` (new line) inclusive are comment. +Characters between `#` and `EOF` (end of file) are also comment. Comments are ignored. ~~~ @@ -139,11 +141,8 @@ tr 120 fd 100 # Now a triangle appears. ~~~ -The comments in the line 1, 2 and 3 are correct. -But there is a bug in the line 6. -The characters after `#` is not recognized as a comment because no new line follows. -You need to press the enter-key and put new line before the end of file. -This is a difficult bug to find. +\ and \ are newline code and end of file respectively. +The comments in the line 1, 2, 3 and 6 are correct syntactically. Spaces (white space, tab and new line) are ignored. They are used only as delimiters. @@ -172,7 +171,7 @@ distance = 100 fd distance ~~~ -A value 100 is assigned tp the variable `distance` in the first line. +A value 100 is assigned to the variable `distance` in the first line. Assignment is a statement. Most of statements begin with commands like `fd`. Assignment is the only exception. @@ -180,14 +179,14 @@ Assignment is the only exception. This program draws a line segment of 100 pixels long. You can use variables in any places in expressions. -There are 8 kinds of calculation available. +There are 8 kinds of calculations available. - addition: x + y - subtraction: x - y - multiplication: x * y - division: x / y - unary minus: - x -- logical equal: x = y This symbol `=` works as `==` in C language. +- logical equal: x = y. This symbol `=` works as `==` in C language. - greater than: x > y - less than: x < y @@ -262,9 +261,9 @@ a () This is a correct program. -- 1: Define a procedure `a`. +- 1: Defines a procedure `a`. A variable `a` is in its body. -- 2: Assign 100 to a variable `a`. +- 2: Assigns 100 to a variable `a`. - 3: Procedure `a` is called. However, using the same name to a procedure and variable makes confusing. @@ -315,7 +314,7 @@ It is the first stage. The second stage adds two shorter line segments at the endpoint of the original segment. The new segment has 70 percent length to the original segment and the orientation is +30 or -30 degrees different. The third stage adds two shorter line segments to the second stage line segments. -And repeat this several times. +And repeats this several times. This repeating is programmed by recursive call. Two more examples are shown here. @@ -381,7 +380,7 @@ Comments and spaces: These characters are used to separate tokens explicitly. They doesn't have any syntactic meaning and are ignored by the parser. -## Syntax +## Grammar ~~~ program: diff --git a/test/test_lib_mktbl.rb b/test/test_lib_mktbl.rb new file mode 100644 index 0000000..a51f047 --- /dev/null +++ b/test/test_lib_mktbl.rb @@ -0,0 +1,4 @@ +require_relative '../lib/lib_mktbl.rb' + +test + diff --git a/test/test_lib_src2md.rb b/test/test_lib_src2md.rb index 9d1d9f6..7273a16 100644 --- a/test/test_lib_src2md.rb +++ b/test/test_lib_src2md.rb @@ -147,7 +147,7 @@ Otherwise (latex) it remains. ![Screenshot of the box](../../image/screenshot_lb4.png){width=6.3cm height=5.325cm} EOS -sample_md = <