I'm pretty new to vhdl and I can't seem to find the error in my code, I keep getting these errors.
alarm.vhdl (line 19, col 5): (E10) Syntax error at/before reserved symbol 'if'.
Error occurred within 'ARCHITECTURE' at line 16, column 28 in alarm.vhdl.
alarm.vhdl (line 31, col 9): (E56) Expected ;, but got IF
alarm.vhdl (line 31, col 9): (E10) Syntax error at/before reserved symbol 'if'.
alarm.vhdl (line 33, col 4): (E10) Syntax error at/before reserved symbol 'end'.
Is there something wrong with my if statement?
library IEEE;
use ieee.std_logic_1164.all;
entity alarm is
port( master_switch: in std_logic;
door_sensor: in std_logic;
wheel_sensor: in std_logic;
clock: in std_logic;
Z : out std_logic;
J : in std_logic_vector(1 downto 0);
K : in std_logic_vector(1 downto 0);
Q : inout std_logic_vector(1 downto 0);
Qcomp : inout std_logic_vector(1 downto 0) );
end alarm;
architecture behav of alarm is
begin
if clock='1' then
J(1) <= Qcomp(1) AND Q(0) AND master_switch AND door_sensor;
K(1) <= Q(0) OR Q(1);
J(0) <= Qcomp(0);
K(0) <= Qcomp(1) OR (Q(0) AND Q(1));
Q(1) <= ((NOT K(1)) AND Q(1)) OR (J(1) AND Qcomp(1));
Q(0) <= ((NOT K(0)) AND Q(0)) OR (J(0) AND Qcomp(0));
Z <= Q(1) AND Qcomp(0);
end if;
end;
end behav;
The if statement here must be in a process, with clock in its sensitivity list. (Also you want to use rising_edge(clock) rather than clock = '1' for correct synthesis)
on nebulous syntax error messages
alarm.vhdl (line 19, col 5): (E10) Syntax error at/before reserved symbol 'if'.
Error occurred within 'ARCHITECTURE' at line 16, column 28 in alarm.vhdl.
This is caused by a lack of a label preceding the reserved word if, presumed to be a generate statement scheme.
The issue being as Brian says that an if statement which is a sequential statement can only appear in a process, or a subprogram (a function or a procedure).
The apparent poor quality of the error message comes from how the error is detected in the parser.
The statements found inside an architecture statement part are concurrent statements:
architecture_statement_part ::=
{ concurrent_statement }
The curly brackets meaning zero or more concurrent statements are allowed (An architecture statement part can be empty).
concurrent_statement ::=
block_statement
| process_statement
| concurrent_procedure_call_statement
| concurrent_assertion_statement
| concurrent_signal_assignment_statement
| component_instantiation_statement
| generate_statement
A block statement begins with the reserved word block.
A process statement beginning with the reserved word process or postponed.
A concurrent procedure call statement beginning with the a procedure name or the reserved word postponed.
A concurrent assertion statement beginning with the reserved word assert.
A concurrent signal assignment statement beginning with the name of a signal or the keyword postponed.
A component instantiation statement beginning with the reserved word component, or the reserved word entity, or the reserved word configuration, or the name of an entity.
All the above concurrent statements may be optionally labeled, the label preceding either a reserved word or a name (an identifier, which can be a selected name).
The last choice for the generate statement requires a label and can have the reserved word if.
generate_statement ::=
generate_label :
generation_scheme generate
[ { block_declarative_item }
begin ]
{ concurrent_statement }
end generate [ generate_label ] ;
generation_scheme ::=
for generate_parameter_specification
| if condition
label ::= identifier
We see that after a mandatory label we'd expect to see the generation scheme, either indicated by the the reserved word if or the reserved word for.
The parser tested for these in order. You could note that concurrent_statement is not a terminal. One of the various concurrent statements would be a terminal production. Without the ability to hang an error message on a non-terminal everything will get swept up in the last concurrent statement choice (generate statement).
Rather than tell you there's something wrong with the generate statement:
ghdl -a alarm.vhdl
alarm.vhdl:19:1: a generate statement must have a label
alarm.vhdl:19:14: 'generate' is expected instead of 'then'
The parser you used told there's simply something wrong around the reserved word if. Although there is only one concurrent statement that can 'start' with if, the lack of a mandatory label aside.
A VHDL parser can operate with a look ahead of one, assuming semantic predicates are used (e.g. entity_name).
It's sometime possible to use a larger look ahead to avoid backtracking (which makes no sense in the last concurrent statement choice). There was an expression followed by the reserved word then, which disqualifies the current concurrent statement as a generate statement.
It's possible to produce a better error message:
nvc -a alarm.vhdl
** Error: syntax error, unexpected if, expecting process
File alarm.vhdl, Line 19
if clock='1' then
^^
This determining that if is inappropriate without being preceded by a label, and in the case of nvc noting that an if statement is a sequential statement, allowed in, in this case a process statement.
(Notice Brian's answer said "The if statement here must be in a process,..").
Note that neither ghdl nor nvc preceded beyond this error. ghdl treats the current portion of the design description as a generate statement (no non-terminal error messages), while nvc is capable of non-terminal error messages (not using a bison construct in this case). Your tool vendor's parser throws up it's hands a bit sooner but attempts a poor non-terminal error message.
However, there's no excuse or need for preceding further:
alarm.vhdl (line 31, col 9): (E56) Expected ;, but got IF
alarm.vhdl (line 31, col 9): (E10) Syntax error at/before reserved symbol 'if'.
alarm.vhdl (line 33, col 4): (E10) Syntax error at/before reserved symbol 'end'.
Why is an unknown concurrent statement choice being attempted when any error in parsing is sufficient to invalidate the output? There's an attempt to give more context, however referencing line and columns as well as reserved words is likely not the way to do it.
You could also note that nvc's error message can have shortcomings. Label the if statement and you get:
nvc -a alarm.vhdl
** Error: syntax error, unexpected then
File alarm.vhdl, Line 20
if clock='1' then
^^^^
The shortcoming here is that it doesn't tell you it's parsing a generate statement (nor does you're tool vendor's parser).
While ghdl gets a bit more specific:
ghdl -a alarm.vhdl
alarm.vhdl:20:14: 'generate' is expected instead of 'then'
ghdl: compilation error
And one of the things all three of these parsers has in common is that they all required VHDL language expertise to interpret.
In these cases a tool vendor could provide an expanded narrative optionally to explain how the message was produced.
For instance Modelsim has a verror facility which produces a narrative description when provided with an error number.
In your case you appear to be synthesizing the VHDL design description directly. In general a synthesis tool assumes some familiarity with VHDL, which might indicate you'd be better off simulating a design first or failing that based on complexity using a different analyzer to root out syntax errors.
Your error messages appear to come from Cypress's WARP, the Reference Manual (1996, PDF,1.4 MB) tells us:
E10 :Syntax error at/before reserved symbol ‘%s’.
You used a reserved word in an illegal fashion, e.g., as a signal or variable name.
And you can see the message is a bit less than helpful.
WARP is considered obsolete intended to support a discontinued CPLD line and discontinued itself in 2012, otherwise lacking in support. It reinforces the notion of analyzing your VHDL designs with another tool.
Related
The Bison yyparse() function stop to read its input (file or stream) when 0 is returned.
I was wondering if there is a way to execute some more commands after it occurs.
I mean, is possible to tread 0 (or some token thrown by its return) in bison file?
Something like:
Flex
<<EOF>> { return 0; }
Bison
%token start
start : start '0' {
// Desired something else
}
Suppose program is the top-level symbol in a grammar. That is, it is the non-terminal which must be matched by the parser's input.
Of course, it's possible that program will also be matched several times before the input terminates. For example, the grammar might look something like:
%start program
%%
program: %empty
| program declaration
In that grammar, there is no way to inject an action which is only executed when the input is fully parsed. I gather that is what you want to do.
But it's very simple to create a non-terminal whose action will only be executed once, at the end of the parse. All we need to do is insert a new "unit production" at the top of the grammar:
%start start
%%
start : program { /* Completion action */ }
program: %empty
| program declaration
Since start does not appear on the right-hand side of any production in the grammar, it can only be reduced at the end of the parse, when the parser reduced the %start symbol. So even though the production does not explicitly include the end token, we know that that the end token is the lookahead token when the reduction action is executed.
Unit productions -- productions whose right-hand side contains just one symbol -- are frequently used to trigger actions at strategic points of the parse, and the above is just one example of the technique.
I wrote the following two lines in fortran
C23456789
REAL H3 = 0
H3=H*H*H
and I received the following errors from gdb :
ljmd.f:186.5:
REAL H3 = 0
1
Error: Non-numeric character in statement label at (1)
ljmd.f:187.5:
H3=H*H*H
1
Error: Non-numeric character in statement label at (1)
ljmd.f:187.6:
H3=H*H*H
1
What is the proper way to create and use new variables in the middle of someone else's fortran program? C23456789 is my label of the current column used in the program.
This is in any random Fortran tutorial. I expect you have the fixed source form. Then any statement must start at column 7 or farther.
Also,
REAL H3 = 0
isn't legal in free form source Fortran and does a completely different thing in fixed form (see #francesalus' comment). And in your case there is no reason to initialize the variable at all. You can just do
REAL H3
H3 = H**3
If you happen to need the initialization somewhere else, you either must use
real :: a = 0
(requires Fotran 90), or
REAL A
DATA A/0/
(in Fortran77). Beware, both version make the variable SAVE which you may know as static from other languages.
The last point, you cannot introduce variables anywhere "in the middle of program", the declaration of variables have their place at the beginning of each compilation unit (program, function, subroutine,...).
I am try to compile FORTRAN 77 code and I have problems like this.
integer row(nnzmax+nszero),column(nnzmax+nszero),
+ ireg(nximax),florsm(nzimax)/nzimax*2/
real lambda,imodel(nximax,nzimax),dm(nmmax),
+ dum1(nmmax),dum2(nmmax),data(ndmax+nsconst),
+ anz(nnzmax+nszero),ibmodel(nximax,nzimax),
+ smwz(nzimax)/nzimax*-1./,spwz(nzimax)/nzimax*-1./
Error on line 50: attempt to give DATA in type-declaration
Error on line 52: attempt to give DATA in type-declaration
I used to work with this code,but it has been compiled with Intel Fotran Compiler. I have moved to other country so I do not have ifort installed here. I am using fort77 now. Should I try with some compilation options or?I have used this script to compile app .f from this folder.
#! /bin/csh -f
set list=`ls *.f`
set FLAG="-o"
echo $list
foreach file (${list})
echo $file
f77 ${file} ${FLAG} ${file:r}
mv ${file:r} ../bin/.
end
I have changed declarations like this:
integer row(nnzmax+nszero),column(nnzmax+nszero),
+ ireg(nximax),florsm(nzimax),
+ data florsm /nzimax*2/
real lambda,imodel(nximax,nzimax),dm(nmmax),
+ dum1(nmmax),dum2(nmmax),data(ndmax+nsconst),
+ anz(nnzmax+nszero),ibmodel(nximax,nzimax),
+ data smwz /nzimax*-1./,
+ data spwz /nzimax*-1./
But still I got
Error on line 50: attempt to give DATA in type-declaration
Error on line 53: attempt to give DATA in type-declaration
Error on line 385: Declaration error for smwz: used as variable
Error on line 385: Declaration error for smwz: may not appear in namelist
Error on line 385: Declaration error for spwz: used as variable
Error on line 385: Declaration error for spwz: may not appear in namelist
This fragment, and the later similar ones
florsm(nzimax)/nzimax*2/
looks like a non-standard way of initialising a variable with a sort-of data statement merged into the declaration. A more standard approach would separate the two, something like
florsm(nzimax)
...
data florsm /nzimax*2/
One of the beauties of working with the Intel Fortran compiler is its long history; along the way it has picked up, and continues to accept, all sorts of non-standard features. I'm guessing that this is one of those and is not acceptable to the other compiler you mention.
Of course, this seems to be what the error statement seems to be telling us.
A standard replacement might be
florsm(nzimax) = 2
but that takes advantage of a Fortran 90 feature which something called fort77 might not understand either.
I compile a fortran 77 code using gfortran and get the following error:
10 open (23,file=outfile,status='old',access='append',err=10)
1
Warning: Branch at (1) may result in an infinite loop
This happens several times.
One of the output files looks like the following:
^L6a10È <90> ) &<9b>LÓLÓLÕ<91><90> <90> <90> È <8e><9b>LÓLÓLÕ<93>2
!MERCURY ¢¤õ/!ô<8a><8a><90> ÿ<90> ÿ<90> ÿÌÖÏ©ü}M<91>
"VENUS «}>±{©±<8b><90> ÿ<90> ÿ<90> ÿʺ93¿<8d>d<91>
However, it should just look like a table of text.
Any ideas?
Your line of code
10 open (23,file=outfile,status='old',access='append',err=10)
specifies that the open statement should transfer control to itself (label 10) in case an error is encountered, so any error could trigger an infinite loop. It also suppresses the output of error messages. If you want to just check for an error status, I would suggest using the iostat and/or iomsg (Fortran 2003) arguments:
open (23, file=outfile, status='old', access='append', iostat=ios, iomsg=str)
Here ios is an integer that will be zero if no errors occur and nonzero otherwise, and str is a character variable that will record the corresponding error message.
The err= argument in your open statement specifies a statement label to branch to should the open fail for some reason. Your code specifies a branch to the line labelled 10 which happens to be the line containing the open statement. This is probably not a good idea; a better idea would be to branch to a line which deals gracefully with an error from the open statement.
The warning from gfortran is spot on.
As to the apparent garbage in your output file, without sight of the code you use to write the garbage (or what you think are pearls perhaps) it's very difficult to diagnose and fix that problem.
I have a relatively simple lex/flex file and have been running it with flex's debug flag to make sure it's tokenizing properly. Unfortunately, I'm always running into one of two problems - either the program the flex generates stops just gives up silently after a couple of tokens, or the rule I'm using to recognize characters and strings isn't called and the default rule is called instead.
Can someone point me in the right direction? I've attached my flex file and sample input / output.
Edit: I've found that the generated lexer stops after a specific rule: "cdr". This is more detailed, but also much more confusing. I've posted a shorted modified lex file.
/* lex file*/
%option noyywrap
%option nodefault
%{
enum tokens{
CDR,
CHARACTER,
SET
};
%}
%%
"cdr" { return CDR; }
"set" { return SET; }
[ \t\r\n] /*Nothing*/
[a-zA-Z0-9\\!##$%^&*()\-_+=~`:;"'?<>,\.] { return CHARACTER; }
%%
Sample input:
set c cdra + cdr b + () ;
Complete output from running the input through the generated parser:
--(end of buffer or a NUL)
--accepting rule at line 16 ("set")
--accepting rule at line 18 (" ")
--accepting rule at line 19 ("c")
--accepting rule at line 18 (" ")
--accepting rule at line 15 ("cdr")
Any thoughts? The generated program is giving up after half of the input! (for reference, I'm doing input by redirecting the contents of a file to the generated program).
When generating a lexer that's standalone (that is, not one with tokens that are defined in bison/yacc, you typically write an enum at the top of the file defining your tokens. However, the main loop of a lex program, including the main loop generated by default, looks something like this:
while( token = yylex() ){
...
This is fine, until your lexer matches the rule that appears first in the enum - in this specific case CDR. Since enums by default start at zero, this causes the while loop to end. Renumbering your enum - will solve the issue.
enum tokens{
CDR = 1,
CHARACTER,
SET
};
Short version: when defining tokens by hand for a lexer, start with 1 not 0.
This rule
[-+]?([0-9*\.?[0-9]+|[0-9]+\.)([Ee][-+]?[0-9]+)?
|
seems to be missing a closing bracket just after the first 0-9, I added a | below where I think it should be. I couldn't begin to guess how flex would respond to that.
The rule I usually use for symbol names is [a-zA-Z$_], this is like your unquoted strings
except that I usually allow numbers inside symbols as long as the symbol doesn't start with a number.
[a-zA-Z$_]([a-zA-Z$_]|[0-9])*
A characters is just a short symbol. I don't think it needs to have its own rule, but if it does, then you need to insure that the string rule requires at least 2 characters.
[a-zA-Z$_]([a-zA-Z$_]|[0-9])+