I am trying to write some BNF (not EBNF) to describe the various elements of the following code fragment which is in no particular programming language but would be syntactically correct in VBA.
If Temperature <=0 Then
Description = "Freezing"
End If
So far I have come up with the BNF at the bottom of this post (I have not yet described string, number or identifier).
What perplexes me is the second line of code, Description = "Freezing", in which I am assigning a string literal to an identifier. How should I deal with this in my BNF?
I am tempted to simply adjust my definition of a factor like this...
<factor> ::= <identifier> | <number> | <string_literal> | (<expression)>
...after all, in VBA an arithmetic expression containing a string or a string variable would be syntactically correct and not picked up until run time. For example (4+3)*(6-"hi") would not be picked up as a syntax error. Is this the right approach?
Or should I leave the production for a factor as it is and redefine the assignment like this...?
<assignment> ::= <identifier> = <expression> | <identifier> = <string_literal>
I am not trying to define a whole language in my BNF, rather, I just want to cover most of the productions that describe the code fragment. Suggestions would be much appreciated.
BNF so far...
<string> ::= …
<number> ::= …
<identifier> ::= …
<assignment> ::= <identifier> = <expression>
<statements> ::= <statement> <statements>
<statement> ::= <assignment> | <if_statement> | <for_statement> | <while_statement> | …
<expression> ::= <expression> + <term> | <expression> - <term> | <term>
<term> ::= <term> * <factor> | <term> / <factor> | <factor>
<factor> ::= <identifier> | <number> | (<expression)>
<relational_operator> ::= < | > | <= | >= | =
<condition> ::= <expression> <relational_operator> <expression>
<if_statement> ::= If <condition> Then <statement>
| If <condition> Then <statements> End If
| If <condition> Then <statements> Else <statements> End If
Consider the code sample:
X = "hi"
Y = 6 - X
The 6 - X
expression is an error, but you can't make it a syntax error using just a context-free grammar. Similarly for:
If Temperature <= X Then ...
Instead of catching such type errors via the grammar, you'll have to catch them later, either statically or dynamically. And given that you have to do that analysis anyway, there's not much point trying to catch any type errors (express any type constraints) in the grammar.
So go with your first solution, adding <string_literal>
to <factor>
.