I want to implement an interpreter for a multi notation (prefix, infix, and postfix) arithmetic language. Its grammar description in EBNF is given below. How can I code this in Javacc?
< Process> --> PROCESS id ; <First Section> <SecondSection>
<First Section> --> VARIABLES [<Variable List>];
<First List> --> <First Def> | <First Def>, <First List>
<First Def> --> <First Name> [ EQUAL integer_literal ]
<First Name> --> id
<Second Section> --> COMMANDS {<Statement>;}
<Statement> --> <Input Statement> | <Output Statement> | <Assignment Statement>
<Input Statement> --> READ 'message ' <First Name>
<Output Statement> --> WRITE 'message ' [ <Expression>]
<Assignment Statement> --> <First Name> <-- <Expression>
<Expression> --> <PrefixExp> | <InfixExp> | <PostfixExp>
<InfixExp> --> <Term> | <InfixExp> (PLUS | MINUS) <Term>
<Term> --> <Factor> | <Term> (MULTIPLICATION | DIVISION) <Factor>
<Factor> --> integer_literal | <First Name> | ( <InfixExp> )
<PrefixExp> --> <Operator> <PrefixExp> <PrefixExp>
<PrefixExp> --> integer_literal | <First Name>
<PostfixExp> --> <PostfixExp> <PostfixExp> <Operator>
<PostfixExp> --> integer_literal | <First Name>
<Operator> --> (ADD | SUBSTRACT | MULTIPLY | DIVIDE)
Don't do it! Your grammar, as it stands, is ambiguous. First rewrite the grammar in EBNF form to an unambiguous and non-left-recursive form. After you have done that, it will be ready to convert to JavaCC.
For example, consider a command
write 'hello' 1
is the 1 a prefix expression, a postfix expression, or an infix expression? Your grammar permits all three interpretation.
For starters:
Read the JavaCC FAQ.
Browse through the existing JavaCC Grammars here or here.
Take one and try to gradually build your grammar based on it.
Related
I am writing firebase security rules, and I am attempting to get a document that may have a space in its documentID.
I have the following snippet which works well when the document does not have a space
function isAdminOfCompany(companyName) {
let company = get(/databases/$(database)/documents/Companies/$(companyName));
return company.data.authorizedUsers[request.auth.uid].access == "ADMIN;
}
Under the collection, "Companies", I have a document called "Test" and another called "Test Company" - Trying to get the document corresponding to "Test" works just fine, but "Test Company" does not seem to work, as the company variable (first line into the function) is equal to null as per the firebase security rules "playground".
My thought is that there is something to do with URL encoding, but replacing the space in a documentID to "%20" or a "+" does not change the result. Perhaps spaces are illegal characters for documentIDs (https://cloud.google.com/firestore/docs/best-practices lists a few best practices)
Any help would be appreciated!
EDIT: As per a few comments, I Will add some additional images/explanations below.
Here is the structure of my database
And here is what fields are present in the user documents
In short, the following snippet reproduces the problem (I am not actually using this, but it demonstrates the issue the same way)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{user} {
allow update: if findPermission(resource.data.company) == "MASTER"
}
function findPermission(companyName) {
let c = get(path("/databases/" + database + "/documents/Companies/" + companyName));
return c.data.authorizedUsers[request.auth.uid].access;
}
}
}
When I try to update a user called test#email.com (which belongs to company "Test"), the operation is permitted, and everything works exactly as expected.
The issue arises when a user, called test2#email.com, who belongs to company "Test Company" comes along and makes the same request (with authorization email/uid updated in playground, to match what is actually found in the company structure), the request fails. The request fails, since the get() call (line 1 of the function) cannot find the Company document corresponding to "Test Company" - indicated by the variable "c" being null in the screenshot (see below) - IT IS NOT NULL WHEN LOOKING FOR "Test"
Below is a screenshot of the error message, as well as some of the relevant variables when the error occurs
Check to see what type of space just in case it is another non-printable character. You could convert it to Unicode, and check what it might be. However, it is considered bad practice to use spaces in naming variables and data structures. There are so many different types to consider.
| Unicode | HTML | Description | Example |
|---------|--------|--------------------|---------|
| U+0020 |   | Space | [ ] |
| U+00A0 |   | No-Break Space | [ ] |
| U+2000 |   | En Quad | [ ] |
| U+2001 |   | Em Quad | [ ] |
| U+2002 |   | En Space | [ ] |
| U+2003 |   | Em Space | [ ] |
| U+2004 |   | Three-Per-Em Space | [ ] |
| U+2005 |   | Four-Per-Em Space | [ ] |
| U+2006 |   | Six-Per-Em Space | [ ] |
| U+2007 |   | Figure Space | [ ] |
| U+2008 |   | Punctuation Space | [ ] |
| U+2009 |   | Thin Space | [ ] |
| U+200A |   | Hair Space | [ ] |
I am trying to get started with sulu as a CMS , and going with the flow of the steps as mentioned in the 'Getting Started' guide , I have setup my virtual server as 'personal' and this is my webspace
<?xml version="1.0" encoding="utf-8"?>
<webspace xmlns="http://schemas.sulu.io/webspace/webspace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.sulu.io/webspace/webspace http://schemas.sulu.io/webspace/webspace-1.0.xsd">
<name>personal</name>
<key>personal</key>
<localizations>
<localization language="en" default="true"/>
<localization language="de"/>
</localizations>
<theme>
<key>default</key>
<default-templates>
<default-template type="page">default</default-template>
<default-template type="homepage">overview</default-template>
</default-templates>
<error-templates>
<error-template default="true">ClientWebsiteBundle:views:error.html.twig</error-template>
<error-template code="404">ClientWebsiteBundle:views:error404.html.twig</error-template>
</error-templates>
</theme>
<navigation>
<contexts>
<context key="main">
<meta>
<title lang="de">Hauptnavigation</title>
<title lang="en">Mainnavigation</title>
</meta>
</context>
</contexts>
</navigation>
<portals>
<portal>
<name>personal</name>
<key>personal</key>
<resource-locator>
<strategy>tree</strategy>
</resource-locator>
<environments>
<environment type="prod">
<urls>
<url>personal/{localization}</url>
</urls>
</environment>
<environment type="stage">
<urls>
<url>personal/{localization}</url>
</urls>
</environment>
<environment type="dev">
<urls>
<url>personal/{localization}</url>
</urls>
</environment>
</environments>
</portal>
</portals>
</webspace>
I have built the dev and the prod version using
php app/console sulu:build {env}
is there any sulu log I can see , I have made no other changes except the fact that my xml is named as personal.xml. Help ?
When I try to find the routes in the phpcrsh shell , i found a node
jcr:primaryType | NAME (15) | nt:unstructured |
jcr:mixinTypes | NAME (9) | [0] sulu:path |
jcr:uuid | STRING (36) | c4419533-8aff-4799-ac89-c8401a84f7e5 |
sulu:history | BOOLEAN (0) | false |
sulu:content | REFERENCE (36) | ad186c73-6b01-4d13-8b4e-48b7128b1712 |
sulu:created | DATE (29) | 2016-05-29T12:45:13+05:30 |
sulu:changed | DATE (29) | 2016-05-29T12:45:13+05:30 |
1 nodes in set (0.000009 sec)
I need to append a key/value pair value into a file, in such logic.
For example, the file contains such value already:
key1=value1
key2=value2
and if the new pair is key3=value3, it will be appended, but if it was key1=value4, the existing one would be updated.
Can such thing be done in ONE unix command ?
It depends on what you mean by "command". A UNIX command can be an arbitrarily long pipeline/sequence of simpler commands strung together.
There are any number of ways you could do it then, such as with:
awk '
BEGIN { s = "key1=value\n" }
/^key1=/ { printf s; s = ""; next }
{ print }
END { printf s }
' infile >outfile && mv outfile infile
The following transcript shows this in action:
pax> printf '\nkey1=value1\nkey2=value2\nkey3=value3\n' | awk '
...> BEGIN {s="key2=something_else\n"}
...> /^key2=/ {printf s;s="";next}
...> {print}
...> END {printf s}'
key1=value1
key2=something_else
key3=value3
pax> printf '\nkey1=value1\nkey2=value2\nkey3=value3\n' | awk '
...> BEGIN {s="key4=something_new\n"}
...> /^key4=/ {printf s;s="";next}
...> {print}
...> END {printf s}'
key1=value1
key2=value2
key3=value3
key4=something_new
You could probably also do it without a && conjunction by using in-place sed editing, at the cost of a (probably) more complicated command.
Not in one command, but in one line, (albeit word-wrapped below), 1st update 'key1':
echo "key1=value4" | join -t '=' -j 1 -a 1 -a 2 keys.txt - \
| sed 's/=[^=]*=/=/' | sponge keys.txt
cat keys.txt
Output:
key1=value4
key2=value2
Add 'key3':
echo "key3=value3" | join -t '=' -j 1 -a 1 -a 2 keys.txt - \
| sed 's/=[^=]*=/=/' | sponge keys.txt
cat keys.txt
Output:
key1=value4
key2=value2
key3=value3
Notes: I've started with keys.txt single spaced, as that's what join prefers. sponge is from Debian's moreutils package. A fringe benefit of join is that if first we input key6, and then later key5, join outputs the keys in numerical order.
I am currently enrolled in a computer architecture class and I'm trying to do one of the homework assignments.
The assignment is on BNF and even after having the lecture, reading the slides, and looking online, I'm still stumped.
Here is my grammar:
<expr>-><expr> + <term> |
<expr> - <term> |
<term>
<term>-><term> * <factor> |
<term> / <factor> |
<factor>
<factor>->(<expr>)|<id>
<id>->A|B|C|D
What would the parse tree look like for A + (C - D) / B?
I just need a little guidance and I will be able to do this problem for myself. My teacher does not explain very well so I was hoping for explanation in laymans terms of how to go about this?
Though it is not stated, I assume that we are trying to interpret the string A + (C - D) / B as an <expr> (as no other parse works).
<expr> is a nonterminal symbol, i.e. it does not occur literally the final string. Rather, the first rule (<expr> -> <expr> + <term> | <expr> - <term> | <term>) tells us what symbols to expect in a string that is an <expr>. It states that an <expr> can be made from one of the following options:
<expr> + <term>, i.e. an <expr> followed by + followed by a <term>, or
<expr> - <term>, (interpreted similarly), or
<term>
Without getting into the details of how a parser would mechanically make the decision, we have to choose one of these options to proceed building a parse tree. I will choose the first option (<expr> + <term>), which assumes that the first <expr> will represent the A in the message, the + is literally the +, and the <term> is the remaining (C - D) / B. Thus the beginning of our parse tree looks like:
<expr>
/ | \
/ | \
<expr> + <term>
This is not yet a complete parse, as it is not immediately clear from the rules that an <expr> can give the result A. Likewise (C - D) / B is not an immediate option for <term>. We can answer the first objection by seeing that:
<expr> can be <term> (by the third option of the rule for <expr>)
<term> in turn can be <factor> (by the third option of the rule for <term>)
<factor> can be <id> (by the second option of the rule for <factor>), and finally
<id> can be A (by the first option of the rule for <id>)
This line of reasoning fills in the parse tree as follows:
<expr>
/ | \
/ | \
<expr> | <term>
| |
<term> |
| |
<factor>|
| |
<id> |
| |
A +
I hope that this gives you an idea of the process and the meaning of the rules, so that you can show further how <term> can give (C - D) / B and thus fill in the rest of the tree.
This question is a generalized version of the Output of ZipArchive() in tree format question.
Just before I am wasting time on writing this (*nix command line) utility, it will be a good idea to find out if someone already wrote it. I would like a utility that will get as its' standard input a list such as the one returned by find(1) and will output something similar to the one by tree(1)
E.g.:
Input:
/fruit/apple/green
/fruit/apple/red
/fruit/apple/yellow
/fruit/banana/green
/fruit/banana/yellow
/fruit/orange/green
/fruit/orange/orange
/i_want_my_mommy
/person/men/bob
/person/men/david
/person/women/eve
Output
/
|-- fruit/
| |-- apple/
| | |-- green
| | |-- red
| | `-- yellow
| |-- banana/
| | |-- green
| | `-- yellow
| `-- orange/
| |-- green
| `-- orange
|-- i_want_my_mommy
`-- person/
|-- men/
| |-- bob
| `-- david
`-- women/
`-- eve
Usage should be something like:
list2tree --delimiter="/" < Input > Output
Edit0: It seems that I was not clear about the purpose of this exercise. I like the output of tree, but I want it for arbitrary input. It might not be part of any file system name-space.
Edit1: Fixed person branch on the output. Thanks, #Alnitak.
In my Debian 10 I have tree v1.8.0. It supports --fromfile.
--fromfile
Reads a directory listing from a file rather than the file-system. Paths provided on the command line are files to read from rather than directories to search. The dot (.) directory indicates that tree should read paths from standard input.
This way I can feed tree with output from find:
find /foo | tree -d --fromfile .
Problems:
If tree reads /foo/whatever or foo/whatever then foo will be reported as a subdirectory of .. Similarly with ./whatever: . will be reported as an additional level named . under the top level .. So the results may not entirely meet your formal expectations, there will always be a top level . entry. It will be there even if find finds nothing or throws an error.
Filenames with newlines will confuse tree. Using find -print0 is not an option because there is no corresponding switch for tree.
I whipped up a Perl script that splits the paths (on "/"), creates a hash tree, and then prints the tree with Data::TreeDumper. Kinda hacky, but it works:
#!/usr/bin/perl
use strict;
use warnings;
use Data::TreeDumper;
my %tree;
while (<>) {
my $t = \%tree;
foreach my $part (split m!/!, $_) {
next if $part eq '';
chomp $part;
$t->{$part} ||= {};
$t = $t->{$part};
}
}
sub check_tree {
my $t = shift;
foreach my $hash (values %$t) {
undef $hash unless keys %$hash;
check_tree($hash);
}
}
check_tree(\%tree);
my $output = DumpTree(\%tree);
$output =~ s/ = undef.*//g;
$output =~ s/ \[H\d+\].*//g;
print $output;
Here's the output:
$ perl test.pl test.data
|- fruit
| |- apple
| | |- green
| | |- red
| | `- yellow
| |- banana
| | |- green
| | `- yellow
| `- orange
| |- green
| `- orange
|- i_want_my_mommy
`- person
|- men
| |- bob
| `- david
`- women
`- eve
An other tool is treeify written in Rust.
Assuming you have Rust installed get it with:
$ cargo install treeify
So, I finally wrote what I hope will become the python tree utils. Find it at http://pytree.org
I would simply use tree myself but here's a simple thing that I wrote a few days ago that prints a tree of a directory. It doesn't expect input from find (which makes is different from your requirements) and doesn't do the |- display (which can be done with some small modifications). You have to call it like so tree <base_path> <initial_indent>. intial_indent is the number of characters the first "column" is indented.
function tree() {
local root=$1
local indent=$2
cd $root
for i in *
do
for j in $(seq 0 $indent)
do
echo -n " "
done
if [ -d $i ]
then
echo "$i/"
(tree $i $(expr $indent + 5))
else
echo $i
fi
done
}