Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A full-blown parser for such a small grammar could be an overkill, specially when the OP obviously has no prior experience with them. Not even using parser generators like ANTLR or JavaCC seems a good idea.</p> <p>It's not easy to elaborate more with the current information. OP, please provide information requested as comments to your question.</p> <p>Tentative grammar:</p> <pre><code>maxExpr ::= maxExpr '|' '(' minExpr ')' maxExpr ::= '(' minExpr ')' minExpr ::= minExpr '&amp;' ITEM minExpr ::= ITEM ITEM ::= 'DDT\d{4}' </code></pre> <p>Realized that, true, the grammar is excessive for a RegEx, but for a <strong>single</strong> RegEx. Nobody is saying we can't use more than one. In fact, even the simplest RegEx substitution can be regarded as a step in a Turing machine, and thus the problem is solvable using them. So...</p> <pre><code>str= str.replaceAll("\\s+", "" ) ; str= str.replaceAll("&amp;", "," ) ; str= str.replaceAll("\\([^)]+\\)", "-$0" ) ; str= str.replaceAll("\\|", "," ) ; str= str.replaceAll(".+", "+($0)" ) ; str= str.replaceAll("\\w+", "x($0)" ) ; str= str.replaceAll("\\+", "max" ) ; str= str.replaceAll("-", "min" ) ; </code></pre> <p>I didn't take many shortcuts. The general idea is that "+" equates to a production of <code>maxExpr</code> and "-" to one of <code>minExpr</code>.</p> <p>I tested this with input</p> <pre><code>str= "(DDT1453 &amp; DDT1454 &amp; DDT1111) | (DDT3524 &amp; DDT3523 &amp; DDT3522 &amp; DDT3520)" ; </code></pre> <p>Output is:</p> <pre><code>max(min(x(DDT1453),x(DDT1454),x(DDT1111)),min(x(DDT3524),x(DDT3523),x(DDT3522),x(DDT3520))) </code></pre> <p>Back to the idea of a grammar, it's easy to recognize that the significant elements of it really are ITEMS and '|' . All the rest (parentheses and '&amp;') is just decoration.</p> <p>Simplified grammar:</p> <pre><code>maxExpr ::= maxExpr '|' minExpr maxExpr ::= minExpr minExpr ::= minExpr ITEM minExpr ::= ITEM ITEM ::= 'DDT\d{4}' </code></pre> <p>From here, a very simple finite automaton:</p> <pre><code>&lt;start&gt; maxExpr= new List() ; minExpr= new List() ; "Expecting ITEM" (BEFORE_ITEM): ITEM -&gt; minExpr.add(ITEM) ; move to "Expecting ITEM, |, or END" "Expecting ITEM, |, or END" (AFTER_ITEM): ITEM -&gt; minExpr.add(ITEM) ; move to "Expecting ITEM, |, or END" | -&gt; maxExpr.add(minExpr); minExpr= new List(); move to "Expecting ITEM" END -&gt; maxExpr.add(minExpr); move to &lt;finish&gt; </code></pre> <p>... and the corresponding implementation:</p> <pre><code>static Pattern pattern= Pattern.compile("(\\()|(\\))|(\\&amp;)|(\\|)|(\\w+)|(\\s+)") ; static enum TokenType { OPEN, CLOSE, MIN, MAX, ITEM, SPACE, _END_, _ERROR_ }; static enum State { BEFORE_ITEM, AFTER_ITEM, END } public static class Token { TokenType type; String value; public Token(TokenType type, String value) { this.type= type ; this.value= value ; } } public static class Lexer { Scanner scanner; public Lexer(String input) { this.scanner= new Scanner(input) ; } public Token getNext() { String tokenValue= scanner.findInLine(pattern) ; TokenType tokenType; if( tokenValue == null ) tokenType= TokenType._END_ ; else if( tokenValue.matches("\\s+") ) tokenType= TokenType.SPACE ; else if( "(".equals(tokenValue) ) tokenType= TokenType.OPEN ; else if( ")".equals(tokenValue) ) tokenType= TokenType.CLOSE ; else if( "&amp;".equals(tokenValue) ) tokenType= TokenType.MIN ; else if( "|".equals(tokenValue) ) tokenType= TokenType.MAX ; else if( tokenValue.matches("\\w+") ) tokenType= TokenType.ITEM ; else tokenType= TokenType._ERROR_ ; return new Token(tokenType,tokenValue) ; } public void close() { scanner.close(); } } public static String formatColl(String pre,Collection&lt;?&gt; coll,String sep,String post) { StringBuilder result= new StringBuilder() ; result.append(pre); boolean first= true ; for(Object item: coll ) { if( ! first ) result.append(sep); result.append(item); first= false ; } result.append(post); return result.toString() ; } public static void main(String... args) { String str= "(DDT1453 &amp; DDT1454) | (DDT3524 &amp; DDT3523 &amp; DDT3522 &amp; DDT3520)" ; Lexer lexer= new Lexer(str) ; State currentState= State.BEFORE_ITEM ; List&lt;List&lt;String&gt;&gt; maxExpr= new LinkedList&lt;List&lt;String&gt;&gt;() ; List&lt;String&gt; minExpr= new LinkedList&lt;String&gt;() ; while( currentState != State.END ) { Token token= lexer.getNext() ; switch( currentState ) { case BEFORE_ITEM: switch( token.type ) { case ITEM: minExpr.add("x("+token.value+")") ; currentState= State.AFTER_ITEM ; break; case _END_: maxExpr.add(minExpr) ; currentState= State.END ; break; default: // Ignore; preserve currentState, of course break; } break; case AFTER_ITEM: switch( token.type ) { case ITEM: minExpr.add("x("+token.value+")") ; currentState= State.AFTER_ITEM ; break; case MAX: maxExpr.add(minExpr) ; minExpr= new LinkedList&lt;String&gt;() ; currentState= State.BEFORE_ITEM ; break; case _END_: maxExpr.add(minExpr) ; currentState= State.END ; break; default: // Ignore; preserve currentState, of course break; } break; } } lexer.close(); System.out.println(maxExpr); List&lt;String&gt; maxResult= new LinkedList&lt;String&gt;() ; for(List&lt;String&gt; minItem: maxExpr ) { maxResult.add( formatColl("min(",minExpr,",",")") ) ; } System.out.println( formatColl("max(",maxResult,",",")") ); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload