Well, between real life obligations and several design flaws, I’m about a week behind my last schedule. I’ve completely rewritten the backtracking and discard management systems, and I think they are both now mostly correct. I’ve got to take a final (I hope) pass on error recovery, then do code generation, and out the door it goes.
Here’s my latest test grammar (the test case follows). You may notice a few changes in the grammar. Priority direction is now configurable. “ignore” tokens are now called “discard” tokens. And they actually work, now.
grammar Math
priority ascending
start_rule program
discard whitespace
discard eol
strings
eol => '\n'
whitespace => [ \t\r]+
digit => [0-9]
integer => digit+
identifier_first_char => [a-zA-Z_]
identifier_char => [{identifier_first_char}{digit}]
identifier => identifier_first_char identifier_char*
end
program => statement+
group expression
integer
identifier
subexpression => '(' expression ')'
addition_expression => expression:lhs '+' expression:rhs @associativity=left
subtraction_expression => expression:lhs '-' expression:rhs @associativity=left
multiplication_expression => expression:lhs '*' expression:rhs @associativity=left
division_expression => expression:lhs '/' expression:rhs @associativity=left
special_expression => expression '*' expression '*' '(' identifier ')'
end
reorder
addition_expression substraction_expression
multiplication_expression division_expression
end
group statement
assignment_statement => identifier '=' expression eol:ignore ;
if_statement => 'if' '(' expression ')' '{' statement* '}' ;
if_lookalike => 'if' subexpression '{' statement* '}' 'booya' eol:ignore ;
end
end
Here’s the test case:
a = ((10 - 3)
)
b = 20
id = 10
if( 10 * 7 * (id) )
{
a = 10 * 7 * (id)
b = 18 * 3 * (37) - 19 * 4 * (37)
c = 12 - 14 - 27 * 36
}
if (10 - 3
)
{
a = 10 *
7
}
booya
b = 20
And the resulting tree:
Math.program
statements:
[0]:
Math.assignment_statement
identifier:
[a]:Math.identifier
expression:
Math.subexpression
expression:
Math.subexpression
expression:
Math.subtraction_expression
lhs:
[10]:Math.integer
rhs:
[3]:Math.integer
[1]:
Math.assignment_statement
identifier:
[b]:Math.identifier
expression:
[20]:Math.integer
[2]:
Math.assignment_statement
identifier:
[id]:Math.identifier
expression:
[10]:Math.integer
[3]:
Math.if_statement
expression:
Math.special_expression
expression_1:
[10]:Math.integer
expression_2:
[7]:Math.integer
identifier:
[id]:Math.identifier
statements:
[0]:
Math.assignment_statement
identifier:
[a]:Math.identifier
expression:
Math.special_expression
expression_1:
[10]:Math.integer
expression_2:
[7]:Math.integer
identifier:
[id]:Math.identifier
[1]:
Math.assignment_statement
identifier:
[b]:Math.identifier
expression:
Math.subtraction_expression
lhs:
Math.multiplication_expression
lhs:
Math.multiplication_expression
lhs:
[18]:Math.integer
rhs:
[3]:Math.integer
rhs:
Math.subexpression
expression:
[37]:Math.integer
rhs:
Math.multiplication_expression
lhs:
Math.multiplication_expression
lhs:
[19]:Math.integer
rhs:
[4]:Math.integer
rhs:
Math.subexpression
expression:
[37]:Math.integer
[2]:
Math.assignment_statement
identifier:
[c]:Math.identifier
expression:
Math.subtraction_expression
lhs:
Math.subtraction_expression
lhs:
[12]:Math.integer
rhs:
[14]:Math.integer
rhs:
Math.multiplication_expression
lhs:
[27]:Math.integer
rhs:
[36]:Math.integer
[4]:
Math.if_lookalike
subexpression:
Math.subexpression
expression:
Math.subtraction_expression
lhs:
[10]:Math.integer
rhs:
[3]:Math.integer
statements:
[0]:
Math.assignment_statement
identifier:
[a]:Math.identifier
expression:
Math.multiplication_expression
lhs:
[10]:Math.integer
rhs:
[7]:Math.integer
[5]:
Math.assignment_statement
identifier:
[b]:Math.identifier
expression:
[20]:Math.integer
| in Announcements: | |
| on site: |
Markdown: The kinds of formatting markup you'd use in an email will probably work here. For more details on what you can do, check out the Markdown docs.