#  Copyright (c) 1997-2006
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#----------------------------------------------------------------------------
#  $Project: polymake $$Id: regex.pl,v 1.5 2006/02/21 19:28:02 gawrilow Exp $

use namespaces;
use re 'eval';
package Poly;

# an identifier (alphanumeric, first character not a digit)
declare $id_re=qr{(?> (?!\d)\w+ )}x;

# a list of identifiers (separated by commas)
declare $ids_re=qr{(?> $id_re (?: \s*,\s* $id_re)* )}xo;

# hierarchical identifier (identifiers connected with dots)
declare $hier_id_re=qr{(?> (?!\d\.)[.\w]+ )}xo;

# a list of hierarchical identifiers (separated by commas)
declare $hier_ids_re=qr{(?> $hier_id_re (?: \s*,\s* $hier_id_re)* )}xo;

# a lone identifier
declare $id_only_re=qr{ ($id_re) \s*$ }xo;

# fully qualified name
declare $qual_id_re=qr{(?> $id_re (?: :: $id_re)* )}xo;

# a list of fully qualified names
declare $qual_ids_re=qr{(?> $qual_id_re (?: \s*,\s* $qual_id_re)* )}xo;

# unqualified name
declare $unqual_id_re=qr{(?<!::) (?<!\w) $id_re (?! :: )}xo;

declare $balanced_re;
$balanced_re=qr{ (?: (?> [^(\[{}\])]+ ) | (?<! \\ ) \\ [(\[{}\])] |
                     \( (??{ $balanced_re }) \) |
                     \[ (??{ $balanced_re }) \] |
                     \{ (??{ $balanced_re }) \}
                 )* }xo;

# variable assignment as full statement
declare $assignment_re=qr{ ([\$\@%] $qual_id_re) \s*= (?: [^\#\n]+; | .*\n (?: ^.*\n)*? ^ [^\#\n]+; ) }xom;

# a string literal
declare $quoted_re=qr{ (['"]) .*? (?<! \\) \1 }x;

# property type, possibly parameterized
declare $type_re;

# a list of types (separated by commas)
declare $types_re=qr{(?> (??{ $type_re }) (?: \s*,\s* (??{ $type_re }))* )}xo;

$type_re=qr{ $qual_id_re (?: \s*<\s* (?: $types_re )? \s*>\s* )? }xo;

# a lone type
declare $type_only_re=qr{ $type_re \s*$ }xo;

# a type parameter in a declaration
declare $type_param_re=qr{ $id_re (?: \s*=\s* $type_re )? }xo;

# a list of type parameters
declare $type_params_re=qr{(?> $type_param_re (?: \s*,\s* $type_param_re)* )}xo;

# function declaration with optional signature
declare $sub_re=qr{ ($id_re) \b (?: \s*\( ($balanced_re) \) )? }xo;

# overloaded function declaration with optional labels
declare $labeled_sub_re=qr{ (?:($hier_ids_re)\s*:\s*)? $sub_re }xo;

# filename (directory part stripped)
declare $filename_re=qr{ ([^/]+) $ }x;

# an empty line
declare $empty_line_re=qr{^ [ \t]* \n}xm;

# an empty line or separator (a line of hashes)
declare $empty_or_separator_line=qr{^ (?: [ \t]* | \#{2,} ) \n}xm;

# an empty line with possible comments
declare $nonsignificant_line_re=qr{^ [ \t]* (?:\#.*)? \n}xm;

# a line with some contents (like perl code)
declare $significant_line_re=qr{^ [ \t]* (?! $ | \#) }xm;
1;
