I have the following code and the annoying Error, "[" unexpected In Maple error keeps coming up. Does anyone see what it is that I am doing wrong because I have been staring at the screen for hours and still dont see it.
Relations:=proc(n::posint,fb::Array,{mindeps::posint:=5,verbose::truefalse:=false})
local s,np,f,j,g,f1,f2,i;
s:=isqrt(n);
np:=ArrayNumElems(fb);
f:=[];
j:=1;
g:=np+mindeps;
while nops(f) < g do
f1:=FBTrialDivision(n,s-j+1,fb);
f2:=FBTrialDivision(n,s+j,fb);
f:=[op(f),f1,f2];
j:=j+1
end do;
if verbose then
printf("smooth",g,2*j-2)
else
print("");
print(2*j-2)
end if
[Vector([seq(f[i][1], i = 1..nops(f))]),Vector([seq(f[i][2], i = 1..nops(f))]),
LinearAlgebra:-Transpose(Matrix([seq(f[i][3], i = 1..nops(f))]))]
end proc:
Second one:
FindFactors:=proc(n,rels,deps)
local fact, i, x, y;
fact:=1;
for i to nops(deps) while fact = 1 or fact = n do
x:=mul(j,j=rels[1]~deps[i]);
y:=isqrt(mul(j,j=rels[2]~deps[i]));
fact:=igcd(x+y,n)
end do;
if fact <> 1 and fact <> n then
``(fact)*``(iquo(n,fact))
else
print("no trivial")
end if;
end proc:
There is no terminator for the preceding line.
As plaintext 1D Maple Notation code, the previous line,
end if
is missing a statement terminator (either colon or semicolon). That's the cause of the error.
I notice that in several; places your code makes use of the fact that terminators are not required on lines that precede an end if, end do, end proc, etc. You may be seeing one of the dangers of that habit: when you edit and add a new statement between such a line and the end that trails it, you have to remember to add a statement terminator to the line which is no longer "last". Some people find that it just pays off to keep things simple and always use statement terminators, whether the current line needs it or not.
Related
I'm trying to recover from an error in an If-Else statement.
In my grammar an If is always followed by an Else.
statement: OBRACES statements CBRACES
| IF OPAR exp CPAR statement ELSE statement
| IF OPAR exp CPAR statement error '\n' { yyerrok; yyclearin;}
;
The error found is in the commented else in the last lines:
public boolean Equal(Element other){
if (!this.Compare(aux01,Age))
ret_val = false ;
//else
//nt = 0 ;
}
error: syntax error, unexpected CBRACES, expecting ELSE -> } # line 29
It is not recovering from that error ignoring the errors that come after.
Maybe i'm not understanding well how this error works but i can only find 2 examples on every site about error recovery: "error '\n'" and "'(' error ')'"
Anyone have an idea how to recover from this error (when an if is not followed by an else).
Thanks
You've provided not enough context to know exactly, but my guess is that the lexer/tokenizer, which feeds tokens to your parser, skips white space - including '\n'. So the parser never sees the newline and b/c of that never reduces the
IF OPAR exp CPAR statement error '\n'
production and so its action
{ yyerrok; yyclearin;}
never gets executed and so the error is not recovered.
Probably (although it is hard to say for sure without seeing more of the grammar) you don't need to skip any tokens in the case that else is not found.
The most likely case is that the program is simply lacking an else clause (perhaps because its author is used to other programming languages in which else is optional), and parsing can simply continue as though there were an empty else clause. So you should be able to just use:
IF OPAR exp CPAR statement error { yyerrok; }
(Note: I removed yyclearin because you almost certainly don't want to do that. In the case of the error in the OP, the result would be to ignore the '}' token, leading to extraneous errors later in the parse.)
You probably should take advantage of the action in this error production to produce a clear error message ("if statements must have else clauses"), although the default message is reasonably clear as well.
It is certainly the case that whatever token(s) are used as error context must be produceable by the scanner. That generally precludes error recovery techniques such as "skip to the end of the line", except in the case of languages in which newlines are syntactically significant.
I found out the problem. Thanks for the help anyway.
I put the error inside the braces and now is working.
statement: OBRACES statements CBRACES
| OBRACES error CBRACES { yyerrok; yyclearin;}
| IF OPAR exp CPAR statement ELSE statement
;
Lets say I have the following error string:
err = "/mnt/cd4/autorun.lua:43: 'end' expected (to close 'while' at line 1)
near '-eof-'"
How would I parse the file path, line number, and the error message separately from the string?
I have no prior experience in parsing Lua strings, so I thought asking here would be useful. I also tried finding a topic solving the same matter but I could not find one.
Something like this should work:
err = "/mnt/cd4/autorun.lua:43: 'end' expected (to close 'while' at line 1) near '-eof-'"
local file, line, errmsg = err:match('^(.-):(%d+):(.+)')
print(file, line, errmsg)
The pattern says: capture starting at the end of the line (^) a shortest group of zero or more (-) of any symbol (.), followed by :, then a group of one or more digits (%d+), followed by :, and then a group of one of more symbols (.+). You can read about patterns here.
I'm trying to write a rudimentary bit of code to print a 50*50 array called 'arr'. Unfortunately it so far only prints the first row of the array, although the formatting for that row is correct. I've attached the code below and was wondering if anyone could point out where I was going wrong? Thank you!
program testing
implicit none
integer :: i, j
integer, dimension (1:50, 1:50) :: arr
arr = 1
do i=1,50
open(unit=6, file= "array.txt", action="write")
write(6, '(2500I3)') (arr(i,j), j=1,50)
close(6)
end do
end program testing
Your open statement is inside loop (along with a matching close statement). That means for every row of the array, you open the file. That's probably not what you meant to do.
The default position specifier for an OPEN statement if there is no POSITION specifier is 'ASIS'. For a file that already exists (your case after the first iteration, and perhaps even for the first iteration) that means that the position is unspecified. Your processor probably takes that to be the start of the file. That means that each iteration of the loop you simply overwrite the first record, over and over again.
If you must open the file each iteration, then use the POSITION='APPEND' specifier to position the file at the end when the open statement is executed. Otherwise, move the open and close statements out of the loop.
(The way that the default of 'ASIS' behaves means that you should always specify the initial position of a file via a POSITION specifier when executing an OPEN statement for an existing "on disk" file.)
IanH's answer is correct. Your program can be fixed as follows. Note that output units should be parameterized and not set to 6 and that arrays and array sections can be written as shown.
program testing
implicit none
integer :: i
integer, dimension (1:50, 1:50) :: arr
integer, parameter :: outu = 20 ! better to parameterize unit and
! not to use the number 6, which most compilers
! use for standard output
arr = 1
open(unit=outu, file= "array.txt", action="write")
do i=1,50
write(outu, '(2500I3)') arr(i,:) ! can write array section without implied do loop
end do
close(outu)
end program testing
This should be an easy one.. I can't figure out why my read statement has a syntax error. I have a file 7477 lines long and I want each of those variables to correspond in each line like my format specifies. Any help here would be great. Thanks!
implicit none
integer :: spe, flen = 7477, i
real, dimension (7477):: wnum,s,A,abh
character :: other
integer :: lun = 11
write(*,*) 'Opening File!'
open(lun,file ='h2o_allbands',status = 'old',action ='read')
write(*,*) 'Success!'
17 format (1x,i2,3x,F9.6,1x,E9.3,1x,E9.3,F5.5,A120)
do i = 1, 7477
read(lun,17) spe(i),wnum(i),s(i),A(i),abh(i),other
write(*,*) wnum(i)
end do
The read has spe(i) as an input list item. spe is not declared as an array, so the compiler probably thinks spe(i) is a reference to an integer function. You cannot read "into" the result of a plain integer function.
Perhaps spe should be declared as an array?
Without seeing a line from your input file, it is difficult to say what the exact problem is: However:
First of all, you should not use a format statement when reading entities (unless in special cases), as this can lead to all sort of different errors, if your line is not well formatted for whatever reasons. So just replace the read line with:
read(lun,*) spe(i), wnum(i), s(i), A(i), abh(i), other
If all the lines are read in well apart the last one, then make sure, that you have a newline at the end of the last line.
I am writing a FORTRAN code that uses data in a file made by a MD program. the data is a list of values but has breaks in the data for list updates in the form (# Neighbor list update .. 6527 indexes in list), These breaks are at random intervals so I can't just skip every x
I when I do my code it doesn't ignore these lines and randomly adds the value from the previous step.
1, 0.98510699999999995, 0.98510699999999995
2, 1.9654170000000000, 0.98031000000000001
3, 2.9427820000000002, 0.97736500000000004
4, 3.9186540000000001, 0.97587199999999996
4, 4.8945259999999999, 0.97587199999999996
5, 5.8697910000000002, 0.97526500000000005
note the double step 4 with an identical value from the true step 4
How would I go about skipping this line. Please find the sample code below
Open(Unit=10,File='prod._100.tup')
do i=1,50
Read(10,*,IOSTAT=ios)step,temp,kinetic,potential,total,pressure
If(IS_IOSTAT_END(ios)) Exit
test=test+temp
print*, step, test, temp
End Do
It is not clear to me what the "breaks" in the file are. Are they blank lines? If so, the following code should work:
use, intrinsic :: iso_fortran_env
character (len=200) :: line
Open(Unit=10,File='prod._100.tup')
read_loop: do
Read (10,'(A)',IOSTAT=ios) line
If(ios == iostat_end) exit read_loop
if (len_trim (line) == 0) then
write (*, *) "blank line"
cycle read_loop
end if
read (line, *) step,temp,kinetic,potential,total,pressure
test=test+temp
print*, step, test, temp
end do: read_loop
write (*, *) "total is", test
The above is not tested. The "len_trim" test is based on bad records being blank lines. If breaks are otherwise defined you will have to create a different test.
Try:
i=1
do while (i<=50)
Read(10,*,IOSTAT=ios)step,temp,kinetic,potential,total,pressure
If(IS_IOSTAT_END(ios)) Exit
IF(ios.ne.0) cycle
test=test+temp
i=i+1
enddo
When a bad record is read, ios is assigned a system dependent non-zero number (it is zero on success). Apparently you've written a function (IS_IOSTAT_END) to tell if you've reached the end of the file, but other error conditions can exist (for example, the read statement doesn't match the data). That will return a different non-zero ios than an end-file record, so you should just restart the loop at that point (e.g. cycle)
I assume you want to read exactly 50 lines from the file, so I changed your do loop to a do while, but if the number of records you read doesn't actually matter, then feel free to change it back.