Skip to content

Commit

Permalink
A new rule with the same LHS as an existing rule adds its cases to th…
Browse files Browse the repository at this point in the history
…e existing rule
  • Loading branch information
sylvainhalle committed Aug 7, 2015
1 parent cad1443 commit 0b519df
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 16 deletions.
30 changes: 27 additions & 3 deletions Source/Parsing/src/ca/uqac/lif/bullwinkle/BnfParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,38 @@ public ParseNode getParseTree(final String input) throws ParseException
return null;
}

/**
* Adds a rule to the parser. If a rule with the same left-hand side
* already exists in the parser, the case of the rule passed as an argument
* will be added to the cases of the existing rule.
* @param rule The rule to add
*/
public void addRule(final BnfRule rule)
{
NonTerminalToken r_left = rule.getLeftHandSide();
for (BnfRule in_rule : m_rules)
{
NonTerminalToken in_left = in_rule.getLeftHandSide();
if (r_left.equals(in_left))
{
in_rule.addAlternatives(rule.getAlternatives());
break;
}
}
// No rule with the same LHS was found
m_rules.add(rule);
}

/**
* Adds a collection of rules to the parser
* @param rules The rules to add
*/
public void addRules(final Collection<BnfRule> rules)
{
m_rules.addAll(rules);
for (BnfRule rule : rules)
{
addRule(rule);
}
}

public void setStartRule(final String tokenName)
Expand Down Expand Up @@ -338,12 +362,12 @@ public void setStartRule(final NonTerminalToken token)
return null;
}
input.truncateSubstring(chars_consumed);
/*if (level == 0 && !input.isEmpty())
if (level == 0 && !input.isEmpty())
{
// The top-level rule must parse the complete string
log("FAILED: The top-level rule must parse the complete string", level);
return null;
}*/
}
return out_node;
}

Expand Down
61 changes: 53 additions & 8 deletions Source/Parsing/src/ca/uqac/lif/bullwinkle/BnfRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.IOException;
import java.io.StringReader;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
Expand All @@ -27,18 +28,39 @@

import ca.uqac.lif.util.EmptyException;

/**
* Implementation of a single rule of a BNF grammar
*/
public class BnfRule
{
/**
* A list of token strings that for all the possible cases of that rule
*/
private List<TokenString> m_alternatives;

/**
* The left-hand side of the rule. Since we deal with BNF grammars, this
* left-hand side must be a single non-terminal symbol.
*/
private NonTerminalToken m_leftHandSide;

/**
* Creates a new empty BNF rule
*/
BnfRule()
{
super();
m_alternatives = new LinkedList<TokenString>();
}

/**
* Creates a BNF rule out of a string
* @param input The string that contains a BNF rule. This string must follow
* the syntactical restrictions described in the README
* @return A BNF rule if the parsing succeeded
* @throws BnfRule.InvalidRuleException Thrown if the parsing could not be
* done correctly
*/
public static BnfRule parseRule(String input) throws BnfRule.InvalidRuleException
{
// TODO: split parsing of LHS and RHS in two methods. Then, use RHS parsing
Expand Down Expand Up @@ -119,21 +141,39 @@ else if (trimmed_word.compareTo("\uCEB5") == 0 || trimmed_word.compareTo("\u03B5
return out;
}

/**
* Sets the left-hand side of the rule
* @param t The non-terminal token that will be used for the
* left-hand side of the rule
*/
void setLeftHandSide(final NonTerminalToken t)
{
m_leftHandSide = t;
}

/**
* Adds an alternative to the rule
* @param ts The alternative to add
*/
void addAlternative(/* @NonNull */ final TokenString ts)
{
m_alternatives.add(ts);
}

/**
* Retrieves the list of all the alternatives that this rule defines
* @return A list of alternatives, each of which is a string of tokens
* (either terminal or non-terminal)
*/
List<TokenString> getAlternatives()
{
return m_alternatives;
}

/**
* Retrieves the left-hand side symbol of the rule
* @return The left-hand side symbol
*/
NonTerminalToken getLeftHandSide()
{
return m_leftHandSide;
Expand All @@ -159,7 +199,7 @@ protected static String unescapeString(String s)
}
catch (IOException e)
{
// TODO Auto-generated catch block
// Auto-generated catch block
e.printStackTrace();
}
return p.getProperty("key");
Expand All @@ -183,13 +223,6 @@ public String toString()
return out.toString();
}

public TokenString tokenize(String s)
{
TokenString out = new TokenString();
// TODO
return out;
}

public Set<TerminalToken> getTerminalTokens()
{
Set<TerminalToken> out = new HashSet<TerminalToken>();
Expand All @@ -200,6 +233,18 @@ public Set<TerminalToken> getTerminalTokens()
return out;
}

/**
* Adds a collection of alternatives to the rule
* @param alternatives The alternatives to add
*/
public void addAlternatives(Collection<TokenString> alternatives)
{
m_alternatives.addAll(alternatives);
}

/**
* Exception thrown when the parsing of a rule form a string fails
*/
public static class InvalidRuleException extends EmptyException
{
/**
Expand Down
9 changes: 8 additions & 1 deletion Source/Parsing/src/ca/uqac/lif/bullwinkle/BullwinkleCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public class BullwinkleCli
protected static final String VERSION_STRING = BullwinkleCli.class.getPackage().getImplementationVersion();

/**
* @param args
* Main loop
* @param args The command-line arguments
*/
public static void main(String[] args)
{
Expand Down Expand Up @@ -254,6 +255,12 @@ private static Options setupOptions()
"Verbose messages with level x")
.create();
options.addOption(opt);
opt = OptionBuilder
.withLongOpt("version")
.withDescription(
"Show version number")
.create();
options.addOption(opt);
return options;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ public boolean matches(final Token tok)
public int match(final String s)
{
return 0;
}
}
}
15 changes: 15 additions & 0 deletions Source/Parsing/src/ca/uqac/lif/bullwinkle/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ public int hashCode()
return m_name.hashCode();
}

