Ada object "Train" cannot be used before end of its declaration - concurrency

What is the problem with this code? Compiler says two things, that there is no Run entry and that Run accept does not match an entry (both seem wrong), and separately that Train cannot be used before declaration (but it is already declared). Please explain to me what is going on.
I am hesitant to show entire code but can do so.
type ItineraryType is array (0..255) of Integer;
type Train is record
Label : Integer;
Capacity : Integer;
Maxspeed : Integer;
Starts : Integer;
Itinerary : ItineraryType;
Stops : Integer;
lock : access Mutex;
end record;
task type TrainThread is
entry Run (train1:Train);
end;
task body TrainThread is
train : Train;
begin
accept Run (train1:Train) do
train := train1;
end;
end;
-- part of main
train1 := new TrainThread;
train1.Run(trains(i));
main.adb:51:05: warning: no accept for entry "Run"
main.adb:52:17: object "Train" cannot be used before end of its declaration
main.adb:54:09: no entry declaration matches accept statement
gnatmake: "main.adb" compilation error

Ada is case insensitive, so train and Train are equivalent. So the declaration train : Train will always be invalid. (Admittedly gnat's message could be better in this case)

Related

How to do something else in Bison after Flex returns 0?

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.

Ada I/O: Put_Line not working after Get_Line

I'm trying to do basic I/O in Ada, but the documentation on this isn't very informative (unless I'm going to the wrong place). In the following block, I was trying to test string appending and output, but for some reason it literally only outputs "Hello WORLD!" I'm sure I'm missing something really simple, but I have been trying for a few hours to figure this out.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
procedure Main is
usrIn : String(1..80);
appendString : Unbounded_String;
last : Natural;
begin
Put_Line ("Hello WORLD!");
Get_Line(usrIn, last);
Put_Line ("AAAAAAAA");
appendString := To_Unbounded_String("USER IN: ");
Append(appendString,usrIn);
Put_Line("Output follows");
Put_Line(To_String(appendString));
end Main;
usrIn is a String(1..80), i.e., an array of 80 characters.
This line:
Append(appendString,usrIn);
appends all 80 characters (most of which are likely garbage) to appendString.
This is what the last argument to Get_Line is for.
Replace userIn by userIn(userIn'First .. last). That's a slice that consists only of the characters read by the Get_Line call.
If you are compiling using a version in Ada 2005 or more, you can also use the function form of Get_Line :
declare
usrIn : constant String := Get_Line;
begin
Append(appendString,usrIn);
end;

c++ Variable values not updated correctly on GUI

I am debugging some simulation software that has been written partly in C++ and partly in Ada. On the GUI, there are two values displaying the ETA & TimeToGo of an entity moving in the simulation on any given leg of its journey, and for the remainder of the whole journey. The TimeToGo & ETA values that are displayed for the current leg are correct (i.e. how long it will take the entity to reach its current target destination from its current location). However, the TimeToGo & ETA values for the remainder of the whole journey are incorrect- approximately 40-50s lagging behind.
I have come across a couple of assignments in the code, and I am wondering if they are the wrong way round:
if(some condition){
mFlightPlanData[0] = fpMiniToteData;
} else {
mFlightPlanData[1] = fpMiniToteData;
}
mFlightPlanData[] is an array of flightPlans, of size 2- because each aircraft can have up to two flight plans at any one time- a primary and a secondary. fpMiniToteData is the variable used to display the flight plan data on the GUI.
Now, it appears to me that these assignments are the wrong way round- these seem to be saying:
Set the first element in the flight plan array equal to the value of the display data
else
Set the second element in the flight plan array equal to the value of the display data
However, what should be happening is that the display data should be being set to the value of either the first or second element in the flight plan array...
I tried to do this, by switching the assignments around, i.e.
if(some condition){
fpMiniToteData = mFlightPlanData[0];
} else {
fpMiniToteData = mFlightPlanData[1];
}
But I now get a compile error that says:
error C2678: binary '=': no operator found which takes a left-hand operand of type 'const...' or there is no acceptable conversion)
What does this error mean? Do I need to have defined a function that will convert the data type held in the array to the data type of the fpMiniToteData?
Any help would be much appreciated.
Edit 12/02/2015 # 1645
fpMiniToteData is defined in the function definition- the function that the code above belongs to:
void FlightPlanInterface::setFlightPlanData(
const FlightPlanMinitoteTypes::FlightPlanPerformanceDataViewId_Type viewId,
const FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& fpMiniToteData)
{
and mFlightPlanData is defined in a header file as follows:
private:
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant mFlightPlanData[2];

IF syntax error in simple VHDL code

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.

Simple (mostly) variable parser

In one of my projects, I need to be able to provide a very simple variable find-and-replace parser (mostly for use in paths). Variables are used primarily during startup and occasionally to access files (not the program's primary function, just loading resources), so the parser need not be high-performance. I would greatly prefer it to be thread-safe, however.
The parser needs to be able to store a set of variables (map<string, string> at the moment) and be able to replace tokens with the corresponding value in strings. Variable values may contain other variables, which will be resolved when the variable is used (not when it is added, as variables may be added over time).
The current variable grammar looks something like:
$basepath$/resources/file.txt
/$drive$/$folder$/path/file
My current parser uses a pair of stringstreams ("output" and "varname"), writes to the "output" stream until it finds the first $, the "varname" stream until the second $, then looks up the variable (using the contents of varname.str()). It's very simple and works nicely, even when recursing over variable values.
String Parse(String input)
{
stringstream output, varname;
bool dest = false;
size_t total = input.length();
size_t pos = 0;
while ( pos < total )
{
char inchar = input[pos];
if ( inchar != '$' )
{
if ( dest ) output << inchar;
else varname << inchar;
} else {
// Is a varname start/end
if ( !dest )
{
varname.clear();
dest = true;
} else {
// Is an end
Variable = mVariables.find(varname.str());
output << Parse(Variable.value());
dest = false;
}
}
++pos;
}
return output.str();
}
(error checking and such removed)
However, that method fails me when I try to apply it to my desired grammar. I would like something similar to what Visual Studio uses for project variables:
$(basepath)/resources/file.txt
/$(drive)/$(folder)/path/file
I would also like to be able to do:
$(base$(path))/subdir/file
Recursing in the variable name has run me into a wall, and I'm not sure the best way to proceed.
I have, at the moment, two possible concepts:
Iterate over the input string until I find a $, look for a ( as the next character, then find the matching ) (counting levels in and out until the proper close paran is reached). Send that bit off to be parsed, then use the returned value as the variable name. This seems like it will be messy and cause a lot of copying, however.
The second concept is to use a char *, or perhaps char * &, and move that forward until I reach a terminating null. The parser function can use the pointer in recursive calls to itself while parsing variable names. I'm not sure how best to implement this technique, besides having each call keep track of the name it's parsed out, and append the returned value of any calls it makes.
The project need only compile in VS2010, so STL streams and strings, the supported bits of C++0x, and Microsoft-specific features are all fair game (a generic solution is preferable in case those reqs change, but it's not necessary at this point). Using other libraries is no good, though, especially not Boost.
Both my ideas seem like they're more complicated and messier than is needed, so I'm looking for a nice clean way of handling this. Code, ideas or documents discussing how best to do it are all very much welcome.
Simple solution is to search for the first ')' in the string, then move backwards to see if there's an identifier preceeded by "$(". If so, replace it and restart your scanning. If you don't find "$(" identifier, then find the next ')' - when there isn't one you're finished.
To explain: by searching for a ) you can be sure that you're finding a complete identifier for your substitution, which then has the chance to contribute to some other identifier used in a subsequent substitution.
EXAMPLE
Had a great time on $($(day)$(month)), did you?
Dictionary: "day" -> "1", "month" -> "April", "1April" -> "April Fools Day"
Had a great time on $($(day)$(month)), did you?
^ find this
Had a great time on $($(day)$(month)), did you?
^^^^^^ back up to match this complete substitution
Had a great time on $(1$(month)), did you?
^ substitution made, restart entire process...
Had a great time on $(1$(month)), did you?
^ find this
etc.