%{ /**************************************************************************** Copyright (C) 1987-2004 by Jeffery P. Hansen 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 of the License, or (at your option) any later version. 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 the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************/ #include #include #include #include "yybasic.h" #include "ycmalloc.h" #include "vgrammar.h" #ifndef YY_START #define YY_START YYSTATE #endif struct lex_keywordentry { char *Keyword; int Value; }; struct lex_keywordentry lex_verilog_words[] = { {"assign",ASSIGN}, {"endmodule",ENDMODULE}, {"inout",INOUT}, {"input",INPUT}, {"module",MODULE}, {"output",OUTPUT}, {"supply0",SUPPLY0}, {"supply1",SUPPLY1}, {"tran",TRAN}, {"wire",WIRE}, }; int lex_verilog_num = sizeof(lex_verilog_words)/sizeof(lex_verilog_words[0]); struct lex_keywordentry lex_anotate_words[] = { {"comment",COMMENT}, {"enddecls",ENDDECLS}, {"frame",FRAME}, {"interface",BDESC}, {"joint",JOINT}, {"property",PROPERTY}, {"root_module",ROOTMODULE}, {"script",SCRIPT}, {"version",VERSION}, }; int lex_anotate_num = sizeof(lex_anotate_words)/sizeof(lex_anotate_words[0]); struct lex_keywordentry lex_aoption_words[] = { {"/bd",BDPORTS}, {"/dp",DECPOS}, {"/end",COMEND}, {"/p",PORTS}, {"/r",ROT}, {"/sn",SHOWNAME}, {"/st",STATE}, {"/sz",SIZE}, {"/w",WPLACE}, }; int lex_aoption_num = sizeof(lex_aoption_words)/sizeof(lex_aoption_words[0]); struct lex_keywordentry lex_delay_words[] = { {"area",AREA}, {"break",BREAK}, {"case",CASE}, {"default",DEFAULT}, {"delay",DELAY}, {"else",ELSE}, {"if",IF}, {"power",POWER}, {"primitive",PRIMITIVE}, {"return",RETURN}, {"switch",SWITCH}, {"technology",TECHNOLOGY}, {"version",VERSION}, }; int lex_delay_num = sizeof(lex_delay_words)/sizeof(lex_delay_words[0]); static int yc_last_mode; int ycLiteral(char *Tok,struct lex_keywordentry *low,int len); int ycString(char *S); int ycLineNumber; const char *ycFileName; /* Start states: VR Verilog BC Block comment LC Line comment AC Annotation comment DD Delay definition DDP Delay definition parameter */ %} %start VR BC LC AC DD DDP VN white [ \t\r] num [0-9] hex [0-9A-Fa-f] lit1 [A-Za-z_] lit2 [A-Za-z0-9_] litddp [A-Za-z0-9_/*-] vnset [A-Za-z0-9.] %% "/*" { yc_last_mode = YY_START; BEGIN BC; } "*/" { BEGIN yc_last_mode; } . { } \n { ycLineNumber++; } "//" { yc_last_mode = YY_START; BEGIN LC; } \n { ycLineNumber++; BEGIN yc_last_mode; } . { } "//:" { yc_last_mode = YY_START; BEGIN AC; return ANOTATE; } \n { ycLineNumber++; BEGIN yc_last_mode; return ENDANOTATE; } ";" { return SEMI; } ":" { return COLON; } "," { return COMMA; } "." { return DOT; } "=" { return ASGN; } "/" { return SLASH; } "(" { return LPAREN; } ")" { return RPAREN; } "{" { return LBRACE; } "}" { return RBRACE; } "[" { return LBRACK; } "]" { return RBRACK; } "!" { return NOT; } "@" { return AT; } ">" { return GT; } "<" { return LT; }
"||" { return OR; }
"&&" { return AND; }
">=" { return GE; }
"<=" { return LE; }
"==" { return EQ; }
"!=" { return NE; }
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"**" { return POW; }
"/" { return DIV; } \"([^\\\"]*("\\\\"|"\\\"")*)*\" { return ycString(yytext); } {num}+"'h"{hex}+ { yylval.S = yc_strdup(yytext); return HEX; }
{num}+ { sscanf(yytext,"%d",&yylval.I); return NUMBER; } "-"?{num}+ { sscanf(yytext,"%d",&yylval.I); return NUMBER; } {litddp}+ { return ycLiteral(yytext,lex_delay_words,lex_delay_num); }
{lit1}{lit2}* { return ycLiteral(yytext,lex_delay_words,lex_delay_num); } {lit1}{lit2}* { return ycLiteral(yytext,lex_verilog_words,lex_verilog_num); } {lit1}{lit2}* { return ycLiteral(yytext,lex_anotate_words,lex_anotate_num); } "/"{lit1}{lit2}* { return ycLiteral(yytext,lex_aoption_words,lex_aoption_num); } {vnset}+ { yylval.S = yc_strdup(yytext); return VERNUM; } {white}+ { } "\n" { ycLineNumber++; } . { yyerror("Illegal character (%d) '%c'.\n",*yytext,*yytext); return BOGOCHAR; } %% int ycKeyCmp(const char *S1,const char *S2) { for (;*S1;S1++,S2++) { int C1 = islower(*S1) ? toupper(*S1) : *S1; int C2 = islower(*S2) ? toupper(*S2) : *S2; if (C1 != C2) return (C1 < C2) ? -1 : 1; } return *S2 ? -1 : 0; } int ycLookup(char *Tok,struct lex_keywordentry *low,int len) { struct lex_keywordentry *high = low+len-1; struct lex_keywordentry *K; while (low <= high) { K = low + (high-low)/2; switch (ycKeyCmp(K->Keyword,Tok)) { case 0 : return K->Value; case -1 : low = K + 1; break; case 1 : high = K - 1; break; } } return -1; } int ycIsKW(char *Tok) { if (ycLookup(Tok,lex_anotate_words,lex_anotate_num) >= 0) return 1; if (ycLookup(Tok,lex_verilog_words,lex_verilog_num) >= 0) return 1; return 0; } /* Parse a "literal-like" token. If it is in a keyword table, return the token for that keyword, otherwise treat it as a literal. */ int ycLiteral(char *Tok,struct lex_keywordentry *low,int len) { int t; if (!Tok) Tok = yytext; yylval.S = "???"; t = ycLookup(Tok,low,len); yylval.S = yc_strdup(Tok); return t >= 0 ? t : LITERAL; } int ycString(char *S) { S = yylval.S = yc_strdup(S+1); S[strlen(S)-1] = 0; for (;*S;S++) if (*S == '\\' && S[1]) { memmove(S,S+1,strlen(S+1)+1); S++; } return STRING; } void BeginVR() { BEGIN VR; } void BeginAC() { BEGIN AC; } void BeginLC() { BEGIN LC; } void BeginBC() { BEGIN BC; } void BeginDD() { BEGIN DD; } void BeginDDP() { BEGIN DDP; } void BeginVN() { BEGIN VN; } int yywrap() { return 1; }