& doesn't work for long equation in Fortran - fortran

Anyone can figure out what is wrong with these lines in Fortran :
if (i==1) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(imax-1,j)) &
+ (c*c*dt*dt)/2/dx/dx*(u(i+1,j)-2*u(i,j)+u(imax-1,j))
more codes here:
select case (case_no)
C.. 1--Lax Wendroff one step scheme
case (1)
write (6,*) 'Entrance for the Lax-Wendroff one step method'
t=dt
do while (t<=18)
do i=1,41
if (i==1) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(imax-1,j)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+ u(imax-1,j))
else if (i==41) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(i-1,2)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+ u(i-1,2))
else
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(i-1,j)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+u(i-1,j))
end if
j=j+1
t=t+dt
end do
end do
Equation is too long and I wanna use '&' to separate it into two lines. But the compiler said
1. classifiable statement at 'u(i,j+1)'
2. invalid character in name at '+'
I am new to Fortran. Many thanks.

You have fixed form source features (you are using a C in column one to start comments) but you are asking about free form line continuation. You need to decide which source form you are using (free form is best in the absence of a need to remain consistent with ancient code), tell the compiler that you are using free form in the appropriate manner (typically using a .f90 file extension) and then make sure that the comment style, token splitting and line continuation aspects are consistent with that form.

Related

Fortran string formatting issues [duplicate]

This question already has answers here:
invalid character name at (1)
(2 answers)
Compilation error: Invalid character in name at (1)
(1 answer)
Closed 3 years ago.
I'm having some issues coding in fortran for a school assignment. I'm trying to write a sentence all on one line (per request of the instructor), but I'm having format issues.
From my understanding I need to use the & to concat the two lines (see below)
I've tried multiple variants of this but I'm having no luck.
'''[j87n896#csci305 fortran]$ gfortran money.f -o money
money.f:94:67:
94 | write(*,*) lunks,'lunkers',loons,'loonters',lits,'littles' &
| 1:
95 | & poons, 'pooneys'
| 1
Error: Invalid character in name at (1)'''
In case you are coding in fixed form - and I believe you are - line continuation is done by adding any non-zero and non-blank character in the sixth column of the second line:
write(*,*) lunks,'lunkers',loons,'loonters',lits,'littles',
+ poons, 'pooneys'
In the case above, I have used a +, but any non-zero/blank char in the 6th column of the second line will do it. You can also extend it to split into more lines by adding chars at the 6th column of the third line, fourth line and so on.
In case you are coding in free form, the continuation is done by adding a & in the end of the first line and in the beginning of the next line (although this last one is not always required):
write(*,*) lunks,'lunkers',loons,'loonters',lits,'littles', &
& poons, 'pooneys'
You may benefit from reading this unofficial copy of the Fortran Standard. Item 6.3.2.4 describes continuation in free format, while item 6.3.3.3 describes continuation in fixed format (which I believe to be your case). You should not expect to understand every single thing you read there, but the sooner you start to try, the sooner it will make some sense for you.
Also, in your example there is a comma missing right after 'littles'. I've fixed that in both examples. Check it out.

Proper Fortran compiler to execute a program

I have little knowledge of the Fortran language. I have come across some programs written in the 90s (see attached snapshot showing just a portion of a long script).
I'd like to know what kind of compiler is appropriate to execute such codes? I have installed gfortran-4.2.3 on my mac. I'm also not sure about the indentation in the attached code: if C (comment) is at column 1, does the main code start at column 9 or 7? what about the position of numbers placed in between referred by GO TO?
This is not Fortran 90. This is Fortran 77.
That said, gfortran is able to compile this code. Make sure that the file extension for the file is .f so that gfortran realises it's fixed-form.
The C needs to be in the first column, the numbers that you reference are labels, they can be between column 1 and 5. The asterisk at line 198 is a continuation character, meaning that this should be treated as part of the previous line. It must be in column 6. Everything else needs to be between columns 7 and 72 (inclusive)
Oh, and the 3-digit numbers at the very beginning are line numbers, and must not be in the source code.
Edited to add: Since you have to type it all again anyway, you might as well make it free-form:
Replace the C in the first column with !, and change the way continuation lines are marked: Turn this:
write (*, *) "This is some long text,
* which doesn't fit into a line"
Into this:
write(*, *) "This is some long text, " // &
"which doesn't fit into a line"
Everything else can stay like it is. (You can now use proper indentation, too!)
New Edit
So you've pasted the code that you wrote and the error messages, so I'm replying to that now.
In Fixed Form, any character past column 72 is ignored. You have a few lines with long strings, where the terminating quotation mark is in that ignored region.
Make sure that no line exceeds the 72nd row.

Automatic determination of free versus fixed form Fortran code

