File: grammar.lemon

package info (click to toggle)
kicad 9.0.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 770,320 kB
  • sloc: cpp: 961,692; ansic: 121,001; xml: 66,428; python: 18,387; sh: 1,010; awk: 301; asm: 292; makefile: 227; javascript: 167; perl: 10
file content (70 lines) | stat: -rw-r--r-- 2,852 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
    This file is part of libeval, a simple math expression evaluator

    Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

%token_type { numEval::TokenType }
%extra_argument { NUMERIC_EVALUATOR* pEval }

%nonassoc VAR ASSIGN SEMCOL.
%left PLUS MINUS.
%right UNIT.
%left DIVIDE MULT.

%include {
#include <assert.h>
#include <libeval/numeric_evaluator.h>
}

%syntax_error {
  pEval->parseError("Syntax error");
}

%parse_accept {
  pEval->parseOk();
}

main ::= in.

/* Allow multiple statements in input string: x=1; y=2 */
in ::= stmt.
in ::= in stmt.

/* A statement can be empty, an expr or an expr followed by ';' */
stmt ::= ENDS.
stmt ::= expr(A) ENDS.                    { pEval->parseSetResult(A.valid ? A.dValue : NAN); }
stmt ::= expr SEMCOL.                     { pEval->parseSetResult(NAN); }

expr(A) ::= VALUE(B).                     { A.dValue = B.dValue; A.valid=true; }
expr(A) ::= expr(B) UNIT(C).              { A.dValue = B.dValue * C.dValue; A.valid=B.valid; }
expr(A) ::= MINUS expr(B).                { A.dValue = -B.dValue; A.valid=B.valid; }
expr(A) ::= PLUS expr(B).                 { A.dValue = B.dValue; A.valid=B.valid; }
expr(A) ::= VAR(B).                       { A.dValue = pEval->GetVar(B.text); A.valid=true; }
expr(A) ::= VAR(B) ASSIGN expr(C).        { pEval->SetVar(B.text, C.dValue); A.dValue = C.dValue; A.valid=false; }
expr(A) ::= expr(B) PLUS expr(C).         { A.dValue = B.dValue + C.dValue; A.valid=C.valid; }
expr(A) ::= expr(B) MINUS expr(C).        { A.dValue = B.dValue - C.dValue; A.valid=C.valid; }
expr(A) ::= expr(B) MULT expr(C).         { A.dValue = B.dValue * C.dValue; A.valid=C.valid; }
expr(A) ::= expr(B) DIVIDE expr(C).       {
                                              if( C.dValue != 0.0 )
                                                  A.dValue = B.dValue / C.dValue;
                                              else
                                                  pEval->parseError( "Divide by zero" );

                                              A.valid = C.valid;
                                          }
expr(A) ::= PARENL expr(B) PARENR.        { A.dValue = B.dValue; A.valid = B.valid; }