You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by el...@apache.org on 2006/12/04 19:41:31 UTC
svn commit: r482284 [1/3] - in /labs/dungeon: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/dungeon/ src/main/java/org/apache/dungeon/meta/
src/main/java/org/apache/dungeon/meta/parser/ src/main/...
Author: elecharny
Date: Mon Dec 4 10:41:29 2006
New Revision: 482284
URL: http://svn.apache.org/viewvc?view=rev&rev=482284
Log:
First shot of sources, with a pom.xml and tests
Added:
labs/dungeon/pom.xml
labs/dungeon/src/
labs/dungeon/src/main/
labs/dungeon/src/main/java/
labs/dungeon/src/main/java/org/
labs/dungeon/src/main/java/org/apache/
labs/dungeon/src/main/java/org/apache/dungeon/
labs/dungeon/src/main/java/org/apache/dungeon/meta/
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractProduction.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractSymbol.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonException.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonTransition.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Ident.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaGrammar.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaLexeme.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaParser.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaProduction.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaRhs.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/ParserException.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Production.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Symbol.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Test.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VN.java
labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VT.java
labs/dungeon/src/main/java/org/apache/dungeon/util/
labs/dungeon/src/main/java/org/apache/dungeon/util/Position.java
labs/dungeon/src/main/java/org/apache/dungeon/util/StringTools.java
labs/dungeon/src/test/
labs/dungeon/src/test/java/
labs/dungeon/src/test/java/org/
labs/dungeon/src/test/java/org/apache/
labs/dungeon/src/test/java/org/apache/dungeon/
labs/dungeon/src/test/java/org/apache/dungeon/meta/
labs/dungeon/src/test/java/org/apache/dungeon/meta/parser/
labs/dungeon/src/test/java/org/apache/dungeon/meta/parser/MetaParserTest.java
Added: labs/dungeon/pom.xml
URL: http://svn.apache.org/viewvc/labs/dungeon/pom.xml?view=auto&rev=482284
==============================================================================
--- labs/dungeon/pom.xml (added)
+++ labs/dungeon/pom.xml Mon Dec 4 10:41:29 2006
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.directory</groupId>
+ <version>0.1.0-SNAPSHOT</version>
+ <artifactId>dungeon</artifactId>
+ <name>Apache Labs Dungeon Project</name>
+ <inceptionYear>2006</inceptionYear>
+ <packaging>jar</packaging>
+ <!--distributionManagement>
+ <site>
+ <id>apacheds.websites</id>
+ <url>scp://minotaur.apache.org/www/directory.apache.org/newsite/subprojects/asn1/</url>
+ </site>
+ </distributionManagement-->
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>nlog4j</artifactId>
+ <version>1.2.25</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/labs/dungeon</connection>
+ <developerConnection>scm:svn:http://svn.apache.org/repos/asf/labs/dungeon</developerConnection>
+ </scm>
+
+ <ciManagement>
+ <system>continuum</system>
+ <url>http://localhost:8080/continuum</url>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>elecharny@apache.org</address>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+
+</project>
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractProduction.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractProduction.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractProduction.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractProduction.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ * The abstract Production container. A production is a set of
+ * rules :
+ *
+ * <lhs> ::= aAbB | ... | zZtT | #
+ *
+ * where {a, b, z, t} are terminal symbols and {A, B, Z, T}
+ * are non terminal symbols. Epsilon transition (marker '#')
+ * are also allowed.
+ *
+ * <lhs> is a non terminal symbol.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractProduction implements Production
+{
+ /** The LHS element **/
+ private Symbol lhs;
+
+ /**
+ *
+ * Creates a new instance of AbstractProduction.
+ *
+ */
+ public AbstractProduction()
+ {
+ }
+
+ /**
+ * @return the name of this production, which is
+ * the name of its LHS
+ */
+ public String getName()
+ {
+ return lhs.getName();
+ }
+
+ /**
+ * @return the production's LHS
+ */
+ public Symbol getLhs()
+ {
+ return lhs;
+ }
+
+ /**
+ * Set the production's LHS
+ * @param lhs The LHS element
+ */
+ public void setLhs( Symbol lhs )
+ {
+ this.lhs = lhs;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public abstract String toString();
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractSymbol.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractSymbol.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractSymbol.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/AbstractSymbol.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+import org.apache.dungeon.util.StringTools;
+
+/**
+ *
+ * A super class to implement default behavior for Symbols
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractSymbol implements Symbol
+{
+ /** The symbol name or lexical element */
+ protected String name;
+
+ /** The associated code, if any */
+ protected String code;
+
+ /**
+ *
+ * Creates a new instance of AbstractSymbol.
+ *
+ * @param name The symbol's name
+ */
+ public AbstractSymbol( String name )
+ {
+ this.name = name;
+ }
+
+ /**
+ * Add some code to the symbol
+ *
+ * @param code The associated code. Can be null.
+ */
+ public void addCode( String code )
+ {
+ this.code = code;
+ }
+
+ /**
+ * @return the symbol's name
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * @return the production as its textual representation
+ */
+ public abstract String nameToString();
+
+ /**
+ * @return a textual representation of this object
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( " Name : " ).append( name ).append( '\n' );
+
+ if ( StringTools.isEmpty( code ) )
+ {
+ sb.append( " No code." );
+ }
+ else
+ {
+ // We don't want to generate a code portion
+ // if it's longer than 80 chars.
+ if ( code.length() > 80)
+ {
+ sb.append( " Code : '" ).append( code.substring( 0, 80) ).append( "'\n" );
+ }
+ else
+ {
+ sb.append( " Code : '" ).append( code ).append( "'\n" );
+ }
+ }
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonException.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonException.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonException.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonException.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * Exception to use if we already have an epsilon exception within the production
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class EpsilonException extends Exception {
+ static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an Exception with a detailed message.
+ *
+ * @param message The message associated with the exception.
+ */
+ public EpsilonException( String message )
+ {
+ super( message );
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonTransition.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonTransition.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonTransition.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/EpsilonTransition.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * An epsilon transition symbol.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class EpsilonTransition extends VN
+{
+ /**
+ *
+ * Creates a new instance of EpsilonTransition.
+ */
+ public EpsilonTransition()
+ {
+ super( "#" );
+ }
+
+ /**
+ * @see AbstractSymbol#nameToString()
+ */
+ public String nameToString()
+ {
+ return "#";
+ }
+
+ /**
+ * @see AbstractSymbol#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Epsilon Transition -> \n" ).append( super.toString() );
+
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Ident.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Ident.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Ident.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Ident.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ *
+ * An ident is a named regular expression used to match a lexical element.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Ident extends VT
+{
+ /** The regular expression used to match the ident */
+ private Pattern regexp;
+
+ /**
+ *
+ * Creates a new instance of Ident.
+ *
+ * @param symbol The Ident value
+ */
+ public Ident( String symbol )
+ {
+ super( symbol );
+ }
+
+ /**
+ * @see AbstractSymbol#nameToString()
+ */
+ public String nameToString()
+ {
+ return '\'' + super.getName() + '\'';
+ }
+
+ /**
+ *
+ * Set the regexp associated with this ident.
+ *
+ * @param regexp The string regexp
+ * @throws PatternSyntaxException If the regexp is syntaxically incorrect
+ */
+ public void setRegexp( String regexp ) throws PatternSyntaxException
+ {
+ this.regexp = Pattern.compile( regexp );
+ }
+
+ /**
+ * @return The Pattern representing the compiled regexp.
+ */
+ public Pattern getRegexp()
+ {
+ return regexp;
+ }
+
+ /**
+ * @see AbstractSymbol#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Ident[" ).
+ append( getName() ).
+ append( " ]-> '" ).
+ append( regexp.toString() ).
+ append( "'\n" );
+
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaGrammar.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaGrammar.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaGrammar.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaGrammar.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ *
+ * A grammar container.
+ * - Grammar are composed of N productions.
+ * - Each production has a LHS and a RHS
+ * - Each RHS is composed of N rules
+ * - Each rule is composed of N symbols
+ * - Each symbol can be either VT, VN or epsilon transition (#)
+ *
+ * We also have those rules to follow :
+ * - Each VN is declared in one RHS
+ * - A production can't have more than one epsilon transition
+ *
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MetaGrammar
+{
+ /** List of all productions for this grammar */
+ private List<Production> productions;
+
+ /** The set of all VN declared */
+ private Set<String> vns;
+
+ private Set<String> rhsVNs;
+
+ /**
+ *
+ * Creates a new instance of MetaGrammar.
+ */
+ public MetaGrammar()
+ {
+ productions = new ArrayList<Production>();
+ vns = new HashSet<String>();
+ rhsVNs = new HashSet<String>();
+ }
+
+ /**
+ *
+ * A new production has been parsed. We add it to the
+ * Lists
+ *
+ * @param production The new parsed production
+ */
+ public void addProduction ( Production production )
+ {
+ productions.add( production );
+ vns.add( production.getName() );
+ }
+
+ /**
+ *
+ * Checks if the production has already been parsed
+ *
+ * @param name The production's name
+ * @return <code>true</code> if the production already exists
+ */
+ public boolean containsVN( String name )
+ {
+ return vns.contains( name );
+ }
+
+ /**
+ * @return The list of all productions for this grammar
+ */
+ public List<Production> getProductions()
+ {
+ return productions;
+ }
+
+ public Set<String> getRhsVNs()
+ {
+ return rhsVNs;
+ }
+
+ public void addRhsVN( String vn )
+ {
+ this.rhsVNs.add( vn );
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaLexeme.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaLexeme.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaLexeme.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaLexeme.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * A class to store a lexical production.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MetaLexeme extends AbstractProduction
+{
+ private Ident ident;
+
+ /**
+ *
+ * Creates a new instance of MetaLexeme.
+ *
+ */
+ public MetaLexeme()
+ {
+ }
+
+ /**
+ *
+ * Associate an ident object to this lexeme
+ *
+ * @param ident The Ident object
+ */
+ public void setIdent( Ident ident )
+ {
+ this.ident = ident;
+ }
+
+ /**
+ * @return The ident object
+ */
+ public Ident getIdent()
+ {
+ return ident;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Lexeme \n" ).
+ append( getName() ).
+ append( " -> '" ).
+ append( ident.getRegexp() ).
+ append( "'\n" );
+
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaParser.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaParser.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaParser.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaParser.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,971 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+
+//import java.util.regex.Pattern;
+
+import org.apache.dungeon.util.Position;
+import org.apache.dungeon.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ *
+ * This class parse a grammar and produce a MetaGrammar object.
+ *
+ * The Meta Grammar follow the rules :
+ *
+ * // Syntaxic
+ * <grammar> ::= <production> <productions> ;
+ * <productions>::= <production> <productions> | # ;
+ * <production> ::= SPS <vn> SPS AFFECT SPS <rhs> SPS SEMI ;
+ * <rhs> ::= <vt> <rule> <rhs-e> | <vn> <rule> <rhs-e> | <epsilon> ;
+ * <rhs-e> ::= BAR SPS <rhs> | # ;
+ * <rule> ::= <vt> <rule> | <vn> <rule> | #
+ * <vn> ::= LESSER IDENT GREATER <code-e> ;
+ * <vt> ::= QUOTE LEX QUOTE <code-e> ;
+ * <epsilon> ::= EPSILON <code-e> ;
+ * <code-e> ::= SPS ACTION SPS <code-num> SPS ACTION SPS | # ;
+ * <code-num> ::= CODE | NUM ;
+ *
+ * // Lexical
+ * AFFECT -> '::=';
+ * SPS -> '(\n|\s)*';
+ * LESSER -> '<';
+ * GREATER -> '>';
+ * IDENT -> '[a-zA-Z]([a-z-A-Z0-9_-])*';
+ * SEMI -> ';';
+ * QUOTE -> '\'';
+ * LEX -> '([^']|'')+';
+ * EPSILON -> '#';
+ * BAR -> '|';
+ * ACTION -> '@@'
+ * CODE -> '(.*@@)';
+ * NUM -> '[1-9]([0-9]*)';
+ *
+ * <grammar> ::= <production> <productions>
+ * <productions> ::= <production> <productions> | #
+ * <production> ::= IDENT '::=' <rhs> NLS
+ * <rhs> ::= <lexical> <rules> | <rule> <rules> | '#'
+ * <rules> ::= '|' <rules-e>
+ * <rules-e> ::= <lexical> <rules-e> | <rule> <rules-e> | '#' '{' <code> '}' | '{' <code> '}' | #
+ * <rule> ::= '<' IDENT '>' '{' <code> '}'
+ * <lexical> ::= '\'' LEX '\'' '{' <code> '}'
+ * <code> ::= JAVA_CODE
+ *
+ * IDENT -> ([a..z] | [A..Z]) ([a..z] | [A..Z] | [0-9] | '_'
+ * LEX -> <any Unicode char, but ' is escaped by a ' >
+ * JAVA_CODE -> some java code
+ * NL -> '\n' | '\r' | '\r\n'
+ * NLS -> NL+
+ *
+ * '''' -> '
+ * 'ab''c' -> ab'c
+ * 'abc''' -> abc'
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ *
+ */
+public class MetaParser
+{
+ /** The logger */
+ private static final transient Logger log = LoggerFactory.getLogger( MetaParser.class );
+
+ /** Constants used in the code */
+ private static final String AFFECT = "::=";
+ private static final char SEMI_COLON = ';';
+ private static final char LESSER = '<';
+ private static final char GREATER = '>';
+ private static final char BAR = '|';
+ private static final char EPSILON = '#';
+ private static final char QUOTE = '\'';
+ private static final char AT = '@';
+
+ private static final String ACTION = "@@";
+
+ /** Pattern used to match lexical elements. Currently not used */
+ /*
+ private static final Pattern IDENT = Pattern.compile( "[a-zA-Z][a-zA-Z0-9_]*" );
+ private static final Pattern NUMBER = Pattern.compile( "[1-9][0-9]*" );
+ private static final Pattern LEX = Pattern.compile( "([^']|'')+" );
+ private static final Pattern CODE = Pattern.compile( ".*@@" );
+ private static final Pattern NL = Pattern.compile( "[\r\n]+" );
+ */
+
+ /**
+ * Skip spaces characters
+ *
+ * @param grammarText The grammar text
+ * @param pos The current position in the grammar
+ */
+ private void skipSpaces( char[] grammarText, Position pos )
+ {
+ while ( StringTools.isSpace( grammarText, pos.current ) )
+ {
+ pos.current++;
+ }
+ }
+
+ /**
+ * Parse an identifier.
+ * IIDENT -> [a-zA-Z][a-zA-Z0-9-]*
+ *
+ * @param grammarText The grammar buffer
+ * @param position The current position
+ * @return A valid ident
+ */
+ private String parseIdent( char[] grammarText, Position pos ) throws ParserException
+ {
+ pos.start = pos.current;
+ pos.length = 0;
+
+ if ( StringTools.isAlphaASCII( grammarText, pos.current ) )
+ {
+ pos.current++;
+ pos.length++;
+ }
+ else
+ {
+ log.error( "An ALPHA char is expected at position {}", pos );
+ throw new ParserException( "ALPHA char expected" );
+ }
+
+ while ( StringTools.isAlphaDigitMinus( grammarText, pos.current ) )
+ {
+ pos.current++;
+ pos.length++;
+ }
+
+ String ident = new String( grammarText, pos.start, pos.length );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Ident found ( {} ) at position {}", ident, pos );
+ }
+
+ return ident;
+ }
+
+ /**
+ * Check that the token found in the text equals an expected token
+ *
+ * @param grammarText The grammar buffer
+ * @param pos The current position in the buffer
+ * @param expectedToken The expected token to find
+ * @throws ParserException If the token is not found
+ */
+ private void parseToken( char[] grammarText, Position pos, String expectedToken ) throws ParserException
+ {
+ int newPos = 0;
+
+ if ( ( newPos = StringTools.areEquals( grammarText, pos.current, expectedToken ) )
+ == StringTools.NOT_EQUAL )
+ {
+ log.error( "Expected token '{}' not found at position {}", expectedToken, pos );
+ throw new ParserException( "Token '" + expectedToken + " expected" );
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Token '{}' found at position {}", expectedToken, pos );
+ }
+
+ pos.current = newPos;
+ }
+
+ /**
+ * Parse the following rule :
+ * <code-e> ::= SPS ACTION SPS <code-num> SPS ACTION SPS | #
+ *
+ * @throws ParserException
+ * @param grammarText The grammar buffer
+ * @param pos The current position in the buffer
+ * @throws ParserException If we can get the code or if the ACTION tag
+ * is not closed (missing '@@' at the end of the code)
+ * @return The code if any
+ */
+ private String parseCodeEmpty( char[] grammarText, Position pos ) throws ParserException
+ {
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ return null;
+ }
+
+ // ACTION
+ if ( StringTools.areEquals( grammarText, pos.current, ACTION ) != StringTools.NOT_EQUAL)
+ {
+ // We have some code.
+ pos.current += 2;
+ pos.start = pos.current;
+ pos.length = 0;
+
+ // We will have to grab the code
+ boolean isCode = true;
+
+ while ( isCode )
+ {
+ while ( StringTools.isCharASCII( grammarText, pos.current, AT ) == false )
+ {
+ pos.current++;
+ pos.length++;
+ }
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "The code should end with '@@'" );
+ throw new ParserException( "No @@ to close the action" );
+ }
+
+ if ( StringTools.areEquals( grammarText, pos.current, ACTION ) != StringTools.NOT_EQUAL)
+ {
+ // The code is over.
+ pos.current += 2;
+ isCode = false;
+ }
+ else
+ {
+ pos.current++;
+ pos.length++;
+ }
+ }
+
+ String code = new String( grammarText, pos.start, pos.length );
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ return code;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Parse a lexical
+ * LEX -> ([^']|'')+
+ *
+ * @param grammarText The grammar buffer
+ * @param position The current position
+ * @throws ParserException if the lexical element is not enclosed by a '\''
+ * @return A valid ident
+ */
+ private String parseLex( char[] grammarText, Position pos ) throws ParserException
+ {
+ pos.start = pos.current;
+ pos.length = 0;
+
+ boolean isLex = true;
+
+ while ( isLex )
+ {
+ while ( StringTools.isCharASCII( grammarText, pos.current, QUOTE ) == false )
+ {
+ pos.current++;
+ pos.length++;
+ }
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "The lexical should end with '\''" );
+ throw new ParserException( " No ' to close the VT" );
+ }
+
+ if ( StringTools.areEquals( grammarText, pos.current, "''" ) != StringTools.NOT_EQUAL)
+ {
+ // We have an escaped quote
+ pos.current += 2;
+ pos.length+=2;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ String lexical = new String( grammarText, pos.start, pos.length );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Lexical found ( {} ) at position {}", lexical, pos );
+ }
+
+ return lexical;
+ }
+
+ /**
+ * Parse the rule :
+ * <vt> ::= QUOTE LEX QUOTE <code-e>
+ *
+ * @param grammarText The grammar buffer
+ * @param position The current position
+ * @throws ParserException if the lexical element is not enclosed by a '\'',
+ * or if the code is not correctly parsed.
+ * @return A valid VT
+ */
+ private Symbol parseVT( char[] grammarText, Position pos ) throws ParserException
+ {
+ // QUOTE
+ if ( StringTools.isCharASCII( grammarText, pos.current, QUOTE ) == false )
+ {
+ log.error( "A '\'' character is expected at position {}", pos );
+ throw new ParserException( "A ' is expected" );
+ }
+
+ pos.current++;
+
+ // LEX
+ String lex = parseLex( grammarText, pos );
+
+ // QUOTE
+ if ( StringTools.isCharASCII( grammarText, pos.current, QUOTE ) == false )
+ {
+ log.error( "A '\'' character is expected at position {}", pos );
+ throw new ParserException( "No ' to close the VT" );
+ }
+
+ pos.current++;
+
+ Symbol vt = new VT( lex );
+
+ // <code-e>
+ String code = null;
+
+ try
+ {
+ code = parseCodeEmpty( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error in code, position {}", pos );
+ throw pe;
+ }
+
+ vt.addCode( code );
+
+ return vt;
+ }
+
+ /**
+ * Parse the rule :
+ * <vn> ::= LESSER IDENT GREATER <code-e>
+ *
+ * @param grammarText The grammar buffer
+ * @param position The current position
+ * @throws ParserException if the lexical element is not enclosed by a '<' or
+ * a '>', or if the code is not correctly parsed
+ * @return A valid VN
+ */
+ private Symbol parseVN( char[] grammarText, Position pos ) throws ParserException
+ {
+ // LESSER
+ if ( StringTools.isCharASCII( grammarText, pos.current, LESSER ) == false )
+ {
+ log.error( "A '<' character is expected at position {}", pos );
+ throw new ParserException( "A < is expected" );
+ }
+
+ pos.current++;
+
+ // IDENT
+ String ident = parseIdent( grammarText, pos );
+
+ // GREATER
+ if ( StringTools.isCharASCII( grammarText, pos.current, GREATER ) == false )
+ {
+ log.error( "A '>' character is expected at position {}", pos );
+ throw new ParserException( "No > to close the VN" );
+ }
+
+ pos.current++;
+
+ Symbol vn = new VN( ident );
+
+ // <code-e>
+ String code = null;
+
+ try
+ {
+ code = parseCodeEmpty( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error in code, position {}", pos );
+ throw pe;
+ }
+
+ vn.addCode( code );
+
+ return vn;
+ }
+
+ /**
+ * Parse the rule :
+ * <rhs-e> ::= BAR SPS <rhs> | #
+ *
+ * @param grammarText The grammar buffer
+ * @param position The current position
+ * @return
+ * @throws ParserException
+ */
+ private MetaRhs parseRhsEmpty( char[] grammarText, Position pos, MetaRhs rhs ) throws ParserException
+ {
+ // BAR
+ if ( StringTools.isCharASCII( grammarText, pos.current, BAR ) == false )
+ {
+ // No bar means empty
+ return null;
+ }
+
+ pos.current++;
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "A symbol is expected after a '|' char at position {}", pos );
+ throw new ParserException( "Expected element after the |" );
+ }
+
+ return parseRhs( grammarText, pos, rhs );
+ }
+
+ /**
+ * Parse the rule :
+ * <rhs> ::= <vt> SPS <rule> | <vn> SPS <rule> | #
+ *
+ * The first element must be either :
+ * '<' -> rule
+ * '\'' -> lexical element
+ *
+ * @param grammarText
+ * @param pos
+ * @param production
+ * @return
+ * @throws ParserException
+ */
+ private MetaRhs parseRule( char[] grammarText, Position pos, MetaRhs rhs ) throws ParserException
+ {
+ char c = StringTools.charAt( grammarText, pos.current );
+
+ if ( c == 0 )
+ {
+ log.error( "A character is expected at position {}", pos );
+ throw new ParserException( "Expecting <, ' or #" );
+ }
+
+ Symbol symbol = null;
+
+ switch ( c )
+ {
+ case QUOTE :
+ // This is a VT
+ try
+ {
+ symbol = parseVT( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing lexical element at position {}", pos );
+ throw pe;
+ }
+
+ break;
+
+ case LESSER :
+ // This is a VN
+ try
+ {
+ symbol = parseVN( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing lexical element at position {}", pos );
+ throw pe;
+ }
+
+ break;
+
+ default :
+ // We have read all the symbols
+ return rhs;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for '::=' at position {}", pos );
+ throw new ParserException( "Expecting ::=" );
+ }
+
+ rhs.addSymbol( symbol );
+
+ // <rule>
+ return parseRule( grammarText, pos, rhs );
+ }
+
+ /**
+ * Parse the rule :
+ * <rhs> ::= <vt> SPS <rule> SPS <rhs-e> | <vn> SPS <rule> SPS <rhs-e> | <epsilon>
+ *
+ * The first element must be either :
+ * '#' -> epsilon transition
+ * '<' -> rule
+ * '\'' -> lexical element
+ *
+ * @param grammarText
+ * @param pos
+ * @param production
+ * @return
+ * @throws ParserException
+ */
+ private MetaRhs parseRhs( char[] grammarText, Position pos, MetaRhs rhs ) throws ParserException
+ {
+ char c = StringTools.charAt( grammarText, pos.current );
+
+ if ( c == 0 )
+ {
+ log.error( "A character is expected at position {}", pos );
+ throw new ParserException( "Expecting <, ' or #" );
+ }
+
+ Symbol symbol = null;
+
+ switch ( c )
+ {
+ case QUOTE :
+ // This is a VT
+ try
+ {
+ symbol = parseVT( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing lexical element at position {}", pos );
+ throw pe;
+ }
+
+ break;
+
+ case LESSER :
+ // This is a VN
+ try
+ {
+ symbol = parseVN( grammarText, pos );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing lexical element at position {}", pos );
+ throw pe;
+ }
+
+ break;
+
+ case EPSILON :
+ // This is an epsilon transition
+ // <epsilon> ::= EPSILON <code-e>
+ pos.current++;
+
+ String code = parseCodeEmpty( grammarText, pos );
+
+ EpsilonTransition epsilonTransition = new EpsilonTransition();
+
+ if ( code != null )
+ {
+ epsilonTransition.addCode( code );
+ }
+
+ rhs.addSymbol( epsilonTransition );
+ return rhs;
+
+ default :
+ log.error( "A VT, VN or epsilon transition expected, found '{}' at position {}", c, pos );
+ throw new ParserException( "Expecting <, ' or #" );
+ }
+
+ rhs.addSymbol( symbol );
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for '::=' at position {}", pos );
+ throw new ParserException( "Expecting ::=" );
+ }
+
+ // <rule>
+ parseRule( grammarText, pos, rhs );
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for '::=' at position {}", pos );
+ throw new ParserException( "Expecting ::=" );
+ }
+
+ try
+ {
+ //rhs.addSymbol( symbol );
+ parseRhsEmpty( grammarText, pos, rhs );
+ return rhs;
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing the remainding rhs at position {}", pos );
+ throw pe;
+ }
+ }
+
+ /**
+ * Parse the rule :
+ * <regexp> ::= IDENT SPS ASSIGN SPS QUOTE REGEXP QUOTE SPS SEMI
+ *
+ * @param grammarText
+ * @param pos
+ * @param grammar
+ * @return
+ * @throws ParserException
+ */
+ private Production parseRegexp( char[] grammarText, Position pos, MetaGrammar grammar ) throws ParserException
+ {
+ Production lexeme = new MetaLexeme();
+
+ // IDENT
+ try
+ {
+ String ident = parseIdent( grammarText, pos );
+
+ if ( StringTools.isEmpty( ident ) )
+ {
+ log.error( "We cannot have an empty ident at position {}", pos );
+ throw new ParserException( "Empty ident unexpected" );
+ }
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "The ident is invalid at position {}", pos );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for '::=' at position {}", pos );
+ throw new ParserException( "Expecting ::=" );
+ }
+
+ // ASSIGN
+ try
+ {
+ parseToken( grammarText, pos, AFFECT );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Token '::=' expected and not found at position {}", pos );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for some rules at position {}", pos );
+ throw new ParserException( "Expecting some rules" );
+ }
+
+ Ident ident = new Ident( lexeme.getName() );
+
+ // QUOTE REGEXP QUOTE
+ try
+ {
+ String regexp = parseLex( grammarText, pos );
+
+ ident.setRegexp( regexp );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing the regexp at position {}", pos );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for a ';' at position {}", pos );
+ throw new ParserException( "No ; at the end of the production" );
+ }
+
+ // SEMI
+ if ( StringTools.isCharASCII( grammarText, pos.current, SEMI_COLON ) )
+ {
+ pos.current++;
+ }
+ else
+ {
+ log.error( "Expecting a ';' at position {}", pos );
+ throw new ParserException( "No ; at the end of the production" );
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Found production {} at position {}", lexeme, pos );
+ }
+
+ lexeme.setLhs( ident );
+ return lexeme;
+ }
+
+
+ /**
+ *
+ * Parse the rule :
+ * <prod> ::= <vn> SPS AFFECT SPS <rhs> SPS SEMI
+ *
+ * @param grammarText
+ * @param pos
+ * @param grammar
+ * @return
+ * @throws ParserException
+ */
+ private Production parseProd( char[] grammarText, Position pos, MetaGrammar grammar ) throws ParserException
+ {
+ Production production = new MetaProduction();
+
+ try
+ {
+ Symbol vn = parseVN( grammarText, pos );
+ String name = vn.getName();
+
+ if ( grammar.containsVN( name ) )
+ {
+ log.error( "The rule '{}' has already been defined in the grammar (position : {})", name, pos );
+ throw new ParserException( "Rule " + name + " already defined" );
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Found a new rule : '{}' at position {}", name, pos );
+ }
+
+ production.setLhs( vn );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "No VN found on LHS of this production at position {}", pos );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for '::=' at position {}", pos );
+ throw new ParserException( "Expecting ::=" );
+ }
+
+ // AFFECT
+ try
+ {
+ parseToken( grammarText, pos, AFFECT );
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Token '::=' expected and not found at position {}", pos );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for some rules at position {}", pos );
+ throw new ParserException( "Expecting some rules" );
+ }
+
+ // rhs
+ try
+ {
+ MetaRhs rhs = new MetaRhs();
+ rhs = parseRhs( grammarText, pos, rhs );
+ ((MetaProduction)production).setRhs( rhs );
+
+ // Feed the grammar with all the found VN
+ for ( Symbol symbol:rhs.getSymbols() )
+ {
+ if ( symbol instanceof VN )
+ {
+ grammar.addRhsVN( symbol.getName() );
+ }
+ }
+
+ }
+ catch ( ParserException pe )
+ {
+ log.error( "Error while parsing RHSs at position {} : {}", pos, pe.getMessage() );
+ throw pe;
+ }
+
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ log.error( "Waiting for a ';' at position {}", pos );
+ throw new ParserException( "No ; at the end of the production" );
+ }
+
+ // SEMI
+ if ( StringTools.isCharASCII( grammarText, pos.current, SEMI_COLON ) )
+ {
+ pos.current++;
+ }
+ else
+ {
+ log.error( "Expecting a ';' at position {}", pos );
+ throw new ParserException( "No ; at the end of the production" );
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Found production {} at position {}", production, pos );
+ }
+
+ return production;
+ }
+
+ /**
+ *
+ * Parse this rule :
+ * <production> ::= SPS <vn> SPS AFFECT SPS <rhs> SPS SEMI
+ *
+ * @param grammarText
+ * @param pos
+ * @return
+ * @throws ParserException
+ */
+ private Production parseProduction( char[] grammarText, Position pos, MetaGrammar grammar ) throws ParserException
+ {
+ // SPS
+ skipSpaces( grammarText, pos );
+
+ if ( pos.current >= grammarText.length )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "No more text in the grammar" );
+ }
+
+ return null;
+ }
+
+ // <vn> or IDENT, depending on which part of the grammar we are parsing
+ // We will read on char and if it's a '<' then we have a VN, and if it's [a-zA-Z] then it's an ident
+ char c = StringTools.charAt( grammarText, pos.current );
+
+ if ( c == 0 )
+ {
+ log.error( "A character is expected at position {}", pos );
+ throw new ParserException( "Expecting < of [a-zA-Z]" );
+ }
+
+ if ( c == LESSER )
+ {
+ return parseProd( grammarText, pos, grammar );
+ }
+ else
+ {
+ return parseRegexp( grammarText, pos, grammar );
+ }
+ }
+
+ /**
+ * Parse a grammar and return a MetGrammar object
+ * The rules parsed in this method are :
+ * <grammar> ::= <production> <productions>
+ * <productions> ::= <production> <productions> | #
+ *
+ * @param grammarText The grammar to parse
+ * @return A MetaGrammar
+ * @throws ParserException
+ * If the grammar is invalid
+ */
+ public MetaGrammar parseGrammar( char[] grammarText ) throws ParserException
+ {
+ log.info( "Starting to parse the grammar" );
+
+ if ( ( grammarText == null ) || ( grammarText.length == 0 ) )
+ {
+ // We have an empty grammar, just get out of the function.
+ log.warn( "The grammar is empty" );
+ return null;
+ }
+
+ MetaGrammar grammar = new MetaGrammar();
+
+ Position pos = new Position();
+ pos.start = 0;
+ pos.current = 0;
+ pos.length = 0;
+
+ // Parse this rule : <grammar> ::= <production> <productions>
+ Production production = parseProduction( grammarText, pos, grammar );
+
+ if ( production == null )
+ {
+ log.error( "At least a production is expected in the grammar" );
+ throw new ParserException( "No productions" );
+ }
+ else
+ {
+ grammar.addProduction( production );
+ }
+
+ // Parse this rule : <productions> ::= <production> <productions> | #
+ while ( ( production = parseProduction( grammarText, pos, grammar ) ) != null )
+ {
+ grammar.addProduction( production );
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Number of production found : {}", grammar.getProductions().size() );
+ }
+ return grammar;
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaProduction.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaProduction.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaProduction.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaProduction.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * TODO MetaProduction.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MetaProduction extends AbstractProduction
+{
+ private String name;
+ private MetaRhs rhs;
+ private boolean epsilonTransition;
+ private Symbol lhs;
+
+ public MetaProduction()
+ {
+ rhs = null;
+ epsilonTransition = false;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public void setRhs( MetaRhs rhs )
+ {
+ this.rhs = rhs;
+ }
+
+ public MetaRhs getRhs()
+ {
+ return rhs;
+ }
+
+ public boolean hasEpsilonTransition()
+ {
+ return epsilonTransition;
+ }
+
+ public Symbol getLhs()
+ {
+ return lhs;
+ }
+
+ public void setLhs( Symbol lhs )
+ {
+ this.lhs = lhs;
+ name = lhs.getName();
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Production \n<" ).append( name ).append( "> ::= " );
+
+ boolean isFirst = true;
+
+ for ( Symbol symbol:rhs.getSymbols() )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( " | " );
+ }
+
+ sb.append( symbol.nameToString() );
+ }
+
+ return sb.toString();
+ }
+
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaRhs.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaRhs.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaRhs.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/MetaRhs.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * TODO MetaProduction.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MetaRhs
+{
+ private List<Symbol> symbols;
+
+ public MetaRhs()
+ {
+ symbols = new ArrayList<Symbol>();
+ }
+
+ public void addSymbol( Symbol symbol )
+ {
+ symbols.add( symbol );
+ }
+
+ public List<Symbol> getSymbols()
+ {
+ return symbols;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "RHS : " );
+
+ boolean isFirst = true;
+
+ for ( Symbol symbol:symbols )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( " " );
+ }
+
+ sb.append( symbol.nameToString() );
+ }
+
+ return sb.toString();
+ }
+
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/ParserException.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/ParserException.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/ParserException.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/ParserException.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * TODO ParserException.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ParserException extends Exception {
+ static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an Exception with a detailed message.
+ *
+ * @param message The message associated with the exception.
+ */
+ public ParserException( String message )
+ {
+ super( message );
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Production.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Production.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Production.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Production.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+/**
+ * Interface used for Production sub-classes, like MetaProduction
+ * and MetaLexeme.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface Production
+{
+ /**
+ * Set the production's LHS
+ * @param lhs The LHS element
+ */
+ void setLhs( Symbol symbol );
+
+ /**
+ * @return the name of this production, which is
+ * the name of its LHS
+ */
+ String getName() ;
+
+ /**
+ * @return the production's LHS
+ */
+ Symbol getLhs();
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Symbol.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Symbol.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Symbol.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Symbol.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * TODO Symbol.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface Symbol
+{
+ void addCode( String code );
+ String getName();
+ String nameToString();
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Test.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Test.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Test.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/Test.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,28 @@
+
+package org.apache.dungeon.meta.parser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Test
+{
+
+ /**
+ * TODO main.
+ *
+ * @param args
+ */
+ public static void main( String[] args )
+ {
+ // TODO Auto-generated method stub
+ Pattern p = Pattern.compile( "([^']|'')+" );
+
+ Matcher m = p.matcher( "ab''''c', afg" );
+
+ if ( m.find() )
+ {
+ System.out.println( "Match :" + m.group() );
+ }
+ }
+
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VN.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VN.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VN.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VN.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * A VN (Vocabulary Non Terminal) symbol. Represent
+ * all the rules.
+ *
+ * For instance, in the following production :<br/>
+ *
+ * <code><b><A> ::= b <C> | <D> | #</b></code><br/>
+ *
+ * A, C and D are VNs
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class VN extends AbstractSymbol
+{
+ /**
+ *
+ * Creates a new instance of VN.
+ *
+ * @param name The VN name
+ */
+ public VN( String name)
+ {
+ super( name );
+ }
+
+ /**
+ * @see AbstractSymbol#nameToString()
+ */
+ public String nameToString()
+ {
+ return '<' + name + '>';
+ }
+
+ /**
+ * @see AbstractSymbol#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "VN -> \n" ).append( super.toString() );
+
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VT.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VT.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VT.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/meta/parser/VT.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.dungeon.meta.parser;
+
+/**
+ *
+ * A VT (Vocabulary Terminal) symbol. Represent
+ * all the lexical elements.
+ *
+ * For instance, in the following production :<br/>
+ *
+ * <code><b><A> ::= b <C> | <D> | # </b></code><br/>
+ *
+ * b is a VT
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ * @version $Rev$, $Date$
+ */
+public class VT extends AbstractSymbol
+{
+ /**
+ *
+ * Creates a new instance of VT.
+ *
+ * @param symbol The VT value
+ */
+ public VT( String symbol )
+ {
+ super( symbol );
+ }
+
+ /**
+ * @see AbstractSymbol#nameToString()
+ */
+ public String nameToString()
+ {
+ return '\'' + super.getName() + '\'';
+ }
+
+ /**
+ * @see AbstractSymbol#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "VT -> \n" ).append( super.toString() );
+
+ return sb.toString();
+ }
+}
Added: labs/dungeon/src/main/java/org/apache/dungeon/util/Position.java
URL: http://svn.apache.org/viewvc/labs/dungeon/src/main/java/org/apache/dungeon/util/Position.java?view=auto&rev=482284
==============================================================================
--- labs/dungeon/src/main/java/org/apache/dungeon/util/Position.java (added)
+++ labs/dungeon/src/main/java/org/apache/dungeon/util/Position.java Mon Dec 4 10:41:29 2006
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.dungeon.util;
+
+/**
+ *
+ * This class is used to store the position of a token in a string. It's very
+ * usefull while parsing a DN.
+ *
+ * @author <a href="mailto:dev@labs.apache.org">Dungeon Project</a>
+ *
+ */
+public class Position
+{
+ public int start = 0;
+ public int length =0;
+ public int current = 0;
+
+ public String toString()
+ {
+ return "[" + start + ", " + current + ", " + length + "]";
+ }
+
+ public boolean isEnd()
+ {
+ return current == length;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org