Nested fibonacci? - nested

First off this is for school and I'm not looking for a handout. Just guidance.
I need to write a fibonacci function using very basic tools.
I have these tools (from a language we wrote in Java):
if-else
for-loop
arithmetic
assignment
infinite nesting
any number of statements.
The problem is any nest or statement can only have one resultant statement or nest.
For example, this is okay:
repeat b to 7 by 2
{
repeat a to 5 by 1
{
a = a + 1
}
}
but this is not okay:
repeat x to 5 by 1
{
x = x + 1
y = x
}
Here is the relevant section of the grammar:
<code> ::= <statement> <code>
<code> ::= <statement>
<statement> ::= load <string>
<statement> ::= print <expr>
<statement> ::= input <var>
<statement> ::= if <cond> <statement>
<statement> ::= if <cond> <statement> else <statement>
<statement> ::= repeat <var> to <val> by <val>
<statement> ::= <var> = <expr>
<expr> ::= <val> + <val>
<expr> ::= <val> - <val>
<expr> ::= <val> * <val>
<expr> ::= <val> / <val>
<expr> ::= <val>
<cond> ::= <val> == <val>
<cond> ::= <val> > <val>
<cond> ::= <val> < <val>
<val> ::= <num>
<val> ::= <var>
I can't figure out how the heck I'm going to get this done. Recursion is not allowed.
Any pointers?
Again, not looking for the solution, just guidance.
Thanks so much

Like this? use 3 variables that represent the last 3 numbers of the sequence?. What you really want is to have a simple:
a = 0
b = 1
repeat x to 5 by 1
{
c = a + b
a = b
b = c
}
But this is not allowed. However, since if-else counts as 1 statement, you can simply (ab)use this to do 3 statements by doing 1 statement in each part of a repeat:
a = 0
b = 1
repeat x to 5 by 1
{
repeat y to 3 by 1
{
if y < 2
{
if y < 1
{
c = a + b
}
else
{
a = b
}
}
else
{
b = c
}
}
}

Related

Beginner: ANTLR does misbehave?

I have a pretty simple grammer to parse Dice-expressions.
grammar Dice;
function : ( dice | binaryOp | DIGIT );
binaryOp: dice OPERATOR function | DIGIT OPERATOR function;
dice : DIGIT DSEPERATOR DIGIT EXPLODING?;
DSEPERATOR : ( 'd' | 'D' | 'w' | 'W' );
EXPLODING : ( '*' );
OPERATOR : ( ADD | SUB );
ADD : '+';
SUB : '-';
DIGIT : ('0'..'9')+;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
It SHOULD parse something like 3D6+2D10 but it doesn't. I get a no viable alternative at input '2d10' with this partial result:
(function (binaryOp (dice 3 W 6) + (function 2 d 10)))
and I do not understand why. Could you please help me understanding this?
Since the function rule is recursive (eventually), you need to add a rule explicitly for the top level so that ANTLR can infer "oh, this top level rule should be the one that implicitly can accept an EOF at the end of input", and then parse from that.
I added a line:
start : function ;
to your grammar, and can now parse:
$ echo "3D6+2D10" | java -cp antlr-4.7.1-complete.jar:. org.antlr.v4.gui.TestRig Dice start -tree
(start (function (binaryOp (dice 3 D 6) + (function (dice 2 D 10)))))

Antlr4 expressions are chaining

from what i have read the way i defined my 'expression' this should provide me with the following:
This is my input:
xyz = a + b + c + d
This should be my output:
xyz = ( ( a + b ) + ( c + d) )
But instead i get:
xyz = ( a + (b + (c + d) ) )
I bet this has been solved before and i just wasnt able to find the solution.
statementList : s=statement sl=statementList #multipleStatementList
| s=statement #singleStatementList
;
statement : statementAssign
| statementIf
;
statementAssign : var=VAR ASSIGN expr=expression #overwriteStatementAssign
| var=VAR PLUS ASSIGN expr=expression #addStatementAssign
| var=VAR MINUS ASSIGN expr=expression #subStatementAssign
;
;
expression : BRACKET_OPEN expr=expression BRACKET_CLOSE #priorityExp
| left=expression operand=('*'|'/') right=expression #mulDivExp
| left=expression operand=('+'|'-') right=expression #addSubExp
| <assoc=right> left=expression POWER right=expression #powExp
| variable=VAR #varExp
| number=NUMBER #numExp
;
BRACKET_OPEN : '(' ;
BRACKET_CLOSE : ')' ;
ASTERISK : '*' ;
SLASH : '/' ;
PLUS : '+' ;
MINUS : '-' ;
POWER : '^' ;
MODULO : '%' ;
ASSIGN : '=' ;
NUMBER : [0-9]+ ;
VAR : [a-z][a-zA-Z0-9\-]* ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
If you want the expression
xyz = ( ( a + b ) + ( c + d) )
Then you'll need to control the binding of the + operator with parentheses just as you've done in your expected output. Otherwise, with
xyz = ( a + (b + (c + d) ) )
is the way the parser is going to parse it because all the + operators have the same precedence, and the parser continues parsing until it reaches the end of the expression.
It recursively applies
left=expression operand=('+'|'-') right=expression
until the expression is completed.
and you get the grouping you got. So use those parentheses, that's what they're for if you want to force the order of expression evaluation. ;)
If you change your input to
xyz = a * b + c + d
you'll see what I mean about the precedence, because the multiplication rule appears before the addition rule -- and hence binds earlier -- which is a mathematical convention (lacking parentheses to group terms.)
You're doing it right and the parser is too. Just group what you want if you want a specific binding order.

