jGuru Forums

How to parse an expression
2 posts in topic
Flat View
TOPIC ACTIONS:

Posted By:   Anu_Bhargava
Posted On:   Tuesday, November 6, 2001 09:13 AM

Iam trying to build the grammar fiel for parsing expressions like ((a=b AND b=c)OR(b=d OR x=y)). Iam using the following grammar. class LangParser extends Parser; options { codeGenMakeSwitchThreshold = 3; codeGenBitsetTestThreshold = 4; buildAST=true; genHashLines = true; } block : LPAREN^ (statement)* RPAREN! ; statement : expr SEMI! | "if"^ LPAREN! expr RPAREN! statement ( "else"! statement )? | "while"^ LPAREN! expr RPAREN! statement |! b:block { statement_AST = b_AST; } // do some manual tree returning ; expr: ass   More>>

Iam trying to build the grammar fiel for parsing expressions like

((a=b AND b=c)OR(b=d OR x=y)).

Iam using the following grammar.

```
class LangParser extends Parser;

options {

codeGenMakeSwitchThreshold = 3;

codeGenBitsetTestThreshold = 4;

buildAST=true;

genHashLines = true;

}

block

:  LPAREN^ (statement)* RPAREN!

;

statement

: expr SEMI!

| "if"^ LPAREN! expr RPAREN! statement

( "else"! statement )?

| "while"^ LPAREN! expr RPAREN! statement

|! b:block { statement_AST = b_AST; }

// do some manual tree returning

;

expr: assignExpr

;

assignExpr

: aexpr (ASSIGN^ assignExpr)?

;

aexpr

: mexpr (AND^ mexpr)*

|       LPAREN^ (aexpr OR^ (mexpr))* RPAREN!

;

mexpr: atom ((OR^ | NOT^) atom)*

;

atom: ID

| STRING

;

class LangWalker extends TreeParser;

block

: #( LPAREN( stat )+ )

;

stat: #("if" expr stat (stat)?)

| #("while" expr stat)

| expr

| block

;

expr: #(ASSIGN expr expr)  {System.out.println("found assign");}

| #(AND expr expr) {System.out.println("found AND");}

| #(OR expr expr)  {System.out.println("found OR");}

|       #(NOT expr expr)        {System.out.println("found NOT");}

| a:ID   {System.out.println("found ID "+a.getText());}

| b:STRING  {System.out.println("found String "+b.getText());}

;

class LangLexer extends Lexer;

WS : (' '

| ' '

| '

'

| '

')

{ _ttype = Token.SKIP; }

;

LPAREN: '('

;

RPAREN: ')'

;

LCURLY: '{'

;

RCURLY: '}'

;

NOT:    '!'

;

OR: '|' ;

AND: '&'

;

ASSIGN

: '='

;

SEMI: ';'

;

COMMA

: ','

;

protected

ESC : '\\'

( 'n'

| 'r'

| 't'

| 'b'

| 'f'

| '"'

| '\''

| '\\'

)

;

protected

CHAR

: ('0'..'9'|'a'..'z'|'='|'A'..'Z')

;

STRING: (CHAR)+

;

ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*

{

String i = (String)literals.get(getText());

}

;

```

I am trying to use recursive rule.

Thanks
Anu    <<Less

Re: How to parse an expression

Posted By:   SRIRAM_SRINIVASAN
Posted On:   Tuesday, November 13, 2001 07:58 PM

Anu,

There is a mismatch between your example and the grammer.

Your example indicates a higher precedence for assignment than the other operators. That is, in (a=b AND c=d), I presume you want to have a=b and c=d evaluated first. Did you really have assignment or equality in mind here?
In any case, this is not what your grammar does.

Assuming you want the conventional expression grammar, I went ahead and corrected a few things in order to get it to compile.

There are three ambiguities in the parse grammar and one in the lexer.

A left paren starts both an expression and a block. No amount of lookahead can fix that. The easiest option is to make it look like c-like programming languages, and to have the block start with a different character, a left_curly.

`block  : LCURLY^ (statement)* RCURLY!`

You need to explicitly turn off the ambig warnings in the following two cases, because antlr does the right thing by default (being greedy).

`: "if"^ LPAREN! expr RPAREN! statement    (options warnWhenFollowAmbig=false;}: "else"! statement )?and,mexpr  : atom (options {warnWhenFollowAmbig=false;}:(OR^ | NOT^) atom)*`

The lexer has an ambiguity between ID and STRING. Both start with a letter.
I have a suspicion you meant to make STRING a literal in quotes.

Hope this helps.

-Sriram

Re: How to parse an expression

Posted By:   Vulcun_Louis
Posted On:   Wednesday, November 7, 2001 02:10 AM

First,

Use the

tag for indent that , :)