PIC PIC
Master of Science in Informatics at Grenoble
Master Mathématiques Informatique - spécialité Informatique
option Graphics, Vision and Robotics

Programmable Generation of 2D Vector Textures

Hugo Loi
06/09/2012
Research project performed at MAVERICK - Laboratoire LJK - INRIA Rhône-Alpes
Under the supervision of:
Joëlle Thollot, INRIA Rhône-Alpes
Thomas Hurtut, Université Paris Descartes
Defended before a jury composed of:
Marie-Paule Cani
James L. Crowley
Remi Ronfard
Joëlle Thollot
Thomas Hurtut
Pascal Barla
September 2012

Abstract

For a long time, artists and technical illustrators have used textures made of small 2D elements, arranged in a repetitive fashion. These textures have been widely used to produce pictures. Today, the diffusion of high resolution color wide printers and digital looms creates a need for very large digital pictures. However, producing textures by hand is a slow and tedious process. The automation of this process has been an intense research field for years. There is still a difficult trade off between the control given over this automation and the user-friendliness of this control. In addition, the sudden increase of available input data and of the number of specific needs for texture generation casts doubt on the “one application, one method” approach. We present a domain-specific language for making programmable description of 2D vector elements arrangements. This description language provides a user-friendly control over the exploration a wide space of resulting arrangements, as well as a user-friendly control for the creation and importation of input data for the programs. It also enables communication with non technical users through a visual notation, and encourages trial-and-error use by allowing incremental modification of the programs and showing the result within acceptable computation time.

Résumé

Depuis longtemps, les artistes et les illustrateurs techniques se servent de textures à base de petits éléments 2D, organisés d’une manière répétitive. Ces textures ont été largement utilisées pour produire diverses images. Aujourd’hui, la diffusion de grandes imprimantes couleurs à haute résolution et de métiers à tisser pilotés par ordinateur crée une demande pour de très grandes oeuvres digitales. Toutefois, le dessin manuel des textures est un procédé coûteux et souvent ennuyeux. L’automatisation de ce procédé est un domaine intense de recherche depuis des années. Le compromis entre le niveau de contrôle de l’automatisation et l’ergonomie de ce contrôle est une problématique encore débattue. De plus, l’explosion de la quantité de données disponibles, candidates comme données d’entrée de l’automatisation, et du nombre de besoins particuliers en terme de génération de textures, remet en cause l’approche “une application, une méthode”. Nous présentons ici un langage spécifique au domaine pour décrire de façon programmable des compositions d’éléments 2D. Ce langage de description donne un contrôle ergonomique pour l’exploration d’un grand espace de résultats. Un autre contrôle ergonomique est présenté pour encourager la création et l’importation de données d’entrée. Il facilite également la discussion avec des utilisateurs non techniques. Ce langage encourage également les approches essai-erreur, en autorisant des modifications incrémentales des programmes et en montrant suffisament rapidement les résultats correspondants.

______________________________________________________________________________________

Contents