I need to know, for a public domain package, if given Fortran code is free of fixed formatted code and it is, unfortunately, not possible to use the extension for this. Is there a reliable way to do this / is there example code that does this?
You would have to write your own program/script that checks the form.
Is there any & before column 72 outside of character strings? -> free form
Is there any non-number in the first columns outside of comments? -> free form
There other possibilities, but they would generally have to be able to decide if the statement is valid and that is more difficult:
Deciding if the character in column is a continuation character or a part of a statement in the free-form.
Deciding if a non-! character in the first column is a comment in the fixed form or a valid statement in the free form.
There may be files that conform to both, but that shouldn't be a problem.
Silverfrost FTN95 uses the file extension:
.for, .f or .fix - fixed format
.f90 .f95 - free format
If the user wants to override the default they use a command line option (which they can also turn on-off as a default)
You could use these extensions as a first guess and then look at the first few lines and see if they match

Indentation control while developing a small python like language

I'm developing a small python like language using flex, byacc (for lexical and parsing) and C++, but i have a few questions regarding scope control.
just as python it uses white spaces (or tabs) for indentation, not only that but i want to implement index breaking like for instance if you type "break 2" inside a while loop that's inside another while loop it would not only break from the last one but from the first loop as well (hence the number 2 after break) and so on.
example:
while 1
while 1
break 2
'hello world'!! #will never reach this. "!!" outputs with a newline
end
'hello world again'!! #also will never reach this. again "!!" used for cout
end
#after break 2 it would jump right here
but since I don't have an "anti" tab character to check when a scope ends (like C for example i would just use the '}' char) i was wondering if this method would the the best:
I would define a global variable, like "int tabIndex" on my yacc file that i would access in my lex file using extern. then every time i find a tab character on my lex file i would increment that variable by 1. when parsing on my yacc file if i find a "break" keyword i would decrement by the amount typed after it from the tabIndex variable, and when i reach and EOF after compiling and i get a tabIndex != 0 i would output compilation error.
now the problem is, whats the best way to see if the indentation got reduced, should i read \b (backspace) chars from lex and then reduce the tabIndex variable (when the user doesn't use break)?
another method to achieve this?
also just another small question, i want every executable to have its starting point on the function called start() should i hardcode this onto my yacc file?
sorry for the long question any help is greatly appreciated. also if someone can provide an yacc file for python would be nice as a guideline (tried looking on Google and had no luck).
thanks in advance.
I am currently implementing a programming language rather similar to this (including the multilevel break oddly enough). My solution was to have the tokenizer emit indent and dedent tokens based on indentation. Eg:
while 1: # colons help :)
print('foo')
break 1
becomes:
["while", "1", ":",
indent,
"print", "(", "'foo'", ")",
"break", "1",
dedent]
It makes the tokenizer's handling of '\n' somewhat complicated though. Also, i wrote the tokenizer and parser from scratch, so i'm not sure whether this is feasable in lex and yacc.
Edit:
Semi-working pseudocode example:
level = 0
levels = []
for c = getc():
if c=='\n':
emit('\n')
n = 0
while (c=getc())==' ':
n += 1
if n > level:
emit(indent)
push(levels,n)
while n < level:
emit(dedent)
level = pop(levels)
if level < n:
error tokenize
# fall through
emit(c) #lazy example
Very interesting exercise. Can't you use the end keyword to check when the scope ends?
On a different note, I have never seen a language that allows you to break out of several nested loops at once. There may be a good reason for that...

Replace C style comments by C++ style comments

How can I automatically replace all C style comments (/* comment */) by C++ style comments (// comment)?
This has to be done automatically in several files. Any solution is okay, as long as it works.
This tool does the job:
https://github.com/cenit/jburkardt/tree/master/recomment
RECOMMENT is a C++ program which
converts C style comments to C++ style
comments.
It also handles all the non-trivial cases mentioned by other people:
This code incorporates suggestions and
coding provided on 28 April 2005 by
Steven Martin of JDS Uniphase,
Melbourne Florida. These suggestions
allow the program to ignore the
internal contents of strings, (which
might otherwise seem to begin or end
comments), to handle lines of code
with trailing comments, and to handle
comments with trailing bits of code.
This is not a trivial problem.
int * /* foo
/* this is not the beginning of a comment.
int * */ var = NULL;
What do you want to replace that with? Any real substitution requires sometimes splitting lines.
int * // foo
// this is not the beginning of a comment.
// int *
var = NULL;
How do you intend to handle situations like this:
void CreateExportableDataTable(/*[out, retval]*/ IDispatch **ppVal)
{
//blah
}
Note the comment inside the parens... this is a common way of documenting things in generated code, or mentioning default parameter values in the implementation of a class, etc. I'm usually not a fan of such uses of comments, but they are common and need to be considered. I don't think you can convert them to C++ style comments without doing some heavy thinking.
I'm with the people who commented in your question. Why do it? Just leave it.
it wastes time, adds useless commits to version control, risk of screwing up
EDIT:
Adding details from the comments from the OP
The fundamental reason of preferring C++-style comment is that you can comment out a block of code which may have comments in it. If that comment is in C-style, this block-comment-out of code is not straight forward. – unknown (yahoo)
that might be a fair/ok thing to want to do, but I have two comments about that:
I know of no one who would advocate changing all existing code - that is a preference for new code. (IMO)
If you feel the need to "comment out code" (another iffy practice) then you can do it as needed - not before
It also appears that you want to use the c-style comments to block out a section of code? Or are you going to use the // to block out many lines?
One alternative is a preprocessor #ifdef for that situation. I cringe at that but it is just as bad as commenting out lines/blocks. Neither should be left in the production code.
I recently converted all C-style comments to C++-style for all files in our repository. Since I could not find a tool that would do it automatically, I wrote my own: c-comments-to-cpp
It is not fool-proof, but way better than anything else I've tried (including RECOMMENT). Among other things, it supports converting Doxygen style comments, for instance:
/**
* #brief My foo struct.
*/
struct foo {
int bar; /*!< This is a member.
It also has a meaning. */
};
Gets converted to:
/// #brief My foo struct.
struct foo {
int bar; ///< This is a member.
///< It also has a meaning.
};
Here's a Python script that will (mostly) do the job. It handles most edge cases, but it does not handle comment characters inside of strings, although that should be easy to fix.
#!/usr/bin/python
import sys
out = ''
in_comment = False
file = open(sys.argv[1], 'r+')
for line in file:
if in_comment:
end = line.find('*/')
if end != -1:
out += '//' + line[:end] + '\n'
out += ' ' * (end + 2) + line[end+2:]
in_comment = False
else:
out += '//' + line
else:
start = line.find('/*')
cpp_start = line.find('//')
if start != -1 and (cpp_start == -1 or cpp_start > start):
out += line[:start] + '//' + line[start+2:]
in_comment = True
else:
out += line
file.seek(0)
file.write(out)
Why don't you write a C app to parse it's own source files? You could find the /* comments */ sections with a relatively easy Regex query. You could then replace the new line characters with new line character + "//".
Anyway, just a thought. Good luck with that.
If you write an application/script to process the C source files, here are some things to be careful of:
comment characters within strings
comment characters in the middle of a line (you might not want to split the code line)
You might be better off trying to find an application that understands how to actually parse the code as code.
There are a few suggestions that you might like to try out:
a)Write your own code (C/ Python/ any language you like) to replace the comments. Something along the lines of what regex said or this naive solution 'might' work:
[Barring cases like the one rmeador, Darron posted]
for line in file:
if line[0] == "\*":
buf = '//' + all charachters in the line except '\*'
flag = True
if flag = True:
if line ends with '*/':
strip off '*/'
flag = False
add '//' + line to buf
b)Find a tool to do it. (I'll look up some and post, if I find them.)
c)Almost all modern IDE's (if you are using one) or text editors have an auto comment feature. You can then manually open up each file, select comment lines, decide how to handle the situation and comment C++ style using an accelerator (say Ctrl + M). Then, you can simply 'Find and Replace' all "/*" and "*/", again using your judgment. I have Gedit configured to do this using the "Code Comment' plugin. I don't remember the way I did it in Vim off hand. I am sure this one can be found easily.
If there are just "several files" is it really necessary to write a program? Opening it up in a text editor might do the trick quicker in practice, unless there's a whole load of comments. emacs has a comment-region command that (unsurprisingly) comments a region, so it'd just be a case of ditching the offending '/*' and '*/'.
Very old question, I know, but I just achieved this using "pure emacs". In short, the solution looks as follows:
Run M-x query-replace-regexp. When prompted, enter
/\*\(\(.\|^J\)*?\)*\*/
as the regex to search for. The ^J is a newline, which you can enter by pressing ^Q (Ctrl+Q in most keyboards), and then pressing the enter key. Then enter
//\,(replace-regexp-in-string "[\n]\\([ ]*?\\) \\([^ ]\\)" "\n\\1// \\2" \1))
as the replacement expression.
Essentially, the idea is that you use two nested regex searches. The main one simply finds C-style comments (the *? eager repetition comes very handy for this). Then, an elisp expression is used to perform a second replacement inside the comment text only. In this case, I'm looking for newlines followed by space, and replacing the last three space characters by //, which is nice for preserving the comment formatting (works only as long as all comments are indented, though).
Changes to the secondary regex will make this approach work in other cases, for example
//\,(replace-regexp-in-string "[\n]" " " \1))
will just put the whole contents of the original comment into a single C++-style comment.
from PHP team convention... some reasonning has to exist if the question was asked. Just answer if you know.
Never use C++ style comments (i.e. // comment). Always use C-style
comments instead. PHP is written in C, and is aimed at compiling
under any ANSI-C compliant compiler. Even though many compilers
accept C++-style comments in C code, you have to ensure that your
code would compile with other compilers as well.
The only exception to this rule is code that is Win32-specific,
because the Win32 port is MS-Visual C++ specific, and this compiler
is known to accept C++-style comments in C code.