summaryrefslogtreecommitdiff
path: root/colm
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-12-14 16:23:58 +0200
committerAdrian Thurston <thurston@colm.net>2019-12-14 16:26:14 +0200
commit732f9db9e6a2d7919e316341de06501d38aaabcc (patch)
tree72e9cc35aebe85eaf55ec80a4dc6dfd29ae318f7 /colm
parente8152c296aa6fa9cee01104a95837756f4bf90fd (diff)
downloadcolm-732f9db9e6a2d7919e316341de06501d38aaabcc.tar.gz
testing left-recursive lists <* and <+ and sublists in productions
Using a transformation pass in prog.lm to create definitions for left-recursive productions and sub-productions. So far just a sketch. Not all production element forms are transformed and there can only be one sub-production in a whole program. refs #74 refs #83 refs #84
Diffstat (limited to 'colm')
-rw-r--r--colm/Makefile.am2
-rw-r--r--colm/colm.lm7
-rw-r--r--colm/ctinput.cc2
-rw-r--r--colm/loadcolm.cc15
-rw-r--r--colm/prog.lm66
5 files changed, 88 insertions, 4 deletions
diff --git a/colm/Makefile.am b/colm/Makefile.am
index ad2a78b2..fe594521 100644
--- a/colm/Makefile.am
+++ b/colm/Makefile.am
@@ -154,7 +154,7 @@ bootstrap2_LDADD = libprog.a libcolm.la
endif
-tar/bootstrap3.tar: $(BUILD_PARSE_3_WITH) prog.lm
+tar/bootstrap3.tar: $(BUILD_PARSE_3_WITH) prog.lm colm.lm
mkdir -p gen
$(BUILD_PARSE_3_WITH) -c -o tar/parse3.c -e tar/if3.h -x tar/if3.cc prog.lm
tar -C tar -cf tar/bootstrap3.tar parse3.c if3.h if3.cc
diff --git a/colm/colm.lm b/colm/colm.lm
index 1c475adc..efbd7a65 100644
--- a/colm/colm.lm
+++ b/colm/colm.lm
@@ -472,9 +472,14 @@ def opt_id
def ignore_def
[IGNORE opt_id LEX_FSLASH opt_lex_expr LEX_FSLASH]
+def prod_sublist
+ [prod_sublist BAR prod_el_list]
+| [prod_el_list]
+
def prod_el
[opt_prod_el_name region_qual id opt_repeat] :Id
| [opt_prod_el_name region_qual backtick_lit opt_repeat] :Lit
+| [opt_prod_el_name POPEN prod_sublist PCLOSE opt_repeat ] :SubList
def opt_prod_el_name
[id COLON] :Name
@@ -666,6 +671,8 @@ def opt_repeat
[STAR] :Star
| [PLUS] :Plus
| [QUESTION] :Question
+| [LT STAR] :LeftStar
+| [LT PLUS] :LeftPlus
| []
def opt_capture
diff --git a/colm/ctinput.cc b/colm/ctinput.cc
index 2adf2a94..bca2080a 100644
--- a/colm/ctinput.cc
+++ b/colm/ctinput.cc
@@ -459,7 +459,7 @@ int repl_undo_consume_data( struct colm_program *prg, struct input_impl_ct *ss,
/* Okay to go up to the front of the buffer. */
if ( length > avail ) {
- ss->cons_item= ss->cons_item->prev;
+ ss->cons_item = ss->cons_item->prev;
ss->offset = ss->cons_item->data.length();
length -= avail;
}
diff --git a/colm/loadcolm.cc b/colm/loadcolm.cc
index 694a88fd..ac64f668 100644
--- a/colm/loadcolm.cc
+++ b/colm/loadcolm.cc
@@ -844,6 +844,11 @@ struct LoadColm
case opt_repeat::Question:
repeatType = RepeatOpt;
break;
+ case opt_repeat::LeftStar:
+ case opt_repeat::LeftPlus:
+ error( OptRepeat.loc() ) << "<* and <+ are implemented as a "
+ "colm transformation, they are not accepted at this stage" << endp;
+ break;
}
return repeatType;
}
@@ -972,10 +977,10 @@ struct LoadColm
}
RepeatType repeatType = walkOptRepeat( El.opt_repeat() );
- NamespaceQual *nspaceQual = walkRegionQual( El.region_qual() );
-
switch ( El.prodName() ) {
case prod_el::Id: {
+ NamespaceQual *nspaceQual = walkRegionQual( El.region_qual() );
+
String typeName = El.id().data();
ProdEl *prodEl = prodElName( El.id().loc(), typeName,
nspaceQual, captureField, repeatType, false );
@@ -983,11 +988,17 @@ struct LoadColm
break;
}
case prod_el::Lit: {
+ NamespaceQual *nspaceQual = walkRegionQual( El.region_qual() );
+
String lit = El.backtick_lit().data();
ProdEl *prodEl = prodElLiteral( El.backtick_lit().loc(), lit,
nspaceQual, captureField, repeatType, false );
appendProdEl( list, prodEl );
break;
+ }
+ case prod_el::SubList: {
+ error( El.POPEN().loc() ) << "production sublist is implemented as a "
+ "colm transformation, it is not accepted at this stage" << endp;
}}
}
diff --git a/colm/prog.lm b/colm/prog.lm
index 43525993..e0ac8c22 100644
--- a/colm/prog.lm
+++ b/colm/prog.lm
@@ -7,5 +7,71 @@ A: str = argv->pop()
F: stream = open( A, 'r' )
parse P: start [ F ]
+def new_roots
+ [new_roots root_item]
+| []
+
+prod_list cons_prod( SLA: prod_sublist )
+{
+ if match SLA [Left: prod_sublist BAR prod_el_list]
+ return cons prod_list[ cons_prod(Left) ' | [ ' SLA.prod_el_list ' ] ' ]
+ else
+ return cons prod_list[ '[ ' SLA.prod_el_list ' ]' ]
+}
+
+void rewrite( P: ref<start> )
+{
+ Modified: bool = false
+ cons Additional: new_roots []
+
+ for PE: prod_el in P {
+ if match PE
+ [OptName: opt_prod_el_name POPEN PS: prod_sublist PCLOSE OptRep: opt_repeat]
+ {
+ PE = cons prod_el
+ [OptName "_sublist_" OptRep]
+
+ cons Def: cfl_def
+ "def _sublist_ [cons_prod(PS)]"
+
+ Additional = cons new_roots
+ [Additional Def]
+ }
+ else if match PE
+ [OptName: opt_prod_el_name Qual: region_qual Id: id "<*"]
+ {
+ parse LeftRepId: id "_lrep_[Id]"
+ PE = cons prod_el [OptName Qual LeftRepId]
+
+ cons Def: cfl_def "def [LeftRepId] \[[LeftRepId] [Id]\] | \[\]
+
+ Additional = cons new_roots [Additional Def]
+ }
+ else if match PE
+ [OptName: opt_prod_el_name Qual: region_qual Id: id "<+"]
+ {
+ parse LeftRepId: id "_lrep_[Id]"
+
+ PE = cons prod_el [OptName Qual LeftRepId]
+
+ cons Def: cfl_def "def [LeftRepId] \[[LeftRepId] [Id]\] | \[[Id]\]
+
+ Additional = cons new_roots [Additional Def]
+ }
+ }
+
+ while ( Additional.root_item ) {
+ P = cons start [Additional.root_item P.RootItemList]
+ Additional = Additional._new_roots
+ Modified = true
+ }
+ return Modified
+}
+
+if P {
+ while ( rewrite( P ) ) {}
+ #rewrite( P )
+}
+
ColmTree = P
ColmError = error