[antlr-interest] Seeking advice - 2 questions using ANTLR
Mark Volkmann
r.mark.volkmann at gmail.com
Thu Jan 17 14:21:33 PST 2008
Here's a version of the grammar that I believe produces the output you
want. Note that it is currently limited to logical expressions with a
single "AND" or "OR". If anyone sees ways to improve what I've done
I'd love to get feedback on this. I'm still learning ANTLR.
grammar Accounting;
options {
output = template;
}
@lexer::header { package com.ociweb.accounting; }
@parser::header { package com.ociweb.accounting; }
@parser::members {
private void out(String text) { System.out.print(text); }
private void outln(String text) { System.out.print(text); }
}
start: ifStatement EOF;
ifBegin: 'IF' { out("IF("); };
ifEnd: 'END IF' { out(")"); };
ifStatement
: ifBegin condition 'THEN' statement ('ELSE' statement)? ifEnd;
comparison
: expression RELATIONAL_OPERATOR expression;
condition
: c1=comparison { out($c1.text); }
| c1=comparison lo=LOGICAL_OPERATOR c2=comparison
{
out($lo.text + "(" + $c1.text + ", " + $c2.text + ")");
}
;
expression
: STRING_LITERAL
| value (SIGN value)*
;
statement
@init { out(", "); }
: e=expression { out($e.text); }
| ifStatement
;
value: NAME | NUMBER;
LOGICAL_OPERATOR: 'AND' | 'OR';
RELATIONAL_OPERATOR: '<' | '<=' | '=' | '>=' | '>';
APOSTROPHE: '\'';
NUMBER: INTEGER | FLOAT;
fragment FLOAT: INTEGER '.' NATURAL_NUMBER;
fragment INTEGER: SIGN? NATURAL_NUMBER;
fragment NATURAL_NUMBER: '0' | '1'..'9' '0'..'9'*;
SIGN: '+' | '-';
NAME: LETTER (LETTER | NUMBER | '_')*;
STRING_LITERAL: APOSTROPHE NONCONTROL_CHAR* APOSTROPHE;
WHITESPACE: (NEWLINE | SPACE)+ { $channel = HIDDEN; };
// Note that NONCONTROL_CHAR does not include the double-quote character.
fragment NONCONTROL_CHAR: LETTER | DIGIT | SYMBOL | SPACE;
fragment LETTER: LOWER | UPPER;
fragment LOWER: 'a'..'z';
fragment UPPER: 'A'..'Z';
fragment DIGIT: '0'..'9';
fragment NEWLINE: '\r'? '\n';
fragment SPACE: ' ' | '\t';
// Note that SYMBOL does not include the
// apostrophe or double-quote characters.
fragment SYMBOL: '!' | '#'..'&' | '('..'/' | ':'..'@' | '['..'`' | '{'..'~';
On Jan 17, 2008 3:55 PM, Mark Volkmann <r.mark.volkmann at gmail.com> wrote:
> Here's a start on your grammar.
>
> grammar Accounting;
>
> options {
> output = template;
> }
>
> @lexer::header { package com.ociweb.accounting; }
> @parser::header { package com.ociweb.accounting; }
>
> start: ifStatement EOF;
>
> ifStatement
> : 'IF' condition 'THEN' statement ('ELSE' statement)? 'END IF';
>
> comparison: expression RELATIONAL_OPERATOR expression;
>
> condition: comparison (LOGICAL_OPERATOR comparison)*;
>
> expression
> : STRING_LITERAL
> | value (SIGN value)*;
>
> statement: expression | ifStatement;
>
> value: NAME | NUMBER;
>
> LOGICAL_OPERATOR: 'AND' | 'OR';
>
> RELATIONAL_OPERATOR: '<' | '<=' | '=' | '>=' | '>';
>
> APOSTROPHE: '\'';
>
> NUMBER: INTEGER | FLOAT;
> fragment FLOAT: INTEGER '.' NATURAL_NUMBER;
> fragment INTEGER: SIGN? NATURAL_NUMBER;
> fragment NATURAL_NUMBER: '0' | '1'..'9' '0'..'9'*;
> SIGN: '+' | '-';
>
> NAME: LETTER (LETTER | NUMBER | '_')*;
>
> STRING_LITERAL: APOSTROPHE NONCONTROL_CHAR* APOSTROPHE;
>
> WHITESPACE: (NEWLINE | SPACE)+ { $channel = HIDDEN; };
>
> // Note that NONCONTROL_CHAR does not include the double-quote character.
> fragment NONCONTROL_CHAR: LETTER | DIGIT | SYMBOL | SPACE;
> fragment LETTER: LOWER | UPPER;
> fragment LOWER: 'a'..'z';
> fragment UPPER: 'A'..'Z';
> fragment DIGIT: '0'..'9';
> fragment NEWLINE: '\r'? '\n';
> fragment SPACE: ' ' | '\t';
>
> // Note that SYMBOL does not include the
> // apostrophe or double-quote characters.
> fragment SYMBOL: '!' | '#'..'&' | '('..'/' | ':'..'@' | '['..'`' | '{'..'~';
>
> It parses your example input except for I changed "H-CAPRESTATE" to
> "H_CAPRESTATE" to simply things. This way I can use "-" for
> subtraction. I'm sure there's a way to work this out so you can also
> use "-" in names.
>
> The grammar above doesn't output anything. It just verifies that input conforms.
>
> Email me privately if you want the Java code I wrote that uses the
> generated classes and my Ant build file.
>
>
> On Jan 17, 2008 3:02 PM, Mark Volkmann <r.mark.volkmann at gmail.com> wrote:
> > On Jan 17, 2008 2:04 PM, Frank Font <mrfont at room4me.com> wrote:
> > > Hello,
> > >
> > > I purchased the book, read through it, but I have a thick skull.
> > > Perhaps I can get some advice here on two questions about converting
> > > formula expressions that look like "basic" syntax...
> > >
> > > IF REP_DTE > '2001-01-01' AND ATOTAL>100 THEN
> > > H-CAPRESTATE
> > > ELSE
> > > IF REP_DTE < '2001-01-01' THEN
> > > ACCTG_CNG + ACCTG_ERR_CRCT
> > > END IF
> > > END IF
> > >
> > > Into a flat format that looks like Excel formula syntax...
> > >
> > > IF( AND(REP_DTE > '2001-01-01',ATOTAL>100), H-CAPRESTATE, IF(REP_DTE <
> > > '2001-01-01', ACCTG_CNG + ACCTG_ERR_CRCT)
> > >
> > > I tried writing a few grammar files, but all have had various runtime
> > > issues.
> > >
> > > Here are my questions...
> > >
> > > 1. Is ANTLR the right tool for this job? (I don't have much time.)
> >
> > ANTLR can definitely do this. However, you shouldn't expect the work
> > to go quickly if this is your first ANTLR grammar. You'll be learning
> > lots of things along the way.
> >
> > > 2. If it is the right tool, is there already a grammar that will get me
> > > most of the way there?
> >
> > I'm not aware of a particular existing grammar that is close to what
> > you want. Maybe someone else knows of one.
> >
> >
> > > Thanks in advance for any advice.
> > >
> > > Regards,
> > > Frank Font
> >
> > --
> > R. Mark Volkmann
> > Object Computing, Inc.
> >
>
>
>
> --
> R. Mark Volkmann
> Object Computing, Inc.
>
--
R. Mark Volkmann
Object Computing, Inc.
More information about the antlr-interest
mailing list