/*
 *  mknode.l from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  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.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
%start CPP LINE_EMBEDDED EMBEDDED TIME_PARAM PARAM_VALUE MENU_NAME IN_COMMENT
	/* add code here with TAB at start of each line */
%a 18000
%p 16000
%n 4000
%o 40000
%e 2000
%{
#undef yywrap
#include "mknodel.h"
#define BEG_SV(y) BEGIN y ; last_lex_state = y 
%}
%%
\/\*([^\*\n]|\*[^/\n])*\*\/	  ;  /* c style comments */
\/\*([^\*\n]|\*[^/\n])*\n		 { BEGIN IN_COMMENT ; LineNumber++ ;}
<IN_COMMENT>([^\*\n]|\*[^/\n])*(\n|\*\n)  {LineNumber++; }
<IN_COMMENT>([^\*\n]|\*[^/\n])*\*\/ { BEGIN last_lex_state; LineNumber++;}
<LINE_EMBEDDED>\n	{LineNumber++; EmbeddedLine();}
\n			LineNumber++ ; /* Skip newline */
\/\/.*\n		LineNumber++ ; /* C++ style comment */
<PARAM_VALUE,TIME_PARAM>\)		{ BEG_SV(CPP) ; BraceInit(); return ')';}
<PARAM_VALUE,TIME_PARAM>\{		{ BEG_SV(CPP); BraceInit(); LeftBrace() ;}
<MENU_NAME>\{				{BEG_SV(LINE_EMBEDDED); LeftBrace();}
<CPP,LINE_EMBEDDED,EMBEDDED>\{		LeftBrace();
<CPP>\}					if(RightBrace()) {
						BEG_SV(0);
						yylval.Text = CurrentText();
						return CPP_CODE ;
					}
<LINE_EMBEDDED>\}			if(RightBrace()) {
						BEG_SV(0);
						yylval.Text = CurrentText();
						return EMBEDDED_TEXT_LINE ;
					}
<EMBEDDED>\}				if(RightBrace()) {
						BEG_SV(0);
						yylval.Text = CurrentText();
						return EMBEDDED_TEXT ;
					}
<LINE_EMBEDDED,EMBEDDED>\$[a-zA-Z][a-zA-Z0-9_]*	AddEmbeddedName(yytext+1);
<LINE_EMBEDDED,EMBEDDED>\$\$[a-zA-Z][a-zA-Z0-9_]*  AddedText(yytext);
<LINE_EMBEDDED,EMBEDDED>[^\n\$\{\}\ \t][^\n\$\{\}\t]*[^\n\$\{\}\ \t] AddedText(yytext);
<LINE_EMBEDDED,EMBEDDED>[^\n\$\{\}\ \t]+	AddedText(yytext);
<LINE_EMBEDDED,EMBEDDED>\n[ \t]+		LineNumber++; // Skip space here
<LINE_EMBEDDED,EMBEDDED>[ \t]+ 			AddedText(" ");
<LINE_EMBEDDED,EMBEDDED>\{\}			AddedText(yytext);
<LINE_EMBEDDED,EMBEDDED>\$+			AddedText(yytext);
<CPP>^\#[^\n]\n					AddedText(yytext);
<CPP>[^\n\$\{\}]+				AddedText(yytext);
<MENU_NAME>[a-zA-Z][ a-zA-Z0-9_+]*[a-zA-Z0-9_+]	{
					yylval.Name = MakeWordString(yytext);
					return WORD_STRING ;}
^#[a-zA-Z_]+		return yylval.Terminal = GetIncludeType(yytext);
[ \t]+			;/* Skip white space BUT NOT IN EMBEDDED TEXT OR CODE */
[a-zA-Z][a-zA-Z0-9_]*		{LexReturn& Ret = FoundName(yytext,yylval);
					if (Ret.NewState) switch (Ret.NewState)
					{
				case BeginCpp:	BEG_SV(CPP); BraceInit(); break ;
 				case BeginParamValue:
						BEG_SV(PARAM_VALUE);
						break ;
 				case BeginTimeParam:
						BEG_SV(TIME_PARAM);
						break ;
 				case BeginMenuName:
						BEG_SV(MENU_NAME);
						BraceInit(); break ;
 				case BeginEmbedded:
						BEG_SV(EMBEDDED);
						BraceInit(); break ;
					}
				/*
				 *	cerr << "Returning " << Ret.Terminal <<
				 *	"\n" ;
 				 */
					return Ret.Terminal ;
				}
\<[^\n \t][^\n]*[^\n \t]\>	|
\<[^\n \t]\>			{
					yylval.String = MakeLitString(yytext);
					return ANGLE_VAL ;
				}
\"[^\n \t][^\n]*[^\n \t]\"	|
\"[^\n \t]\"			{
					yylval.String = MakeString(yytext);
					return STRING_VAL ;
				}
\'([^\\\n]|\\.)\'	{
						yylval.String=MakeLitString(yytext);
						return CHARACTER_VAL ;
					}
0[0-7]*				{
					yylval.Int = OctConvert(yytext);
					FoundInt(yylval.Int);
					return INTEGER_VAL ;
				}
[1-9][0-9]*			{
					yylval.Int = IntConvert(yytext);
					FoundInt(yylval.Int);
					return INTEGER_VAL ;
				}
0[xX][0-9a-fA-F]*		{	
					yylval.Int = HexConvert(yytext+2);
					FoundInt(yylval.Int);
					return INTEGER_VAL ;
				}
[0-9]*\.[0-9]+			|
[0-9]+\.[0-9]*			|
[0-9]*\.?[0-9]+[Ee][+-]?[0-9]+	|
[0-9]+\.[0-9]*[Ee][+-]?[0-9]+	{
					yylval.Dbl = MakeDouble(yytext);
					return DOUBLE_VAL ;
				}
"||"					return OR ;
"&&"					return AND ;
"=="					return EQU ;
"!="					return NEQ ;
"<="					return LEQ ;
">="					return GEQ ;
"<<"					return SHIFT_L ;
">>"					return SHIFT_R ;
"->"					return ARROW ;
"::"					return DOUBLE_COLON ;
\=					|
\-					|
\+					|
\&					|
\|					|
\%					|
\~					|
\!					|
\^					|
\/					|
\<					|
\>					|
\:					|
\?					|
\*					|
\[					|
\]					|
\)					|
\(					|
\,					|
\;					|
\{					return yytext[0] ;
\}					return yytext[0] ;
.					IllegalChar(yytext[0]);