Abstract
Résumé
Operators of the VEAD language
 1.1 CIRCLE_SET
  1.1.1 Outputs
  1.1.2 Inputs
  1.1.3 Description
 1.2 OUTPUT_SIZE
  1.2.1 Outputs
  1.2.2 Inputs
  1.2.3 Description
 1.3 UNIFORM_INITIAL_DISTRIBUTION_STRATEGY
  1.3.1 Outputs
  1.3.2 Description
 1.4 HALTON_INITIAL_DISTRIBUTION_STRATEGY
  1.4.1 Outputs
  1.4.2 Inputs
  1.4.3 Description
 1.5 DART_INITIAL_DISTRIBUTION_STRATEGY
  1.5.1 Outputs
  1.5.2 Inputs
  1.5.3 Description
 1.6 INITIAL_DISTRIBUTION
  1.6.1 Outputs
  1.6.2 Inputs
  1.6.3 Description
 1.7 DART_HATCHING
  1.7.1 Outputs
  1.7.2 Inputs
  1.7.3 Description
 1.8 GEO_EDGES_FROM_SVG
  1.8.1 Outputs
  1.8.2 Inputs
  1.8.3 Description
 1.9 LLOYD_DISTRIBUTION
  1.9.1 Outputs
  1.9.2 Inputs
  1.9.3 Description
 1.10 CENTER_LLOYD_DISTRIBUTION
  1.10.1 Outputs
  1.10.2 Inputs
  1.10.3 Description
 1.11 ORIENTED_DISTRIBUTION
  1.11.1 Outputs
  1.11.2 Inputs
  1.11.3 Description
 1.12 JITTER_DISTRIBUTION
  1.12.1 Outputs
  1.12.2 Inputs
  1.12.3 Description
 1.13 INTERP_DISTRIBUTION
  1.13.1 Outputs
  1.13.2 Inputs
  1.13.3 Description
 1.14 DILATED_DISTRIBS
  1.14.1 Outputs
  1.14.2 Inputs
  1.14.3 Description
 1.15 LAST_FROM_DISTRIBUTION
  1.15.1 Outputs
  1.15.2 Inputs
  1.15.3 Description
 1.16 SELECT_PERCENT_FROM_DISTRIBUTION
  1.16.1 Outputs
  1.16.2 Inputs
  1.16.3 Description
 1.17 GEO_DART
  1.17.1 Outputs
  1.17.2 Inputs
  1.17.3 Description
 1.18 UNION_DISTRIB
  1.18.1 Outputs
  1.18.2 Inputs
  1.18.3 Description
 1.19 DART_FILL
  1.19.1 Outputs
  1.19.2 Inputs
  1.19.3 Description
 1.20 POINT_SET
  1.20.1 Outputs
  1.20.2 Inputs
  1.20.3 Description
 1.21 UNION_SET
  1.21.1 Outputs
  1.21.2 Inputs
  1.21.3 Description
 1.22 CIRCLE_SET
  1.22.1 Outputs
  1.22.2 Inputs
  1.22.3 Description
 1.23 ELLIPSE_SET
  1.23.1 Outputs
  1.23.2 Inputs
  1.23.3 Description
 1.24 FILE_SHAPE
  1.24.1 Outputs
  1.24.2 Inputs
  1.24.3 Description
 1.25 FILE_DENSITY_MAP
  1.25.1 Outputs
  1.25.2 Inputs
  1.25.3 Description
 1.26 UNIFORM_DENSITY_MAP
  1.26.1 Outputs
  1.26.2 Description
 1.27 POINT_GRADATION_DENSITY_MAP
  1.27.1 Outputs
  1.27.2 Inputs
  1.27.3 Description
 1.28 ACCUMULATION_DENSITY_FROM_SLOPE
  1.28.1 Outputs
  1.28.2 Inputs
  1.28.3 Description
 1.29 GEO_DENSITY_FROM_ASPECT
  1.29.1 Outputs
  1.29.2 Inputs
  1.29.3 Description
 1.30 GEO_DENSITY_FROM_EDGES
  1.30.1 Outputs
  1.30.2 Inputs
  1.30.3 Description
 1.31 TEST_HEIGHT_MAP
  1.31.1 Outputs
  1.31.2 Description
 1.32 FILE_HEIGHT_MAP
  1.32.1 Outputs
  1.32.2 Inputs
  1.32.3 Description
 1.33 FILE_MASK_MAP
  1.33.1 Outputs
  1.33.2 Inputs
  1.33.3 Description
 1.34 COLOR_MASK
  1.34.1 Outputs
  1.34.2 Inputs
  1.34.3 Description
 1.35 ANCHORED_ORIENTATION_MAP
  1.35.1 Outputs
  1.35.2 Description
 1.36 SVGFILE_ORIENTATION_MAP
  1.36.1 Outputs
  1.36.2 Inputs
  1.36.3 Description
 1.37 SCALED_ORIENTATION_MAP
  1.37.1 Outputs
  1.37.2 Inputs
  1.37.3 Description
 1.38 FILE_ORIENTATION_MAP
  1.38.1 Outputs
  1.38.2 Inputs
  1.38.3 Description
 1.39 GEO_TESTASPECT_FROM_EDGES
  1.39.1 Outputs
  1.39.2 Inputs
  1.39.3 Description
 1.40 RANDOM_ORIENTATION_MAP
  1.40.1 Outputs
  1.40.2 Description
 1.41 UNIFORM_ORIENTATION_MAP
  1.41.1 Outputs
  1.41.2 Inputs
  1.41.3 Description
 1.42 ADD_RANDOM_ORIENTATION
  1.42.1 Outputs
  1.42.2 Inputs
  1.42.3 Description
 1.43 RASTERIZED_VORONOI
  1.43.1 Outputs
  1.43.2 Inputs
  1.43.3 Description
 1.44 CLIP_RASTER_VORONOI
  1.44.1 Outputs
  1.44.2 Inputs
  1.44.3 Description
 1.45 VECTORIZED_VORONOI
  1.45.1 Outputs
  1.45.2 Inputs
  1.45.3 Description
 1.46 INTEGER_LAW
  1.46.1 Outputs
  1.46.2 Inputs
  1.46.3 Description
 1.47 REAL_CONSTANT_LAW
  1.47.1 Outputs
  1.47.2 Inputs
  1.47.3 Description
 1.48 REAL_UNIFORM_LAW
  1.48.1 Outputs
  1.48.2 Inputs
  1.48.3 Description
 1.49 REAL_NORMAL_LAW
  1.49.1 Outputs
  1.49.2 Inputs
  1.49.3 Description
 1.50 COLOR_CONSTANT_LAW
  1.50.1 Outputs
  1.50.2 Inputs
  1.50.3 Description
 1.51 COLOR_RAINBOW
  1.51.1 Outputs
  1.51.2 Description
 1.52 COLOR_RGB_LAW
  1.52.1 Outputs
  1.52.2 Inputs
  1.52.3 Description
 1.53 COLOR_RGBA_LAW
  1.53.1 Outputs
  1.53.2 Inputs
  1.53.3 Description
 1.54 DISPLAY
  1.54.1 Outputs
  1.54.2 Inputs
  1.54.3 Description
 1.55 SHOW_DISTRIB
  1.55.1 Outputs
  1.55.2 Inputs
  1.55.3 Description
 1.56 SHOW_DENSITY_MAP
  1.56.1 Outputs
  1.56.2 Inputs
  1.56.3 Description
 1.57 SHOW_RASTER_VORONOI
  1.57.1 Outputs
  1.57.2 Inputs
  1.57.3 Description
 1.58 SHOW_INT
  1.58.1 Outputs
  1.58.2 Inputs
  1.58.3 Description
 1.59 PRINT
  1.59.1 Outputs
  1.59.2 Inputs
  1.59.3 Description
 1.60 PRINT_DISTRIB_ON_MASK
  1.60.1 Outputs
  1.60.2 Inputs
  1.60.3 Description
 1.61 PRINT_DENSITY_MAP
  1.61.1 Outputs
  1.61.2 Inputs
  1.61.3 Description
 1.62 PRINT_RASTER_VORONOI
  1.62.1 Outputs
  1.62.2 Inputs
  1.62.3 Description
 1.63 STOP
  1.63.1 Outputs
  1.63.2 Description
Grammar of the VEAD language

Chapter 1
Operators of the VEAD language

1.1 CIRCLE_SET

1.1.1 Outputs

1.1.2 Inputs

1.1.3 Description

This operator creates a set of shapes (circles) to be distributed, with their corresponding colors. Since the shapes are circles, the initial orientation does not affect them and is set to 0. The motivation for such an operator is to control accurately the size of the elements before distributing them. Consequently, this set of sizes will be a constraint for the distribution. It can be defined through the creation of a law, which allows great diversity for the obtained size sets.

1.2 OUTPUT_SIZE

1.2.1 Outputs

1.2.2 Inputs

1.2.3 Description

Sets the size of the output image.

1.3 UNIFORM_INITIAL_DISTRIBUTION_STRATEGY

1.3.1 Outputs

1.3.2 Description

Returns an initial distribution strategy having an uniform distribution property.

1.4 HALTON_INITIAL_DISTRIBUTION_STRATEGY

1.4.1 Outputs

1.4.2 Inputs

1.4.3 Description

Sets the initial distribution as being placed with a Halton pseudo-random sequence.

1.5 DART_INITIAL_DISTRIBUTION_STRATEGY

1.5.1 Outputs

1.5.2 Inputs

1.5.3 Description

