/*
 * Mesa 3-D graphics library
 * Version:  6.6
 *
 * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * \file slang_pp_version.syn
 * slang #version directive syntax
 * \author Michal Krol
 */

.syntax version_directive;

version_directive
	version_directive_1;
version_directive_1
	prior_optional_spaces .and optional_version_directive .and .true .emit $;

optional_version_directive
	version_directive_body .or .true .emit 10 .emit 1;

version_directive_body
	'#' .and optional_space .and "version" .and space .and version_number .and optional_space .and
	new_line;

version_number
	version_number_100 .or version_number_110 .or version_number_120;

version_number_100
	leading_zeroes .and "100" .emit 0 .emit 1;

version_number_110
	leading_zeroes .and "110" .emit 10 .emit 1;

version_number_120
	leading_zeroes .and "120" .emit 20 .emit 1;

leading_zeroes
	.loop zero;

zero
	'0';

space
    single_space .and .loop single_space;

optional_space
    .loop single_space;

single_space
    ' ' .or '\t';

prior_optional_spaces
	.loop prior_space;

prior_space
	c_style_comment_block .or cpp_style_comment_block .or space .or new_line;

c_style_comment_block
    '/' .and '*' .and c_style_comment_rest;

c_style_comment_rest
    .loop c_style_comment_char_no_star .and c_style_comment_rest_1;
c_style_comment_rest_1
    c_style_comment_end .or c_style_comment_rest_2;
c_style_comment_rest_2
    '*' .and c_style_comment_rest;

c_style_comment_char_no_star
    '\x2B'-'\xFF' .or '\x01'-'\x29';

c_style_comment_end
    '*' .and '/';

cpp_style_comment_block
    '/' .and '/' .and cpp_style_comment_block_1;
cpp_style_comment_block_1
    cpp_style_comment_block_2 .or cpp_style_comment_block_3;
cpp_style_comment_block_2
    .loop cpp_style_comment_char .and new_line;
cpp_style_comment_block_3
    .loop cpp_style_comment_char;

cpp_style_comment_char
    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';

new_line
    cr_lf .or lf_cr .or '\n' .or '\r';

cr_lf
    '\r' .and '\n';

lf_cr
	'\n' .and '\r';

.string __string_filter;

__string_filter
    .loop __identifier_char;

__identifier_char
    'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';

