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>&lt;A> ::= b &lt;C> | &lt;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>&lt;A> ::= b &lt;C> | &lt;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