Sets an initial distribution as being placed with the dart throwing algorithm. The dart algorithm is density-aware, the density function is given as an argument.

1.6 INITIAL_DISTRIBUTION

1.6.1 Outputs

1.6.2 Inputs

1.6.3 Description

Creates an element arrangement according to a given distribution strategy.

1.7 DART_HATCHING

1.7.1 Outputs

1.7.2 Inputs

1.7.3 Description

Returns a arrangement of strokes, according to the given density map and orientation map.

1.8 GEO_EDGES_FROM_SVG

1.8.1 Outputs

1.8.2 Inputs

1.8.3 Description

Returns an arrangement of strokes drawn in a SVG file.

1.9 LLOYD_DISTRIBUTION

1.9.1 Outputs

1.9.2 Inputs

1.9.3 Description

Computes and stores all the Lloyd algorithm’s iterations in an array of element arrangements, starting from the given initial arrangement. The stop criteria of Lloyd’s algorithm is based on the maximum movement distance of an element in one iteration. When this value is under max_depl, the algorithm stops.

1.10 CENTER_LLOYD_DISTRIBUTION

1.10.1 Outputs

1.10.2 Inputs

1.10.3 Description

Same as LLOYD_DISTRIBUTION, but the Voronoi diagrams are drawn only from the center of the elements instead of their complete shapes.

1.11 ORIENTED_DISTRIBUTION

1.11.1 Outputs

1.11.2 Inputs

1.11.3 Description

Computes and stores all iterations of an interpolation between the given initial arrangement and the same arrangement whose elements are oriented according to the given orientation map.

1.12 JITTER_DISTRIBUTION

1.12.1 Outputs

1.12.2 Inputs

1.12.3 Description

Computes and stores all nbre_iterations iterations of a jittering algorithm from the given initial arrangement.

1.13 INTERP_DISTRIBUTION

1.13.1 Outputs

1.13.2 Inputs

1.13.3 Description

The given starting and ending arrangements having the same element set, this operator computes and stores all iteration of an interpolation of the position of each element from one arrangement to the other.

1.14 DILATED_DISTRIBS

1.14.1 Outputs

1.14.2 Inputs

1.14.3 Description

Computes and stores all iterations of a Raku effect algorithm, which interpolates the shapes of the elements into the shapes of their associated Voronoi cells.

1.15 LAST_FROM_DISTRIBUTION

1.15.1 Outputs

1.15.2 Inputs

1.15.3 Description

Returns the last arrangement from an array of element arrangements.

1.16 SELECT_PERCENT_FROM_DISTRIBUTION

1.16.1 Outputs

Distribution distribution

1.16.2 Inputs

1.16.3 Description