How to do Priority of Operations (+ * - /) in my grammars?

I define my own grammars using antlr 4 and I want to build tree true According to Priority of Operations (+ * - /) ....
I find sample on do Priority of Operations (* +) it work fine ...
I try to edit it to add the Priority of Operations (- /) but I failed :(
the grammars for Priority of Operations (+ *) is :
println:PRINTLN expression SEMICOLON {System.out.println($expression.value);};
expression returns [Object value]:
t1=factor {$value=(int)$t1.value;}
(PLUS t2=factor{$value=(int)$value+(int)$t2.value;})*;
factor returns [Object value]: t1=term {$value=(int)$t1.value;}
(MULT t2=term{$value=(int)$value*(int)$t2.value;})*;
term returns [Object value]:
NUMBER {$value=Integer.parseInt($NUMBER.text);}
| ID {$value=symbolTable.get($value=$ID.text);}
| PAR_OPEN expression {$value=$expression.value;} PAR_CLOSE
;
MULT :'*';
PLUS :'+';
MINUS:'-';
DIV:'/' ;
How I can add to them the Priority of Operations (- /) ?
In ANTLR3 (and ANTLR4) * and / can be given a higher precedence than + and - like this:
println
: PRINTLN expression SEMICOLON
;
expression
: factor ( PLUS factor
| MINUS factor
)*
;
factor
: term ( MULT term
| DIV term
)*
;
term
: NUMBER
| ID
| PAR_OPEN expression PAR_CLOSE
;
But in ANTLR4, this will also work:
println
: PRINTLN expression SEMICOLON
;
expression
: NUMBER
| ID
| PAR_OPEN expression PAR_CLOSE
| expression ( MULT | DIV ) expression // higher precedence
| expression ( PLUS | MINUS ) expression // lower precedence
;
You normally solve this by defining expression, term, and factor production rules. Here's a grammar (specified in EBNF) that implements unary + and unary -, along with the 4 binary arithmetic operators, plus parentheses:
start ::= expression
expression ::= term (('+' term) | ('-' term))*
term ::= factor (('*' factor) | ('/' factor))*
factor :: = (number | group | '-' factor | '+' factor)
group ::= '(' expression ')'
where number is a numeric literal.

Error when generating a grammar for chess PGN files

I made this ANTLR4 grammar in order to parse a PGN inside my Java programm, but I can't manage to solve the ambiguity in it :
grammar Pgn;
file: game (NEWLINE+ game)*;
game: (tag+ NEWLINE+)? notation;
tag: [TAG_TYPE "TAG_VALUE"];
notation: move+ END_RESULT?;
move: MOVE_NUMBER\. MOVE_DESC MOVE_DESC #CompleteMove
| MOVE_NUMBER\. MOVE_DESC #OnlyWhiteMove
| MOVE_NUMBER\.\.\. MOVE_DESC #OnlyBlackMove
;
END_RESULT: '1-0'
| '0-1'
| '1/2-1/2'
;
TAG_TYPE: LETTER+;
TAG_VALUE: .*;
MOVE_NUMBER: DIGIT+;
MOVE_DESC: .*;
NEWLINE: \r? \n;
SPACES: [ \t]+ -> skip;
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
And this is the error output :
$ antlr4 Pgn.g4
error(50): Pgn.g4:6:6: syntax error: 'TAG_TYPE "TAG_VALUE"' came as a complete surprise to me while matching alternative
I think the error come from the fact that " [ ", " ] " and ' " ' can't be used freely, neither in Grammar nor Lexer.
Helps or advices are welcome.
Looking at the specs for PGN, http://www.thechessdrum.net/PGN_Reference.txt, I see there's a formal definition of the PGN format there:
18: Formal syntax
<PGN-database> ::= <PGN-game> <PGN-database>
<empty>
<PGN-game> ::= <tag-section> <movetext-section>
<tag-section> ::= <tag-pair> <tag-section>
<empty>
<tag-pair> ::= [ <tag-name> <tag-value> ]
<tag-name> ::= <identifier>
<tag-value> ::= <string>
<movetext-section> ::= <element-sequence> <game-termination>
<element-sequence> ::= <element> <element-sequence>
<recursive-variation> <element-sequence>
<empty>
<element> ::= <move-number-indication>
<SAN-move>
<numeric-annotation-glyph>
<recursive-variation> ::= ( <element-sequence> )
<game-termination> ::= 1-0
0-1
1/2-1/2
*
<empty> ::=
I highly recommend you to let your ANTLR grammar resemble that as much as possible. I made a small project with ANTLR 4 on Github which you can try out: https://github.com/bkiers/PGN-parser
The grammar (without comments):
parse
: pgn_database EOF
;
pgn_database
: pgn_game*
;
pgn_game
: tag_section movetext_section
;
tag_section
: tag_pair*
;
tag_pair
: LEFT_BRACKET tag_name tag_value RIGHT_BRACKET
;
tag_name
: SYMBOL
;
tag_value
: STRING
;
movetext_section
: element_sequence game_termination
;
element_sequence
: (element | recursive_variation)*
;
element
: move_number_indication
| san_move
| NUMERIC_ANNOTATION_GLYPH
;
move_number_indication
: INTEGER PERIOD?
;
san_move
: SYMBOL
;
recursive_variation
: LEFT_PARENTHESIS element_sequence RIGHT_PARENTHESIS
;
game_termination
: WHITE_WINS
| BLACK_WINS
| DRAWN_GAME
| ASTERISK
;
WHITE_WINS
: '1-0'
;
BLACK_WINS
: '0-1'
;
DRAWN_GAME
: '1/2-1/2'
;
REST_OF_LINE_COMMENT
: ';' ~[\r\n]* -> skip
;
BRACE_COMMENT
: '{' ~'}'* '}' -> skip
;
ESCAPE
: {getCharPositionInLine() == 0}? '%' ~[\r\n]* -> skip
;
SPACES
: [ \t\r\n]+ -> skip
;
STRING
: '"' ('\\\\' | '\\"' | ~[\\"])* '"'
;
INTEGER
: [0-9]+
;
PERIOD
: '.'
;
ASTERISK
: '*'
;
LEFT_BRACKET
: '['
;
RIGHT_BRACKET
: ']'
;
LEFT_PARENTHESIS
: '('
;
RIGHT_PARENTHESIS
: ')'
;
LEFT_ANGLE_BRACKET
: '<'
;
RIGHT_ANGLE_BRACKET
: '>'
;
NUMERIC_ANNOTATION_GLYPH
: '$' [0-9]+
;
SYMBOL
: [a-zA-Z0-9] [a-zA-Z0-9_+#=:-]*
;
SUFFIX_ANNOTATION
: [?!] [?!]?
;
UNEXPECTED_CHAR
: .
;
For a version with comments, see: https://github.com/bkiers/PGN-parser/blob/master/src/main/antlr4/nl/bigo/pp/PGN.g4

Are characters classes allowed in ANTLR4?

Are character classes supported in ANTLR 4 lexers? I saw some examples that looked like this is OK:
LITERAL: [a-zA-z]+;
but what I found is that it matches the string "OR[" with the opening bracket. Using ranges worked:
LITERAL: ('a'..'z' | 'A'..'Z')+;
and only identified "OR" as the LITERAL. Here is an example:
grammar Test;
#members {
private void log(String msg) {
System.out.println(msg);
}
}
parse
: expr EOF
;
expr
: atom {log("atom(" + $atom.text + ")");}
| l=expr OR r=expr {log("IOR:left(" + $l.text + ") right(" + $r.text + "}");}
| (OR '[' la=atom ra=atom ']') {log("POR:left(" + $la.text + ") right(" + $ra.text + "}");}
;
atom
: LITERAL
;
OR : O R ;
LITERAL: [a-zA-z]+;
//LITERAL: ('a'..'z' | 'A'..'Z')+;
SPACE
: [ \t\r\n] -> skip
;
fragment O: ('o'|'O');
fragment R: ('r'|'R');
When given the input "OR [ cat dog ]" it parses correctly, but "OR[ cat dog ]" does not.
You can use character sets in ANTLR 4 lexers, but the ranges are case sensitive. You used [a-zA-z] where I believe you meant [a-zA-Z].

Resources