[antlr-interest] String concatenation expression rule

Bart Kiers bkiers at gmail.com
Fri Nov 18 04:11:24 PST 2011


On Fri, Nov 18, 2011 at 12:39 PM, franck102 <franck102 at yahoo.com> wrote:

> I am writing a grammar for a fairly complex expression language, and in
> particular I need to support string concatenation which is performed simply
> by separating string literals with a space; and which automatically
> converts
> other expressions to a string if needed to concatenate:
> "a" "b" -> "ab"
> 2+3 "mm" -> "5mm"
>
> I suspect I could use predicates to write a rule like this:
>
> concatExpression
>        :        ( expression | STRING_LITERAL )+ { apply only if at least
> one of the elements is a string literal }?
>
> Is there a way to achieve this? The alternative formulations I can think of
> are pretty messy...
>
>
As far as I understand it, you don't need any predicate. I see a
concat-expression has a lower precedence than addition, in which case this
could do the trick:

grammar T;

options {
  output=AST;
}

tokens {
  ROOT;
  CONCAT;
}

parse
  :  (expression ';')* EOF -> ^(ROOT expression*)
  ;

expression
  :  (add -> add) (add+ -> ^(CONCAT add+))?
  ;

add
  :  atom (('+' | '-')^ atom)*
  ;

atom
  :  Number
  |  String
  |  '(' expression ')' -> expression
  ;

Number : '0'..'9'+ ('.' '0'..'9'+)?;
String : '"' ~'"'* '"';
Space  : ' ' {skip();};

You can test it with the following class:

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String src = "42 - 2; 2 + 3 \"mm\"; \"a\" \"b\" 4-3-2 \"c\"; \"pi = \"
3.14159;";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    CommonTree root = (CommonTree)parser.parse().getTree(); ;
    System.out.println(new DOTTreeGenerator().toDOT(root));
  }
}

Regards,

Bart.


More information about the antlr-interest mailing list