N being the length of the input array, this operator returns the arrangement at position N percent{100.

1.17 GEO_DART

1.17.1 Outputs

1.17.2 Inputs

1.17.3 Description

A test operator for cartographic purposes. It returns a distribution of strokes from a given DEM.

1.18 UNION_DISTRIB

1.18.1 Outputs

1.18.2 Inputs

1.18.3 Description

Return the union of the two input arrangements.

1.19 DART_FILL

1.19.1 Outputs

1.19.2 Inputs

1.19.3 Description

Apply the dart filling algorithm presented in the report. The algorithm applies consecutive scale adaptation for a better fill, and apply a polygon outlining technique to put a minimum distance between the elements. An acceleration grid data structure is used to check the intersections in constant time.

1.20 POINT_SET

1.20.1 Outputs

1.20.2 Inputs

1.20.3 Description

Return a set of nb_points points.

1.21 UNION_SET

1.21.1 Outputs

1.21.2 Inputs

1.21.3 Description

Returns the union of the two input groups of elements.

1.22 CIRCLE_SET

1.22.1 Outputs

1.22.2 Inputs

1.22.3 Description

Creates a set of nb_circles circle-shaped elements.

1.23 ELLIPSE_SET

1.23.1 Outputs

1.23.2 Inputs

1.23.3 Description

Creates a set of nb_ellpises ellipse-shaped elements.

1.24 FILE_SHAPE

1.24.1 Outputs

1.24.2 Inputs

1.24.3 Description

Returns a set of nb_shapes elements whose shape is drawn in the input SVG file.

1.25 FILE_DENSITY_MAP

1.25.1 Outputs

1.25.2 Inputs

1.25.3 Description

Import the input gray-levels image file and converts its values into a discrete density function. Darker levels are considered as lower values.

1.26 UNIFORM_DENSITY_MAP

1.26.1 Outputs

1.26.2 Description

Returns a density function whose unique output value is 1.

1.27 POINT_GRADATION_DENSITY_MAP

1.27.1 Outputs

1.27.2 Inputs

1.27.3 Description

Returns a continuous density function whose values are maximum near the given point and that decrease exponentially with the distance from this point.

1.28 ACCUMULATION_DENSITY_FROM_SLOPE

1.28.1 Outputs

1.28.2 Inputs

1.28.3 Description

Test operator for cartographic purposes. Simulates the density of rocks in a scree slope from a given DEM.

1.29 GEO_DENSITY_FROM_ASPECT

1.29.1 Outputs

1.29.2 Inputs

1.29.3 Description

Test operator for cartographic purposes. Render the cartographic hatching density by simulating a pseudo-hatching from the slopes orientation given in the input orientation map.

1.30 GEO_DENSITY_FROM_EDGES

1.30.1 Outputs

1.30.2 Inputs

1.30.3 Description

Returns a more advanced density map for cartographic style imitation than the one in GEO_DENSITY_FROM_ASPECT. The edges of the mountains are taken into account, qnd the density is piecewise constant, its values depending on the distance with the nearest edge.

1.31 TEST_HEIGHT_MAP

1.31.1 Outputs

1.31.2 Description

Test operator for cartographic purposes. Creates a pseudo-DEM whose properties are already known, in order to test the other operators working on DEM.

1.32 FILE_HEIGHT_MAP

1.32.1 Outputs

1.32.2 Inputs

1.32.3 Description

Imports a DEM file to create a DEM datastructure in the interpreter.

1.33 FILE_MASK_MAP

1.33.1 Outputs

1.33.2 Inputs

1.33.3 Description

Takes a colored image file (no alpha channel) segmented by the colors. Each colored area is considered as a mask.

1.34 COLOR_MASK

1.34.1 Outputs

1.34.2 Inputs

1.34.3 Description

Select one of the colored masks in a mask map.

1.35 ANCHORED_ORIENTATION_MAP

1.35.1 Outputs

1.35.2 Description

Test operator used to test the formulas in SVGFILE_ORIENTATION_MAP.

1.36 SVGFILE_ORIENTATION_MAP

1.36.1 Outputs

1.36.2 Inputs

1.36.3 Description

Imports a SVG file containing influence curves, and creates a continuous orientation vector function. The function interpolates the tangent lines of the influence curves.

1.37 SCALED_ORIENTATION_MAP

1.37.1 Outputs

1.37.2 Inputs

1.37.3 Description

Allow the user to scale the definition domain of an orientation function.

1.38 FILE_ORIENTATION_MAP

1.38.1 Outputs

1.38.2 Inputs

1.38.3 Description

Imports a gray levels image file and consider the gray levels as angle values scaled into 0,255. Returns the corresponding orientation function.

1.39 GEO_TESTASPECT_FROM_EDGES

1.39.1 Outputs

1.39.2 Inputs

1.39.3 Description

Test operator for cartographic purposes. Creates fake slope orientation starting from drawn edges. The slope orientations are coherent with the position and direction of the edges.

1.40 RANDOM_ORIENTATION_MAP

1.40.1 Outputs

1.40.2 Description

Creates an orientation function which returns random values.

1.41 UNIFORM_ORIENTATION_MAP

1.41.1 Outputs

1.41.2 Inputs

1.41.3 Description

Creates an orientation function which returns always the same value.

1.42 ADD_RANDOM_ORIENTATION

1.42.1 Outputs

1.42.2 Inputs

1.42.3 Description

Adds a probabilistic law to a given orientation function. It allows the user to add some noise in an orientation field.

1.43 RASTERIZED_VORONOI

1.43.1 Outputs

1.43.2 Inputs

1.43.3 Description

Computes the Voronoi diagram associated to a given element arrangement, using the Havoc3D library.

1.44 CLIP_RASTER_VORONOI

1.44.1 Outputs

1.44.2 Inputs

1.44.3 Description

Removes the areas of a given rasterized Voronoi diagram in which the values of the given density map are zeros.

1.45 VECTORIZED_VORONOI

1.45.1 Outputs

1.45.2 Inputs

1.45.3 Description

Computes a contour detection algorithm to a given rasterized Voronoi diagram, using the OpenCV2 library. Returns the polygons associated to the raster cells.

1.46 INTEGER_LAW

1.46.1 Outputs

1.46.2 Inputs

1.46.3 Description

Returns an integer probabilistic law that gives the floor values of the input real probabilistic law.

1.47 REAL_CONSTANT_LAW

1.47.1 Outputs

1.47.2 Inputs

1.47.3 Description

Returns a constant real probabilistic law.

1.48 REAL_UNIFORM_LAW

1.48.1 Outputs

1.48.2 Inputs

1.48.3 Description

Returns a uniform real probabilistic law.

1.49 REAL_NORMAL_LAW

1.49.1 Outputs

1.49.2 Inputs

1.49.3 Description

Returns a normal real probabilistic law.

1.50 COLOR_CONSTANT_LAW

1.50.1 Outputs

1.50.2 Inputs

1.50.3 Description

Return a probabilistic law whose values are in the RGB color space. The returned value is always the same.

1.51 COLOR_RAINBOW

1.51.1 Outputs

1.51.2 Description

Return a probabilistic law whose values are in the RGB color space. The returned values are associated with a pseudo-random sequence.

1.52 COLOR_RGB_LAW

1.52.1 Outputs

1.52.2 Inputs

1.52.3 Description

Return a probabilistic law whose values are in the RGB color space. The returned values are associated to three real laws.

1.53 COLOR_RGBA_LAW

1.53.1 Outputs

1.53.2 Inputs

1.53.3 Description

Same as COLOR_RGB_LAW, but with a fourth real law for the alpha channel.

1.54 DISPLAY

1.54.1 Outputs

1.54.2 Inputs

1.54.3 Description

Displays an array of element arrangements in a special interface allowing the user to explore the array using a slider.

1.55 SHOW_DISTRIB

1.55.1 Outputs

1.55.2 Inputs

1.55.3 Description

Shows an element arrangement using a Qt widget.

1.56 SHOW_DENSITY_MAP

1.56.1 Outputs

1.56.2 Inputs

1.56.3 Description

Shows a density function using a Qt widget.

1.57 SHOW_RASTER_VORONOI

1.57.1 Outputs

1.57.2 Inputs

1.57.3 Description

Shows a raster Voronoi diagram using a Qt widget.

1.58 SHOW_INT

1.58.1 Outputs

1.58.2 Inputs

1.58.3 Description

Test operator. Shows the value of an integer literal in a console.

1.59 PRINT

1.59.1 Outputs

1.59.2 Inputs

1.59.3 Description

Prints an element arrangement in a raster image file using the QT4 renderer.

1.60 PRINT_DISTRIB_ON_MASK

1.60.1 Outputs

1.60.2 Inputs

1.60.3 Description

Same as PRINT, with several mask printing options.

1.61 PRINT_DENSITY_MAP

1.61.1 Outputs

1.61.2 Inputs

1.61.3 Description

Prints a density function in a raster image file.

1.62 PRINT_RASTER_VORONOI

1.62.1 Outputs

1.62.2 Inputs

1.62.3 Description

Prints a Voronoi diagram in a raster image file.

1.63 STOP

1.63.1 Outputs

1.63.2 Description

Stops the execution of the program, and displays a widget waiting for the signal of the user to continue.

Chapter 2
Grammar of the VEAD language

grammar Dst;  
 
options  
{  
    output=AST;  
    language = C;  
 
    // If generating an AST (output=AST; option) or specifying a tree walker then  
    // also add the following line  
    //  
 
    // Note that in the C implementation, all implementations of trees and  
    // adaptors pass around pANTLR3_BASE_TREE, which contains a super pointer  
    // to your own implementation of a tree node and tree and so on. Hence  
    // the node type is ALWAYS pANTLR3_BASE_TREE and there is no need to define  
    // the type (the definition is silently ignored if you leave it there)  
    //  
 
    ASTLabelType=pANTLR3_BASE_TREE;  
}  
 
tokens  
{  
    // root of the AST  
    PROGRAM;  
    // literals  
    INT_LIT;  
    REAL_LIT;  
    STRING_LIT;  
    COLOR_LIT;  
    BOOLEAN_LIT;  
    // OBSOLETE AST nodes related to declarations  
    // OBSOLETE VARIABLE;  
    // AST nodes related to definitions  
        OUTPUT_SIZE;  
    UNIFORM_INITIAL_DISTRIBUTION_STRATEGY;  
    HALTON_INITIAL_DISTRIBUTION_STRATEGY;  
    DART_INITIAL_DISTRIBUTION_STRATEGY;  
    // Définitions de distributions: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
        INITIAL_DISTRIBUTION;  
    DART_HATCHING;  
    GEO_EDGES_FROM_SVG;                     // 512 FREE  
    LLOYD_DISTRIBUTION;  
    CENTER_LLOYD_DISTRIBUTION;  
    ORIENTED_DISTRIBUTION;  
    JITTER_DISTRIBUTION;                    // NON IMPLÉMENTÉ  
    INTERP_DISTRIBUTION;                    // NON IMPLÉMENTÉ  
    DILATED_DISTRIBS;  
    LAST_FROM_DISTRIBUTION;                 // 512 FREE  
    SELECT_PERCENT_FROM_DISTRIBUTION;       // 512 FREE  
    GEO_DART;                               // ????????  
    UNION_DISTRIB;                          // 512 FREE  
    DART_FILL;                              // 512 FREE  
    ADD_DART;                               // 512_FREE  
    EMPTY_DISTRIB;                          // 512_FREE  
    // Définitions d’element_sets: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    POINT_SET;                              // NON IMPLÉMENTÉ  
        CIRCLE_SET;                             // 512 FREE  
        ELLIPSE_SET;                            // 512 FREE  
        UNION_SET;                              // 512 FREE  
        FILE_SHAPE;                             // 512 FREE  
    // Définitions de maps de densité: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
        FILE_DENSITY_MAP;  
    UNIFORM_DENSITY_MAP;  
    POINT_GRADATION_DENSITY_MAP;  
    ACCUMULATION_DENSITY_FROM_SLOPE;  
    GEO_DENSITY_FROM_ASPECT;  
    GEO_DENSITY_FROM_EDGES;  
    // Définitions de maps de hauteur: (test cartographie) vvvvvvvvvvvvvvvvvvvvvvvv  
    TEST_HEIGHT_MAP;  
    FILE_HEIGHT_MAP;  
    // Définitions de masques et maps de masques: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    FILE_MASK_MAP;                          // 512 FREE  
    COLOR_MASK;                             // 512 FREE  
    // Définitions de maps d’orientation: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    ANCHORED_ORIENTATION_MAP;               // TEST  
    SVGFILE_ORIENTATION_MAP;                // 512 FREE  
    SCALED_ORIENTATION_MAP;                 // 512 FREE  
    FILE_ORIENTATION_MAP;  
    GEO_TESTASPECT_FROM_EDGES;  
    RANDOM_ORIENTATION_MAP;                 // 512 FREE  
    UNIFORM_ORIENTATION_MAP;                // 512 FREE  
    ADD_RANDOM_ORIENTATION;                 // 512 FREE  
    // Définitions de maps de scale: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    FILE_SCALE_MAP;  
    // Définitions de Diagrammes de Voronoï: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    RASTERIZED_VORONOI;  
    CLIP_RASTER_VORONOI;  
    VECTORIZED_VORONOI;  
    // Définitions de lois: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
        INTEGER_LAW;  
        REAL_CONSTANT_LAW;                      // 512 FREE  
        REAL_UNIFORM_LAW;                       // 512 FREE  
        REAL_NORMAL_LAW;                        // 512 FREE  
        COLOR_CONSTANT_LAW;                     // 512 FREE  
    // COLOR_BY_INDEX_LAW;  
    COLOR_RAINBOW;                          // 512 FREE  
        COLOR_RGB_LAW;                          // 512 FREE  
        COLOR_RGBA_LAW;                         // 512 FREE  
    // Actions sans valeur de sortie: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  
    DISPLAY;  
    SHOW_DISTRIB;  
    SHOW_DENSITY_MAP;  
    SHOW_RASTER_VORONOI;  
    SHOW_INT;                               // 512 FREE  
    PRINT_RASTER_VORONOI;  
    PRINT_DENSITY_MAP;  
    PRINT;  
    PRINT_DISTRIB_ON_MASK;                  // 512 FREE  
    STOP;                                   // 512 FREE  
}  
 
program  
    : ’BEGIN’ statement_list ’END’  
        -> ^(PROGRAM statement_list);  
 
statement_list  
    :  (statement ’;’! )* ;  
 
statement  
    : definition ;  
 
BOOLEAN : ’TRUE’ | ’FALSE’;  
 
definition  
    : initial_distribution_strategy_definition  
    | distribution_definition  
    | point_set_definition  
    | element_set_definition  
    | integer_law_definition  
    | real_law_definition  
    | color_law_definition  
    | display_definition  
    | output_size_definition  
    | density_map_definition  
    | height_map_definition  
    | mask_map_definition  
    | mask_definition  
    | orientation_map_definition  
    | scale_map_definition  
    | rasterized_voronoi_definition  
    | vectorized_voronoi_definition  
    | lit_definition  
    | stop ;  
 
 
name : ID;  
 
lit_definition  
    :  name ’=’ ’INT_LIT’ ’(’ int_lit ’)’  
        -> ^(INT_LIT name int_lit)  
    |  name ’=’ ’REAL_LIT’ ’(’ real_lit ’)’  
        -> ^(REAL_LIT name real_lit)  
    |  name ’=’ ’STRING_LIT’ ’(’ string_lit ’)’  
        -> ^(STRING_LIT name string_lit)  
    |  name ’=’ ’BOOLEAN_LIT’ ’(’ boolean_lit ’)’  
        -> ^(BOOLEAN_LIT name boolean_lit)  
    |  name ’=’ ’COLOR_LIT’ ’(’ color_lit ’)’  
        -> ^(COLOR_LIT name color_lit) ;  
 
 
int_lit : INT;  
real_lit : REAL;  
boolean_lit : BOOLEAN;  
string_lit : STRING;  
color_lit : PREDEFINED_COLOR;  
 
density_map_definition  
    : name ’=’  ’FILE_DENSITY_MAP’ ’(’ dm_filename ’)’  
        -> ^(FILE_DENSITY_MAP name dm_filename)  
    | name ’=’  ’UNIFORM_DENSITY_MAP’  
        -> ^(UNIFORM_DENSITY_MAP name)  
    | name ’=’  ’POINT_GRADATION_DENSITY_MAP’ ’(’ gradation_center_x  
’,’ gradation_center_y ’,’ gradation_length ’)’  
        -> ^(POINT_GRADATION_DENSITY_MAP name gradation_center_x  
gradation_center_y gradation_length)  
    | name ’=’ ’ACCUMULATION_DENSITY_FROM_SLOPE’ ’(’ slope_file ’)’  
        -> ^(ACCUMULATION_DENSITY_FROM_SLOPE name slope_file)  
    | name ’=’ ’GEO_DENSITY_FROM_ASPECT’ ’(’ orientmap_name ’,’  
density_min ’,’ density_max ’,’ direction_to_light ’)’  
        -> ^(GEO_DENSITY_FROM_ASPECT name orientmap_name density_min  
density_max direction_to_light)  
    | name ’=’ ’GEO_DENSITY_FROM_EDGES’ ’(’ orientmap_name ’,’  
rastervoro_name ’,’ distrib_name ’)’  
        -> ^(GEO_DENSITY_FROM_EDGES name orientmap_name  
rastervoro_name distrib_name);  
 
dm_filename : ID;  
gradation_center_x : ID;  
gradation_center_y : ID;  
gradation_length   : ID;  
slope_file  : ID;  
orientmap_name : ID;  
density_min : ID;  
density_max : ID;  
direction_to_light : ID;  
rastervoro_name : ID;  
 
height_map_definition  
    : name ’=’ ’TEST_HEIGHT_MAP’  
        -> ^(TEST_HEIGHT_MAP name)  
    | name ’=’ ’FILE_HEIGHT_MAP’ ’(’ height_file_name ’)’  
        -> ^(FILE_HEIGHT_MAP name height_file_name);  
 
height_file_name : ID;  
 
mask_map_definition  
    : name ’=’ ’FILE_MASK_MAP’ ’(’ filename ’,’ scale_name ’)’  
        -> ^(FILE_MASK_MAP name filename scale_name);  
 
scale_name : ID;  
 
mask_definition  
    : name ’=’ ’COLOR_MASK’ ’(’ mask_map_name ’,’ int_name ’)’  
        -> ^(COLOR_MASK name mask_map_name int_name);  
 
mask_map_name : ID;  
 
orientation_map_definition  
    : name ’=’ ’ANCHORED_ORIENTATION_MAP’  
        -> ^(ANCHORED_ORIENTATION_MAP name) // TODO à conserver ?  
utilisee pour debug actuellement  
    | name ’=’ ’SVGFILE_ORIENTATION_MAP’ ’(’ svg_ori_filename ’,’  
strength ’,’  length ’,’ smoothness’)’  
        -> ^(SVGFILE_ORIENTATION_MAP name svg_ori_filename strength  
length smoothness)  
    | name ’=’ ’SCALED_ORIENTATION_MAP’ ’(’ base_orientmap_name ’,’  
scale_name ’)’  
        -> ^(SCALED_ORIENTATION_MAP name base_orientmap_name scale_name)  
    | name ’=’ ’FILE_ORIENTATION_MAP’ ’(’ filename ’)’  
        -> ^(FILE_ORIENTATION_MAP name filename)  
    | name ’=’ ’GEO_TESTASPECT_FROM_EDGES’ ’(’ distrib_name ’,’  
rasterized_voronoi_name ’)’  
        -> ^(GEO_TESTASPECT_FROM_EDGES name distrib_name  
rasterized_voronoi_name)  
    | name ’=’ ’RANDOM_ORIENTATION_MAP’  
        -> ^(RANDOM_ORIENTATION_MAP name)  
    | name ’=’ ’UNIFORM_ORIENTATION_MAP’ ’(’ angle_name ’)’  
        -> ^(UNIFORM_ORIENTATION_MAP name angle_name)  
    | name ’=’ ’ADD_RANDOM_ORIENTATION’ ’(’ orientmap_name ’,’  
angle_law_name ’)’  
        -> ^(ADD_RANDOM_ORIENTATION name orientmap_name angle_law_name);  
 
svg_ori_filename : ID;  
strength : ID;  
length : ID;  
smoothness : ID;  
filename : ID;  
angle_name : ID;  
angle_law_name : ID;  
base_orientmap_name : ID;  
 
scale_map_definition  
    : name ’=’ ’FILE_SCALE_MAP’ ’(’ filename ’,’ scale_min ’,’ scale_max ’)’  
        -> ^(FILE_SCALE_MAP name filename scale_min scale_max);  
 
scale_min : ID;  
scale_max : ID;  
 
rasterized_voronoi_definition  
    : name ’=’ ’RASTERIZED_VORONOI’ ’(’ distrib_name ’)’  
        -> ^(RASTERIZED_VORONOI name distrib_name)  
    | name ’=’ ’CLIP_RASTER_VORONOI’ ’(’ rasterized_voronoi_name ’,’  
density_map_name ’)’  
        -> ^(CLIP_RASTER_VORONOI name rasterized_voronoi_name density_map_name);  
 
vectorized_voronoi_definition  
    : name ’=’ ’VECTORIZED_VORONOI’ ’(’ rasterized_voronoi_name ’)’  
        -> ^(VECTORIZED_VORONOI name rasterized_voronoi_name);  
 
rasterized_voronoi_name : ID;  
 
output_size_definition  
    : name ’=’  ’OUTPUT_SIZE’ ’(’  width ’,’  height ’)’  
        -> ^(OUTPUT_SIZE name width height) ;  
 
width   :       ID;  
height  :       ID;  
 
 
// TODO nb_trial doit etre sup ou egal à 1  
initial_distribution_strategy_definition  
    : name ’=’ ’UNIFORM’  
        -> ^(UNIFORM_INITIAL_DISTRIBUTION_STRATEGY name)  
    | name ’=’ ’HALTON’ ’(’ prime1 ’,’ prime2 ’)’  
        -> ^(HALTON_INITIAL_DISTRIBUTION_STRATEGY name prime1 prime2)  
    | name ’=’ ’DART’ ’(’ nb_trials ’,’ dart_density_map ’)’  
        -> ^(DART_INITIAL_DISTRIBUTION_STRATEGY name nb_trials  
dart_density_map)  
    | name ’=’ ’DART_HATCHING’ ’(’ dmap_name ’,’ orientmap_name ’)’  
        -> ^(DART_HATCHING name dmap_name orientmap_name);  
 
prime1 : ID;  
prime2 : ID;  
nb_trials : ID;  
dart_density_map : ID;  
dmap_name : ID;  
 
// TODO semantic rule : the distribution should have the same number  
of points,  
// and these points should be in the same order  
distribution_definition  
    : name ’=’ ’DISTRIBUTE’ ’(’ set_name ’,’  
initial_distribution_strategy_name ’)’  
        ->  ^(INITIAL_DISTRIBUTION name set_name  
initial_distribution_strategy_name)  
    | name ’=’ ’GEO_EDGES_FROM_SVG’ ’(’ svg_filename ’,’ thickness ’)’  
        ->  ^(GEO_EDGES_FROM_SVG name svg_filename thickness)  
    | name ’=’ ’LLOYD’ ’(’ distribution_name ’,’ max_depl  
’,’change_orientation ’,’ density_map_name ’)’  
        ->  ^(LLOYD_DISTRIBUTION name distribution_name max_depl  
change_orientation density_map_name)  
    | name ’=’ ’CENTER_LLOYD’ ’(’ distribution_name ’)’  
        ->  ^(CENTER_LLOYD_DISTRIBUTION name distribution_name)  
    | name ’=’ ’ORIENT’ ’(’ distribution_name ’,’ orientation_map_name ’)’  
        ->  ^(ORIENTED_DISTRIBUTION name distribution_name orientation_map_name)  
    | name ’=’ ’JITTER’ ’(’ distribution_name ’,’ nb_iterations ’)’  
        ->  ^(JITTER_DISTRIBUTION name distribution_name nb_iterations)  
    | name ’=’ ’INTERP’ ’(’ start_distribution_name ’,’  
end_distribution_name ’,’nb_steps ’)’  
        ->  ^(INTERP_DISTRIBUTION name start_distribution_name  
end_distribution_name nb_steps)  
    | name ’=’ ’DILATED_DISTRIBS’ ’(’ distrib_name ’,’  
vectorized_voronoi_name ’)’  
        -> ^(DILATED_DISTRIBS name distrib_name vectorized_voronoi_name)  
    | name ’=’ ’LAST_FROM’ ’(’ distribution_array_name ’)’  
        -> ^(LAST_FROM_DISTRIBUTION name distribution_array_name)  
    | name ’=’ ’SELECT_PERCENT_FROM’ ’(’ distribution_array_name ’,’  
percent_name ’)’  
        -> ^(SELECT_PERCENT_FROM_DISTRIBUTION name  
distribution_array_name percent_name)  
    | name ’=’ ’GEO_DART’ ’(’ height_map_name ’)’  
        -> ^(GEO_DART name height_map_name)  
    | name ’=’ ’UNION_DISTRIB’ ’(’ distrib_name_1 ’,’ distrib_name_2 ’)’  
        -> ^(UNION_DISTRIB name distrib_name_1 distrib_name_2)  
    | name ’=’ ’DART_FILL’ ’(’ file_shape_name ’,’ mask_name ’,’  
orientmap_name ’,’ scale_start_name ’,’ scale_end_name ’,’  
nb_scales_name ’,’ nb_essais_par_scale_name ’,’ standard_elt_size_name  
’,’ dist_inter_elements_name ’)’  
        -> ^(DART_FILL name file_shape_name mask_name orientmap_name  
scale_start_name scale_end_name nb_scales_name  
nb_essais_par_scale_name standard_elt_size_name  
dist_inter_elements_name)  
    | name ’=’ ’ADD_DART’ ’(’ distrib_name ’,’ file_shape_name ’,’  
dmap_name ’,’ orientmap_name ’,’ scale_map_name ’,’ nb_essais_max ’,’  
standard_elt_size_name ’,’ dist_inter_elements_name ’)’  
        -> ^(ADD_DART name distrib_name file_shape_name dmap_name  
orientmap_name scale_map_name nb_essais_max standard_elt_size_name  
dist_inter_elements_name)  
    | name ’=’ ’EMPTY_DISTRIB’  
        -> ^(EMPTY_DISTRIB name);  
 
percent_name : ID;  
set_name :      ID ;  
initial_distribution_strategy_name : ID ;  
max_depl : ID;  
change_orientation : ID;  
nb_iterations :  ID;  
distribution_name : ID ;  
distribution_array_name : ID ;  
density_map_name : ID ;  
orientation_map_name : ID ;  
start_distribution_name : distribution_name;  
end_distribution_name : distribution_name;  
nb_steps : ID;  
height_map_name : ID;  
thickness : ID;  
distrib_name_1 : ID;  
distrib_name_2 : ID;  
distrib_name : ID;  
vectorized_voronoi_name : ID;  
file_shape_name : ID;  
mask_name : ID;  
scale_start_name : ID;  
scale_end_name : ID;  
nb_scales_name : ID;  
nb_essais_par_scale_name: ID;  
standard_elt_size_name: ID;  
dist_inter_elements_name : ID;  
nb_essais_max : ID;  
scale_map_name : ID;  
 
point_set_definition  
    : name ’=’ ’POINTS’ ’(’ nb_points ’)’  
        -> ^(POINT_SET name nb_points);  
 
nb_points : ID;  
 
 
element_set_definition  
    : name ’=’ ’CIRCLE_SET’ ’(’ radius_law ’,’ color_law ’,’ nb_circles ’)’  
        -> ^(CIRCLE_SET name radius_law color_law nb_circles)  
    | name ’=’ ’ELLIPSE_SET’ ’(’ width_law ’,’ height_law ’,’  
rotation_law ’,’ color_law ’,’ nb_ellipses ’)’  
        -> ^(ELLIPSE_SET name width_law height_law rotation_law  
color_law nb_ellipses)  
    | name ’=’ ’UNION_SET’ ’(’ set1 ’,’ set2 ’)’  
        -> ^(UNION_SET name set1 set2)  
    |  name ’=’  ’FILE_SHAPE’ ’(’ svg_filename ’,’ nb_shapes ’)’  
        -> ^(FILE_SHAPE name svg_filename nb_shapes) ;  
 
set1 : ID;  
set2 : ID;  
radius_law : ID;  
color_law : ID;  
nb_circles : ID;  
width_law : ID;  
height_law : ID;  
rotation_law : ID;  
nb_ellipses : ID;  
svg_filename : ID;  
nb_shapes : ID;  
 
integer_law_definition  
    : name ’=’ ’INTEGER_LAW’ ’(’ real_law ’)’  
        -> ^(INTEGER_LAW name real_law) ;  
 
real_law : ID;  
 
 
 
real_law_definition  
    : name ’=’ ’REAL_CONSTANT_LAW’ ’(’  constant ’)’  
        -> ^(REAL_CONSTANT_LAW name constant)  
    | name ’=’ ’REAL_UNIFORM_LAW’ ’(’ min ’,’ max ’)’  
        -> ^(REAL_UNIFORM_LAW name min max)  
    | name ’=’ ’REAL_NORMAL_LAW’ ’(’  mean ’,’ std_dev ’)’  
        -> ^(REAL_NORMAL_LAW name mean std_dev) ;  
 
constant : ID;  
min : ID;  
max : ID;  
mean : ID;  
std_dev : ID;  
 
 
 
 
color_law_definition  
    : name ’=’ ’COLOR_CONSTANT_LAW’ ’(’ color ’)’  
        -> ^(COLOR_CONSTANT_LAW name color)  
    | name ’=’ ’COLOR_RAINBOW’  
        -> ^(COLOR_RAINBOW name)  
    | name ’=’ ’COLOR_RGB_LAW’ ’(’ r_real_law ’,’ g_real_law ’,’ b_real_law ’)’  
        -> ^(COLOR_RGB_LAW name r_real_law g_real_law b_real_law)  
    | name ’=’ ’COLOR_RGBA_LAW’ ’(’ r_real_law ’,’ g_real_law ’,’  
b_real_law ’,’ a_real_law ’)’  
        -> ^(COLOR_RGBA_LAW name r_real_law g_real_law b_real_law a_real_law) ;  
 
color : ID;  
 
integer_law : ID;  
 
r_real_law : real_law ;  
g_real_law : real_law ;  
b_real_law : real_law ;  
a_real_law : real_law ;  
 
 
display_definition  
    : name ’=’ ’DISPLAY’ ’(’ distribution_name ’)’  
        -> ^(DISPLAY name distribution_name)  
    | name ’=’ ’SHOW_DISTRIB’ ’(’ distribution_name ’)’  
        -> ^(SHOW_DISTRIB name distribution_name)  
    | name ’=’ ’SHOW_DENSITY_MAP’ ’(’ dmap_name ’)’  
        -> ^(SHOW_DENSITY_MAP name dmap_name)  
    | name ’=’ ’SHOW_RASTER_VORONOI’ ’(’ rasterized_voronoi_name ’)’  
        -> ^(SHOW_RASTER_VORONOI name rasterized_voronoi_name)  
    | name ’=’ ’SHOW_INT’ ’(’ int_name ’)’  
        -> ^(SHOW_INT name int_name)  
    | name ’=’ ’PRINT’ ’(’ distribution_name ’,’ print_filename ’)’  
        -> ^(PRINT name distribution_name print_filename)  
    | name ’=’ ’PRINT_RASTER_VORONOI’ ’(’ rastervoro_name ’,’ print_filename ’)’  
        -> ^(PRINT_RASTER_VORONOI name rastervoro_name print_filename)  
    | name ’=’ ’PRINT_DENSITY_MAP’ ’(’ dmap_name ’,’ print_filename ’)’  
        -> ^(PRINT_DENSITY_MAP name dmap_name print_filename)  
    | name ’=’ ’PRINT_DISTRIB_ON_MASK’ ’(’ print_filename ’,’  
distrib_name ’,’ mask_name ’)’  
        -> ^(PRINT_DISTRIB_ON_MASK name print_filename distrib_name mask_name);  
 
print_filename : ID;  
int_name : ID;  
 
stop : name ’=’ ’STOP’  
        -> ^(STOP name);  
 
PREDEFINED_COLOR  
    : ’WHITE’        // White (#ffffff)  
    | ’BLACK’    // Black (#000000)  
    | ’RED’              // Red (#ff0000)  
    | ’DARKRED’  // Dark red (#800000)  
    | ’GREEN’    // Green (#00ff00)  
    | ’DARKGREEN’        // Dark green (#008000)  
    | ’BLUE’     // Blue (#0000ff)  
    | ’DARKBLUE’         // Dark blue (#000080)  
    | ’CYAN’     // Cyan (#00ffff)  
    | ’DARKCYAN’         // Dark cyan (#008080)  
    | ’MAGENTA’  // Magenta (#ff00ff)  
    | ’DARKMAGENTA’      // Dark magenta (#800080)  
    | ’YELLOW’   // Yellow (#ffff00)  
    | ’DARKYELLOW’       // Dark yellow (#808000)  
    | ’GRAY’     // Gray (#a0a0a4)  
    | ’DARKGRAY’         // Dark gray (#808080)  
    | ’LIGHTGRAY’;       // Light gray (#c0c0c0)  
 
ID  :   (’a’..’z’|’A’..’Z’)(’a’..’z’|’A’..’Z’|’0’..’9’|’_’)*;  
INT :   (’-’)? ’0’..’9’+ ;  
REAL :  (’-’)? ’0’..’9’+ ’.’  ’0’..’9’+;  
 
 
ML_COMMENT  
    :   ’/*’ (options {greedy=false;} : .)* ’*/’ {$channel=HIDDEN;}  
    ;  
 
NEWLINE:’\r’? ’\n’ {$channel = HIDDEN;} ;  
STRING  :        ’"’ (’a’..’z’|’A’..’Z’|’0’..’9’|’.’|’_’|’/’)+ ’"’;  
WS  :   (’ ’|’\t’)+ {$channel = HIDDEN;} ;