Backus Naur Form Assoicativity - bnf

Is this the correct way to implement right associativity for Exponentiation PowExp? So that 2^3^4 is actually (2^(3^4))
<Exp> ::= <Exp> + <MulExp>
| <Exp> - <MulExp>
| <MulExp>
<MulExp> ::= <MulExp> * <PowExp>
| <MulExp> / <PowExp>
| <PowExp>
<PowExp> ::= <NegExp> ^ <PowExp>
|<NegExp>
<NegExp> ::= - <RootExp>
| <RootExp>
<RootExp> ::= ( <Exp> )
| 1 | 2 | 3 | 4

The way you've written it is correct.
Incidentally, you might want to reconsider your hierarchy; in regular math, −34 is −(34), not (−3)4. So you might want - 3 ^ 4 to mean - (3 ^ 4), in which case NegExp would include PowExp rather than the other way around. (But I suppose it could be confusing if -3 ^ 4 means -(3 ^ 4), so maybe there's no intuitive order-of-operations here? Another possibility is to require parentheses for either reading, by having PowExp and NegExp both depend directly on RootExp.)

Related

Recursive macro makes infinite recursion

I made a simple macro that returns the taken parameter.
macro_rules! n {
($n:expr) => {{
let val: usize = $n;
match val {
0 => 0,
_ => n!(val - 1),
}
}};
}
When I compile this code with the option external-macro-backtrace, it raises an error:
error: recursion limit reached while expanding the macro `n`
--> src/main.rs:15:18
|
10 | macro_rules! n {
| _-
| |_|
| |
11 | | ($n:expr) => {{
12 | | let val: usize = $n;
13 | | match val {
14 | | 0 => 0,
15 | | _ => n!(val - 1),
| | ^^^^^^^^^^^
| | |
| | in this macro invocation
16 | | }
17 | | }};
18 | | }
| | -
| |_|
| |_in this expansion of `n!`
| in this expansion of `n!`
...
31 | | n!(1);
| | ------ in this macro invocation
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
I changed the recursion_limit to 128 and higher, but the compiler error message just increase as well. Even when I call n!(0) it makes the same error. I think it is infinite recursion, but I can't find the reason.
Well, it really is an infinite recursion. Check what your macro invocation n!(0) will be expanded into:
{
let val: usize = 0;
match val {
0 => 0,
_ => n!(0 - 1),
}
}
...and since there's no way for argument of n! to stop growing negative, it'll repeat (with n!(0 - 1 - 1) in the second match arm, then n!(0 - 1 - 1 - 1) etc.) infinitely.
The key point here is that the macro expansion happens in compile-time, while the match statement you're trying to use to limit the recursion is invoked only at run-time and can't stop anything from appear before that. Unhappily, there's no easy way to do this, since Rust won't evaluate macro arguments (even if it's a constant expression), and so just adding the (0) => {0} branch to the macro won't work, since the macro will be invoked as (for example) n!(1 - 1).

Convert EBNF to BNF

I am struggling to convert this EBNF to BNF. Using the image:
I converted this to EBNF and would like to now convert this to BNF.
The EBNF I have two alternatives:
number_constant ::= ( | "-") digit+ ("." digit+ | )
number_constant ::= "-"? digit+ ("." digit+)?
The part where I am struggling is the middle of the diagram, I have digit defined as 1-9 so can't use digit as keyword. I was thinking of breaking down the diagram such as the first part:
<min> ::= ' ' | "-"
Then for the mid part:
<dig> ::= <digit> | <digit> <dig>
Combined this would look simply like:
<number_constant> ::= <min> <dig> <last_part>
Then I am unsure of the last part.
Any help is appreciated.
Your dig solution seems correct.
The last part can be implemented with:
<last_part> ::= "." <dig> | ""
Extended BNF sure lets you have things a lot more concise.
Here's a variation based on the semantics of what goes into making up a decimal number:
<number_constant> ::= <integer>
| <integer> '.' <whole_number>
<integer> ::= <integer>
| '- <whole_number>
<whole_number> ::= Digit
| <whole_number> Digit

Representing simple mathematics using BNF

I have written the following BNF "code", which attempts to describe simple mathematics using BNF. The issue I am having is that I have no idea how to add parentheses (brackets).
Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9";
Digits ::= <Digit>|<Digit><Digit>;
Number ::= <Digits>|<Digits>.<Digits>;
Addition ::= <Value> + <Value>;
Subtraction ::= <Value> - <Value>;
Multiplication ::= <Value> * <Value>;
Division ::= <Value> / <Value>;
Value ::= <Number>|<Addition>|<Subtraction>|<Multiplication>|<Division>;
The other issue is that I'm not sure that the BNF is 100% correct, as the Value "description" doesn't look right to me.
Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9";
Digits ::= <Digit>|<Digit><Digits>;
Number ::= <Digits>|<Digits>.<Digits>;
Operator ::= "+" | "-" | "*" | "/"
Bracket_Left ::= "("
Bracket_Right ::= ")"
Value ::= <Number>|<Bracket_Left><Value><Bracket_Right>|<Value><Operator><Value>
Maybe not the most elegant solution, but should work. Always keep in mind the power of recursion.
If you are after operator precedence too, you should use well known method by a recursion (right one in my example):
AddSub ::= <MulDiv> ("+" | "-") <AddSub> | <MulDiv>;
MulDiv ::= <Brackets> ("*" | "/") <MulDiv> | <Brackets>;
Brackets ::= "(" <AddSub> ")" | <Decimal>;
Decimal ::= <Integer> "." <Integer> | <Integer>;
Integer ::= <Digit> <Integer> | <Digit>;
Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9";
and operator precedence is automatically followed by parser, without further intervention. I didn't invent this method, it is there for decades, but I have to admit it's kind of genial.

What would the conversion of this from EBNF to BNF be? Also, what is the leftmost derivation?

I need to convert this from EBNF to BNF.
<statement> ::= <ident> = <expr>
<statement> ::= IF <expr> THEN <statement> [ ELSE <statement> ] END
<statement> ::= WHILE <expr> DO <statement> END
<statement> ::= BEGIN <statement> {; <statement>} END
Also, I'm stuck on this one:
E -> E+T | E-T | T
T -> T*F | T/F | F
F -> (E) | VAR | INT
VAR -> a | b | c
INT -> 0 | 1 | 2| 3 | 4| 5 | 6 | 7 | 8 | 9
After modifying the grammer to add a ^ operator, What is the leftmost derivation that your grammar assigns to the expression a^2^b*(c+1)? You may find it convenient to sketch the parse tree for this expression first, and then figure out the leftmost derivation from that.
I added G -> F^G | G and then got G 2 G b E as my answer but am not sure if that is correct.

Find out the language generated, given a context-free grammar?

Should I manually apply the production rules to find out the language generated by this grammar? This is tedious, is there any trick/tip to speed up things?
G = {{S, B}, {a, b}, P, S}
P = {S -> aSa | aBa, B -> bB | b}
EDIT: I found Matajon's answer a good one, that is thinking about each language generated by non-terminal symbol and then combine them.
But I'm still stuck when I have to solve some complicated examples like this:
G = {{S, R, T}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, P, S}
P = {S -> A | AS | BR | CT,
R -> AR | BT | C | CS,
T -> AT | B | BS | CR,
A -> 0 | 3 | 6 | 9,
B -> 1 | 4 | 7,
C -> 2 | 5 | 8}
Crazy, isn't it? Taken from past exams (programming languages course).
I don't know any general trick, but usually it helps to think about the language generated from each non-terminal.
In your example language generated from B is obviously L(B) = {b}^+. Then you think about S rules, using the first rule, you can generate sentencial forms {a^n.S.a^n | n >= 1}. If you use second rule on these sentencial forms or on S alone you can generate sentencial forms {a^n.B.a^n | n >= 1}.
Rest is pretty easy, you combine these two things and get L(G) = {a^n.b^+.a^n | n >= 1}
By the way, in the definition of grammar terminals and nonterminals are sets, not tuples. And third component is production rules, not start symbol. So you should write G = {{S, B}, {a, b}, P, S}.
Edit
Actually, there is a way to solve your second example without much thinking just by following something like a cookbook. Because, language generated by your second context-free grammar is in fact regular.
When you substitute rules for A, B and C to first three rules, you get
P' = {S -> 0 | 3 | 6 | 9 | 0S | 3S | 6S | 9S | 1R | 4R | 7R | 2T | 5T | 8T
R -> 0R | 3R | 6R | 9R | 1T | 4T | 7T | 2 | 5 | 8 | 2S | 5S | 8S
T -> 0T | 3T | 6T | 9T | 1 | 4 | 7 | 1S | 4S | 7S | 2R | 5R | 8R}
And P' is regular grammar. Because of that, you can convert it to nondeterministic finite automaton (there is really simple way, look for it) and then convert resulting NFA to the regular expression (this is not so simple but if you follow an algorithm and don't get lost, you should be ok). And it from regular expression it is easy to tell what language it describes.
Also, once you have NFA for this language you can look at it and determine what it does logically (it has something to do with counts of 1,4,7 and 2,5,8 in the word and mod 3 of their difference. Think it through, it is your homework, afterall :-) )
Of course, if you don't context-free grammar generating regular language you can't use this trick. There is no general way to tell what language the grammar generates (language equality problem for CFG's is undecideable), you have to think about every single example and look for similarities and patterns in it's logical structure.
I think you'll just need to apply the production rules.

Resources