How to make a program to calculate constant mathematical expressions

Asked

Viewed 518 times

6

I have a job to build an algorithm that calculates expressions coming from a TXT file in this format.

10+20*(30)/ 25.

I know this is a recursive descending analyzer, but I have no idea where to start studying and how to do the program analysis routine. The language used is dear C, materials, tips, are good help.

Program until then.

#include <stdio.h>
#include <stdlib.h>

void token(void) {




int main () {
char bse[100];
    FILE *file;
    file = fopen("conta.txt", "r");
    if(file == NULL) {
         printf("Não foi possivel abrir o arquivo");
         getchar();
         exit(0);
    }     
    while(fgets(bse, 100, file) != NULL) { // Leitura e impressão do conteudo do arquivo TXT
         printf("%s", bse);
    }
    fclose(file);     



 }

I did nothing related to the descending recursive syntax itself. I just did the file read and store commands in a string. I’m having doubts about how to do this analysis of expressions that would be the famous (recursive descending syntax).

  • 2

    Have you tried anything? Post your code if ever.

  • Hello Razor! Welcome to Stack Overflow! Please visit Help center to learn more about how to ask and answer. Also, do the tour! At the moment, your question seems to me very broad - and usually the community does not give material suggestions (not the purpose of the site). Do you already have a compiler installed? Have you ever done a "Hello, World!"? Any start of a program will cause the community to see your issue with other eyes - own experience... ;)

  • Well I did nothing related to the descending recursive syntax itself. I just did the file read and store command in a string. I’m having doubts about how to do this analysis of expressions that would be famous (descending recursive syntax.).

  • It may be that separating operations by operator (+,*,/ -) is a start. Then consider performing the calculations following the order of precedence of operators.

  • Good - unless you want to get really good at C, I recommend doing this type of program in a higher level language (like Python). Having string methods to separate tokens, data structures like lists (which can be used as queues) to put operands and operators - can make your life easier in a few light years, and you’ll understand all the logic in the same way.

  • In another language, you can choose, for example, if you want to parse numbers "manually" - for example, traverse character by character, and if it is digit you accumulate the consecutive digits in a number, or use the "split" list method and apply an "int()" in the tokens they have ". isdigit()" as True - that is, you choose how much work you will do to understand, and how much you will use what the language has ready. In C, you have to do everything from scratch.

  • I’m in the first semester, so the idea is just this, doing it from scratch so I can understand what really happens with these expressions. I will study the Data Structure of STACK, and use the postfixed notation, so I saw it is an easier way to perform the procedure.

  • 1

    Related 1 and 2.

Show 3 more comments

1 answer

0

Razor, I have already implemented something similar in the discipline of Compilers, a little more complex because the text was in written form (for example: "three hundred and twenty-three thousand , two hundred and fifty-four plus fifteen times two"). For this implementation I used the Java language with the help of Jflex it is a lexical parser. Follow the main code, I hope it helps.

LineTerminator = \r|\n|\r\n
WhiteSpace     = {LineTerminator} | [ \t\f]

Number = [:digit:] [:digit:]*
pzero = "zero"
unidades = "um" | "dois" | "tres" | "quatro" | "cinco" | "seis" | "sete" | "oito" | "nove"
dezena = "onze" | "doze" | "treze" | "quatorze" | "quinze" | "dezesseis" | "dezessete" | "dezoito" | "dezenove"
dezenas = "vinte" | "trinta" | "quarenta" | "cinquenta" | "sessenta" | "setenta" | "oitenta" | "noventa"
pcem = "cem" | "duzentos" | "trezentos" | "catorze" | "quatrocentos" | "quinhentos" | "seiscentos" | "setecentos" | "oitocentos" | "novecentos"
centenas = "cento" | "duzentos" | "trezentos" | "quatrocentos" | "quinhentos" | "seiscentos" | "setecentos" | "oitocentos" | "novecentos"
dezuni = {dezenas}(" e "{unidades})
centdezuni = {centenas}( " e "{dezuni}) | {centenas}( " e "{dezenas}) | {centenas}( " e "{unidades}) | {centenas}( " e "{dezena})
juntos = {unidades} | {dezena} | {pcem} | {dezuni} | {centdezuni}
unidadedemilhar = {juntos}( " mil")( " , " {dezenas})*( " e " {unidades})* 
            | {juntos}( " mil")( " , " {pcem})
            | {juntos}( " mil")( " , " {centdezuni})


{WhiteSpace}+   { /* ignore */ }

<YYINITIAL> {
    {juntos}  { return newToken(Terminals.NUMBER, new String(yytext())); }
    {centdezuni}  { return newToken(Terminals.NUMBER, new String(yytext())); }
    {dezuni}    { return newToken(Terminals.NUMBER, new String(yytext())); }
    {pzero}    { return newToken(Terminals.NUMBER, new String(yytext())); }
    {pcem}    { return newToken(Terminals.NUMBER, new String(yytext())); }
{dezenas}    { return newToken(Terminals.NUMBER, new String(yytext())); }
    {dezena}    { return newToken(Terminals.NUMBER, new String(yytext())); }
    {centenas}    { return newToken(Terminals.NUMBER, new String(yytext())); }
    {unidadedemilhar}    { return newToken(Terminals.NUMBER, new String(yytext())); }

"("         { return newToken(Terminals.LPAREN); }
")"         { return newToken(Terminals.RPAREN); }
"vezes"         { return newToken(Terminals.MULT);   }
"dividido"         { return newToken(Terminals.DIV);    }
"mais"         { return newToken(Terminals.PLUS);   }
"menos"         { return newToken(Terminals.MINUS);  }
}

Teste da implementação

Summing up to make your job easier use some lexical analyzer, I know there are some libraries for C. Any questions can contact.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.