PDA

View Full Version : Creating a simple calculator with COCO/R and delphi



noeska
10-02-2008, 03:30 PM
System: Windows XP
Compiler: Delphi 2005 and COCO/R
Libraries: Coco/R

Hello,

Currently i am trying to get a simple calculator to workt with coco/r and delphi. Only the the coco/r part does not seem to behave like i expected:



COMPILER Calculator

uses codegen;

var
gen: TCodeGenerator;

CHARACTERS
digit = "0123456789" .
hexdigit = digit + "ABCDEF" .
IGNORE CHR(1) .. CHR(31)
TOKENS
decNumber = digit { digit } .
hexNumber = "$" hexdigit { hexdigit } .
PRODUCTIONS
Calculator = { Expression "=" } (. gen.Emit(oWRITE); .)
(. gen.Emit(oRET); .)
.
Expression = Term { "+" Term (. gen.Emit(oADD); .)
| "-" Term } (. gen.Emit(oSUB); .)
.
Term = Factor { "*" Factor (. gen.Emit(oMUL); .)
| "/" Factor } (. gen.Emit(oDIV); .)
.
Factor = decNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .)
| hexNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .) .
END Calculator.

The problem seems to be that even if there is not Factor a line is written.

For my input:
10 + 10 =

The following is generated:
CONST10
DIV
CONST10
DIV
ADD
SUB
WRITE
RET

But i expected it to be:
CONST 10
ADD
CONST 10
WRITE
RET

Thanks for your answers in advance.

Also is there a COCO/R forum or mailinglist somewhere?

VilleK
10-02-2008, 04:10 PM
I'm not sure what is wrong.

But a good thing with Coco/R compared to other compiler generators is that the generated code is actually readable. So examine the generated code and you will probably see how you should change your input file.

Also take a look at sample calculator grammars to verify that your input is correct.

noeska
10-02-2008, 08:54 PM
Found the problem. I misplaced the } it should have been placed after a .) then things started to work properly.



COMPILER Calculator

uses codegen;

var
gen: TCodeGenerator;

CHARACTERS
digit = "0123456789" .
hexdigit = digit + "ABCDEF" .
IGNORE CHR(1) .. CHR(31)
TOKENS
decNumber = digit { digit } .
hexNumber = "$" hexdigit { hexdigit } .
PRODUCTIONS
Calculator = { Expression "=" } (. gen.Emit(oWRITE); .)
(. gen.Emit(oRET); .)
.
Expression = Term { "+" Term (. gen.Emit(oAdd) .)
| "-" Term (. gen.Emit(oSub) .)
}
.
Term = Factor { "*" Factor (. gen.Emit(oMul) .)
| "/" Factor (. gen.Emit(oDiv) .)
}
.
Factor = decNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .)
| hexNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .) .
END Calculator.


Next i have to solve is how to get things in proper order as parsing is working a bit to well as i first get the values in order and then all the math operators in reverse order.

For:
10 + 10 / 4 =
i get:

CONST 10
CONST 10
CONST 4
DIV
ADD
WRITE
RET

I just realized i need to introduce () to priotize 10+10 so i can write (10 + 10) / 4 =

noeska
10-02-2008, 09:50 PM
Now things work nicely:

COMPILER Calculator

uses codegen;

var
gen: TCodeGenerator;

CHARACTERS
digit = "0123456789" .
hexdigit = digit + "ABCDEF" .
IGNORE CHR(1) .. CHR(31)
TOKENS
decNumber = digit { digit } .
hexNumber = "$" hexdigit { hexdigit } .
PRODUCTIONS
Calculator = { Expression "=" } (. gen.Emit(oWRITE); .)
(. gen.Emit(oRET); .)
.
Expression = Term { "+" Term (. gen.Emit(oAdd); .)
| "-" Term (. gen.Emit(oSub); .)
} (. .)
.
Term = Factor { "*" Factor (. gen.Emit(oMul); .)
| "/" Factor (. gen.Emit(oDiv); .)
} (. .)
.
Factor = decNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .)
| hexNumber (. gen.Emit(oCONST, StrToInt(LexString()) ); .)
| '(' Expression Factor ')'
.
END Calculator.

I now also can do (10 + 10) / 4 =

But i also get an error:

│ 1 (10 + 10) /4 =
│***** ^ invalid Factor

│ 1 error

It is complaining about the ) as it seems.

Though the end result seem to be right:
CONST 10
CONST 10
ADD
CONST 4
DIV
WRITE
RET

noeska
10-02-2008, 10:14 PM
Ok, actually it was not complaining about the last ), but on the word Factor.
So instead of using:
| '(' Expression Factor ')'
I had to use:
| '(' Expression ')'
And no error anymore.