summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-11-01 10:35:19 -0500
committerAdrian Thurston <thurston@complang.org>2015-11-01 10:35:19 -0500
commit80b9fc661abe6f37853bc12889f0443a1d6c65a9 (patch)
tree156be0111d93e2b5f3ae56c41d2bc4bb5ef47e8c
parent0b175a8ed019785233618b3bb8e3c064e567f2ec (diff)
downloadcolm-80b9fc661abe6f37853bc12889f0443a1d6c65a9.tar.gz
allow access to rhs elements by number
-rw-r--r--colm.vim11
-rw-r--r--src/colm.lm5
-rw-r--r--src/loadcolm.cc12
-rw-r--r--src/parsetree.h3
-rw-r--r--src/reduce.cc88
5 files changed, 87 insertions, 32 deletions
diff --git a/colm.vim b/colm.vim
index 164d9708..3587601f 100644
--- a/colm.vim
+++ b/colm.vim
@@ -90,7 +90,7 @@ syntax region externalCode contained
\ contains=@redItems
\ end="}"
-syntax cluster redItems contains=redRef,redType,redKeyword,redLiteral,redComment,externalCode
+syntax cluster redItems contains=redRef,redType,redKeyword,redNumber,redIdentifier,redLiteral,redComment,externalCode
syntax region redComment start="\/\*" end="\*\/" contained
syntax match redComment "\/\/.*$" contained
@@ -101,6 +101,14 @@ syntax match redLiteral "\"\(\\.\|[^\"\\]\)*\""
syntax match redRef "\$\$" contained
syntax match redRef "\$[a-zA-Z_][a-zA-Z0-9_]*" contained
syntax match redRef "@[a-zA-Z_][a-zA-Z0-9_]*" contained
+syntax match redRef "\$[0-9]\+" contained
+syntax match redRef "@[0-9]\+" contained
+
+syntax match redNumber "[0-9][0-9]*" contained
+syntax match redNumber "true" contained
+syntax match redNumber "false" contained
+
+syntax match redIdentifier "[a-zA-Z_][a-zA-Z_0-9]*" contained
syntax keyword redType unsigned signed void char short int long float double bool
syntax keyword redType inline static extern register const volatile auto
@@ -138,5 +146,6 @@ hi link redKeyword Keyword
hi link redLiteral String
hi link redRef Function
hi link redComment Comment
+hi link redNumber Number
let b:current_syntax = "colm"
diff --git a/src/colm.lm b/src/colm.lm
index a74e53c9..9401ad47 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -364,6 +364,9 @@ lex
token RED_RHS_REF / '$' . red_id /
token RED_RHS_LOC / '@' . red_id /
+ token RED_RHS_NREF / '$' . ('1' .. '9') . ('0' .. '9')* /
+ token RED_RHS_NLOC / '@' . ('1' .. '9') . ('0' .. '9')* /
+
token red_any / any /
end
@@ -382,6 +385,8 @@ def host_item
| [RED_LHS]
| [RED_RHS_REF]
| [RED_RHS_LOC]
+| [RED_RHS_NREF]
+| [RED_RHS_NLOC]
| [RED_OPEN HostItems: host_item* RED_CLOSE]
def reduction_item
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 4829d519..54d3d4d2 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -2365,6 +2365,18 @@ struct LoadColm
rti->txt = item.RED_RHS_LOC().text().c_str();
list.append( rti );
}
+ else if ( item.RED_RHS_NREF() != 0 ) {
+ ReduceTextItem *rti = new ReduceTextItem;
+ rti->type = ReduceTextItem::RhsRef;
+ rti->n = atoi( item.RED_RHS_NREF().text().c_str() + 1 );
+ list.append( rti );
+ }
+ else if ( item.RED_RHS_NLOC() != 0 ) {
+ ReduceTextItem *rti = new ReduceTextItem;
+ rti->type = ReduceTextItem::RhsLoc;
+ rti->n = atoi( item.RED_RHS_NLOC().text().c_str() + 1 );
+ list.append( rti );
+ }
else if ( item.RED_OPEN() != 0 ) {
ReduceTextItem *open = new ReduceTextItem;
open->type = ReduceTextItem::Txt;
diff --git a/src/parsetree.h b/src/parsetree.h
index 2e5bcb49..8bae78f0 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -926,8 +926,11 @@ struct ReduceTextItem
Txt
};
+ ReduceTextItem() : n(0) {}
+
Type type;
String txt;
+ int n;
ReduceTextItem *prev, *next;
};
diff --git a/src/reduce.cc b/src/reduce.cc
index 989329ee..84d635c1 100644
--- a/src/reduce.cc
+++ b/src/reduce.cc
@@ -69,15 +69,30 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list
}
if ( i->type == ReduceTextItem::RhsRef || i->type == ReduceTextItem::RhsLoc ) {
- String name( i->txt.data + 1, i->txt.length() - 1 );
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal; r.lte(); r++ ) {
- if ( r->prodEl->production == production ) {
- if ( i->type == ReduceTextItem::RhsLoc )
- locUsed[r->prodEl->pos] = r->prodEl;
- else
- rhsUsed[r->prodEl->pos] = r->prodEl;
+ if ( i->n > 0 ) {
+ ProdEl *prodEl = production->prodElList->head;
+ int adv = i->n - 1;
+ while ( adv > 0 ) {
+ prodEl = prodEl->next;
+ adv -= 1;
+ }
+
+ if ( i->type == ReduceTextItem::RhsLoc )
+ locUsed[i->n-1] = prodEl;
+ else
+ rhsUsed[i->n-1] = prodEl;
+ }
+ else {
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal; r.lte(); r++ ) {
+ if ( r->prodEl->production == production ) {
+ if ( i->type == ReduceTextItem::RhsLoc )
+ locUsed[r->prodEl->pos] = r->prodEl;
+ else
+ rhsUsed[r->prodEl->pos] = r->prodEl;
+ }
}
}
}
@@ -128,34 +143,44 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list
void Compiler::writeRhsRef( Production *production, ReduceTextItem *i )
{
- ObjectDef *objectDef = production->prodName->objectDef;
- String name( i->txt.data + 1, i->txt.length() - 1 );
-
- /* Find the field in the rhsVal using capture field. */
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal;
- r.lte(); r++ )
- {
- if ( r->prodEl->production == production )
- *outStream << "_rhs" << r->prodEl->pos;
+ if ( i->n > 0 ) {
+ *outStream << "_rhs" << ( i->n - 1 );
+ }
+ else {
+ ObjectDef *objectDef = production->prodName->objectDef;
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+
+ /* Find the field in the rhsVal using capture field. */
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal;
+ r.lte(); r++ )
+ {
+ if ( r->prodEl->production == production )
+ *outStream << "_rhs" << r->prodEl->pos;
+ }
}
}
}
void Compiler::writeRhsLoc( Production *production, ReduceTextItem *i )
{
- ObjectDef *objectDef = production->prodName->objectDef;
- String name( i->txt.data + 1, i->txt.length() - 1 );
-
- /* Find the field in the rhsVal using capture field. */
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal;
- r.lte(); r++ )
- {
- if ( r->prodEl->production == production )
- *outStream << "_loc" << r->prodEl->pos;
+ if ( i->n > 0 ) {
+ *outStream << "_loc" << ( i->n - 1 );
+ }
+ else {
+ ObjectDef *objectDef = production->prodName->objectDef;
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+
+ /* Find the field in the rhsVal using capture field. */
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal;
+ r.lte(); r++ )
+ {
+ if ( r->prodEl->production == production )
+ *outStream << "_loc" << r->prodEl->pos;
+ }
}
}
}
@@ -220,6 +245,7 @@ void Compiler::writeCommit()
"#include <stdlib.h>\n"
"#include <string.h>\n"
"#include <assert.h>\n"
+ "#include <errno.h>\n"
"\n"
"#include <iostream>\n"
"using std::endl;\n"