@Override
public boolean equals(Object o)
{
if (o == null || !(o instanceof Token))
{
return false;
}
return equals((Token) o);
}

protected boolean equals(Token t)
{
return t.getName().compareTo(m_name) == 0;
}

public abstract boolean matches(final Token tok);

public abstract int match(final String s);
Expand Down
3 changes: 3 additions & 0 deletions Source/Parsing/src/ca/uqac/lif/util/FileReadWrite.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class FileReadWrite
* if some IOException is thrown.
* @param filename The filename to write to
* @param contents The file's contents
* @throws IOException If the writing fails
*/
public static void writeToFile(String filename, String contents) throws IOException
{
Expand All @@ -59,6 +60,7 @@ public static void writeToFile(String filename, String contents) throws IOExcep
* @param filename The name (and path) of the file to read
* @return The file's contents, and empty string if the file
* does not exist
* @throws IOException If the reading fails
*/
public static String readFile(String filename) throws IOException
{
Expand All @@ -71,6 +73,7 @@ public static String readFile(String filename) throws IOException
* @param f The file to read
* @return The file's contents, and empty string if the file
* does not exist
* @throws IOException If the reading fails
*/
public static /* @NonNull */ String readFile(File f) throws IOException
{
Expand Down
1 change: 1 addition & 0 deletions Source/Parsing/src/ca/uqac/lif/util/PackageFileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public static String readPackageFile(Class<?> c, String path)
* @param in The input stream to read
* @return The file's contents, and empty string if the file
* does not exist
* @throws IOException If the reading fails
*/
public static String readPackageFile(InputStream in) throws IOException
{
Expand Down
16 changes: 15 additions & 1 deletion Source/ParsingTest/src/ca/uqac/lif/bullwinkle/GrammarTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ public void parseGrammar5()
parseItNot("data/Grammar-10.bnf", "<S>", expression, false);
}

@Test
public void parseGrammar6()
{
String expression = "SELECT 0 AS att FROM 0 AS";
parseItNot("data/Grammar-11.bnf", "<eml_select>", expression, false);
}

@Test
public void parseGrammar7()
{
String expression = "THE TUPLES OF FILE \"a\" WHERE (a) = (0)";
ParseNode node = parseIt("data/Grammar-11.bnf", "<processor>", expression, true);
}

@Test
public void parseGrammarLtlFo1()
{
Expand All @@ -144,7 +158,7 @@ public void parseGrammarLtlFo1()
public void parseGrammarWithEpsilon1()
{
String expression = "hello hello";
ParseNode node = parseIt("data/Grammar-3.bnf", "<S>", expression, true);
ParseNode node = parseIt("data/Grammar-3.bnf", "<S>", expression, false);
int size = node.getSize();
int expected_size = 6;
if (size != expected_size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public void simpleValidGrammarFromFile()
{
fail("Valid grammar has thrown an exception when parsed.");
}
System.out.println(parser);
}

}
Loading

0 comments on commit 0b519df

Please sign in to comment.