Skip to content
Snippets Groups Projects
Commit 495344f3 authored by Henrik (Grubba) Grubbström's avatar Henrik (Grubba) Grubbström
Browse files

Added pikedoc-comments

Rev: lib/modules/LR.pmod/Grammar_parser.pmod:1.3
Rev: lib/modules/LR.pmod/item.pike:1.2
Rev: lib/modules/LR.pmod/kernel.pike:1.2
Rev: lib/modules/LR.pmod/parser.pike:1.2
Rev: lib/modules/LR.pmod/priority.pike:1.2
Rev: lib/modules/LR.pmod/rule.pike:1.2
parent 7a416408
No related branches found
No related tags found
No related merge requests found
#!/home/grubba/src/pike/build/sol2.5/pike
/*
* $Id: Grammar_parser.pmod,v 1.2 1997/03/28 14:42:43 grubba Exp $
* $Id: Grammar_parser.pmod,v 1.3 1997/03/30 17:28:17 grubba Exp $
*
* Generates a parser from a textual specification.
*
* Henrik Grubbstrm 1996-12-06
*/
//.
//. File: Grammar_parser.pmod
//. RCSID: $Id: Grammar_parser.pmod,v 1.3 1997/03/30 17:28:17 grubba Exp $
//. Author: Henrik grubbstrm (grubba@infovav.se)
//.
//. Synopsis: Generates an LR parser from a textual specification.
//.
//. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. This module generates an LR parser from a grammar specified according
//. to the following grammar:
//.
//. directives : directive ;
//. directives : directives directive ;
//. directive : declaration ;
//. directive : rule ;
//. declaration : "%token" terminals ";" ;
//. rule : nonterminal ":" symbols ";" ;
//. rule : nonterminal ":" symbols action ";" ;
//. symbols : symbol ;
//. symbols : symbols symbol ;
//. terminals : terminal ;
//. terminals : terminals terminal ;
//. symbol : nonterminal ;
//. symbol : "string" ;
//. action : "{" "identifier" "}" ;
//. nonterminal : "identifier" ;
//. terminal : "string";
//.
/*
* Includes
*/
......@@ -28,13 +58,13 @@
import LR;
private object(parser) _parser = parser();
static private object(parser) _parser = parser();
/*
* Scanner
*/
class scan {
static private class scan {
string str = "";
int pos;
......@@ -130,9 +160,9 @@ class scan {
}
}
private object(scan) scanner = scan();
static private object(scan) scanner = scan();
private array(string) nonterminals = ({
static private array(string) nonterminals = ({
"translation_unit",
"directives",
"directive",
......@@ -147,17 +177,19 @@ private array(string) nonterminals = ({
"priority",
});
private object(Stack.stack) id_stack = Stack.stack();
static private object(Stack.stack) id_stack = Stack.stack();
private mapping(string:int) nonterminal_lookup = ([]);
static private mapping(string:int) nonterminal_lookup = ([]);
private object(parser) g;
static private object(parser) g;
private object master;
static private object master;
//. + error
//. Error code from the parsing.
int error;
private int add_nonterminal(string id)
static private int add_nonterminal(string id)
{
int nt = nonterminal_lookup[id];
......@@ -168,7 +200,7 @@ private int add_nonterminal(string id)
return(nt);
}
private void add_tokens(array(string) tokens)
static private void add_tokens(array(string) tokens)
{
/* NOOP */
#if 0
......@@ -178,7 +210,7 @@ private void add_tokens(array(string) tokens)
#endif /* 0 */
}
private void set_left_tokens(string ignore, int pri_val, array(string) tokens)
static private void set_left_tokens(string ignore, int pri_val, array(string) tokens)
{
foreach (tokens, string token) {
g->set_associativity(token, -1); /* Left associative */
......@@ -186,7 +218,7 @@ private void set_left_tokens(string ignore, int pri_val, array(string) tokens)
}
}
private string internal_symbol_to_string(int|string symbol)
static private string internal_symbol_to_string(int|string symbol)
{
if (intp(symbol)) {
return (nonterminals[symbol]);
......@@ -195,7 +227,7 @@ private string internal_symbol_to_string(int|string symbol)
}
}
private string symbol_to_string(int|string symbol)
static private string symbol_to_string(int|string symbol)
{
if (intp(symbol)) {
if (symbol < id_stack->ptr) {
......@@ -209,7 +241,7 @@ private string symbol_to_string(int|string symbol)
}
}
private void add_rule(int nt, string colon, array(mixed) symbols, string action)
static private void add_rule(int nt, string colon, array(mixed) symbols, string action)
{
if (action == ";") {
action = 0;
......@@ -286,6 +318,14 @@ void create()
_parser->compile();
}
//. - make_parser
//.
//. Compiles the parser-specification given in the first argument.
//. Named actions are taken from the object if available, otherwise
//. left as is.
//.
//. BUGS: Returns error-code in both Grammar_parser.error and
//. return_value->error.
object(parser) make_parser(string str, object|void m)
{
object(parser) res = 0;
......@@ -328,6 +368,11 @@ object(parser) make_parser(string str, object|void m)
return (res);
}
//. - make_parser_from_file
//.
//. Compiles the file specified in the first argument into an LR parser.
//.
//. SEE ALSO: Grammar_parser.make_parser
int|object(parser) make_parser_from_file(string f, object|void m)
{
object(files.file) f = files.file();
......
/*
* $Id: item.pike,v 1.1 1997/03/03 23:50:15 grubba Exp $
* $Id: item.pike,v 1.2 1997/03/30 17:28:20 grubba Exp $
*
* An LR(0) item
*
* Henrik Grubbström 1996-11-27
*/
//.
//. File: item.pike
//. RCSID: $Id: item.pike,v 1.2 1997/03/30 17:28:20 grubba Exp $
//. Author: Henrik Grubbström (grubba@infovav.se)
//.
//. Synopsis: An LR(0) item
//.
//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. A partially parsed rule.
//.
import LR;
/* constant kernel = (program)"kernel"; */
/* constant item = (program)"item"; */
/* The rule */
//. + r
//. The rule
object(rule) r;
/* How long into the rule the parsing has come */
//. + offset
//. How long into the rule the parsing has come.
int offset;
/* The state we will get if we shift */
//. + next_state
//. The state we will get if we shift according to this rule
object /* (kernel) */ next_state;
/* Item representing this one (used for shifts) */
//. + master_item
//. Item representing this one (used for shifts).
object /* (item) */ master_item = 0;
/* Look-ahead set for this item */
//. + direct_lookahead
//. Look-ahead set for this item.
multiset(string) direct_lookahead = (<>);
//. + error_lookahead
//. Look-ahead set used for detecting conflicts
multiset(string) error_lookahead = (<>);
/* Relation to other items (used when compiling) */
//. + relation
//. Relation to other items (used when compiling).
multiset(object /* (item) */ ) relation = (<>);
/* Depth counter (used when compiling) */
//. + counter
//. Depth counter (used when compiling).
int counter = 0;
/*
* $Id: kernel.pike,v 1.1 1997/03/03 23:50:16 grubba Exp $
* $Id: kernel.pike,v 1.2 1997/03/30 17:28:22 grubba Exp $
*
* Implements a LR(1) state;
*
* Henrik Grubbström 1996-11-25
*/
//.
//. File: kernel.pike
//. RCSID: $Id: kernel.pike,v 1.2 1997/03/30 17:28:22 grubba Exp $
//. Author: Henrik Grubbström
//.
//. Synopsis: Implements an LR(1) state.
//.
//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. State in the LR(1) state-machine.
//.
import LR;
/* Used to check if a rule already has been added when doing closures */
//. + rules
//. Used to check if a rule already has been added when doing closures.
multiset(object(rule)) rules = (<>);
/* Contains the items in this state */
//. + items
//. Contains the items in this state.
array(object(item)) items = ({});
/* Contains the items whose next symbol is this non-terminal */
//. + symbol_items
//. Contains the items whose next symbol is this non-terminal.
mapping(int : multiset(object(item))) symbol_items = ([]);
/* The action table for this state
*
* object(kernel) SHIFT to this state on this symbol.
* object(rule) REDUCE according to this rule on this symbol.
*/
//. + action
//. The action table for this state
//.
//. object(kernel) SHIFT to this state on this symbol.
//. object(rule) REDUCE according to this rule on this symbol.
mapping(int|string : object /* (kernel) */|object(rule)) action = ([]);
/*
* Functions
*/
//. - add_item
//. Add an item to the state.
//. > i
//. Item to add.
void add_item(object(item) i)
{
int|string symbol;
......@@ -44,6 +63,10 @@ void add_item(object(item) i)
}
}
//. - equalp
//. Compare with another state.
//. > state
//. State to compare with.
int equalp(object /* (kernel) */ state)
{
/* Two states are the same if they contain the same items */
......
/*
* $Id: parser.pike,v 1.1 1997/03/03 23:50:18 grubba Exp $
* $Id: parser.pike,v 1.2 1997/03/30 17:28:25 grubba Exp $
*
* A BNF-grammar in Pike.
* Compiles to a LALR(1) state-machine.
......@@ -7,6 +7,26 @@
* Henrik Grubbström 1996-11-24
*/
//.
//. File: parser.pike
//. RCSID: $Id: parser.pike,v 1.2 1997/03/30 17:28:25 grubba Exp $
//. Author: Henrik Grubbström (grubba@infovav.se)
//.
//. Synopsis: LALR(1) parser and compiler.
//.
//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. This object implements an LALR(1) parser and compiler.
//.
//. Normal use of this object would be:
//.
//. {add_rule, set_priority, set_associativity}*
//. set_scanner
//. set_symbol_to_string
//. compile
//. {parse}*
//.
/*
* Includes
*/
......@@ -39,14 +59,25 @@
* Classes
*/
//. o state_queue
//.
//. This is a combined set and queue.
class state_queue {
/*
* This is a combined set and queue.
*/
int head, tail;
//. + head
//. Index of the head of the queue.
int head;
//. + tail
//. Index of the tail of the queue.
int tail;
//. + arr
//. The queue/set itself.
array(object(LR.kernel)) arr=allocate(64);
//. - memberp
//. Returns the index of the state in arr if present.
//. Returns -1 on failure.
//. > state
//. State to search for.
int|object(LR.kernel) memberp(object(LR.kernel) state)
{
int j;
......@@ -59,6 +90,10 @@ class state_queue {
return(-1);
}
//. - push_if_new
//. Pushes the state on the queue if it isn't there already.
//. > state
//. State to push.
object(LR.kernel) push_if_new(object(LR.kernel) state)
{
int index;
......@@ -75,6 +110,8 @@ class state_queue {
}
}
//. - next
//. Return the next state from the queue.
int|object(LR.kernel) next()
{
if (head == tail) {
......@@ -110,13 +147,14 @@ static private mapping(int : multiset(object(rule))) used_by = ([]);
static private object(kernel) start_state;
/* Verbosity level
* 0 - none
* 1 - some
*/
//. + verbose
//. Verbosity level
//. 0 - none
//. 1 - some
int verbose=1;
/* Error code */
//. + error
//. Error code
int error=0;
/* Number of next rule (used only for conflict resolving) */
......@@ -141,20 +179,28 @@ static private string builtin_symbol_to_string(int|string symbol)
static private function(int|string : string) symbol_to_string = builtin_symbol_to_string;
//. - rule_to_string
//. Pretty-prints a rule to a string.
//. > r
//. Rule to print.
string rule_to_string(object(rule) r)
{
array(string) res = ({ symbol_to_string(r->nonterminal), ":\t" });
string res = symbol_to_string(r->nonterminal) + ":\t";
if (sizeof(r->symbols)) {
foreach (r->symbols, int|string symbol) {
res += ({ symbol_to_string(symbol), " " });
res += symbol_to_string(symbol) + " ";
}
} else {
res += ({ "/* empty */" });
res += "/* empty */";
}
return(res * "");
return(res);
}
//. - item_to_string
//. Pretty-prints an item to a string.
//. > i
//. Item to pretty-print.
string item_to_string(object(item) i)
{
array(string) res = ({ symbol_to_string(i->r->nonterminal), ":\t" });
......@@ -178,11 +224,17 @@ string item_to_string(object(item) i)
return(res * "");
}
//. - state_to_string
//. Pretty-prints a state to a string.
//. > state
//. State to pretty-print.
string state_to_string(object(kernel) state)
{
return (map(state->items, item_to_string) * "\n");
}
//. - cast_to_string
//. Pretty-prints the current grammar to a string.
string cast_to_string()
{
array(string) res = ({});
......@@ -205,6 +257,10 @@ string cast_to_string()
return (res * "");
}
//. - cast
//. Implements casting.
//. > type
//. Type to cast to.
mixed cast(string type)
{
if (type == "string") {
......@@ -215,6 +271,12 @@ mixed cast(string type)
/* Here come the functions that actually do some work */
//. - set_priority
//. Sets the priority of a terminal.
//. > terminal
//. Terminal to set the priority for.
//. > pri_val
//. Priority; higher = prefer this terminal.
void set_priority(string terminal, int pri_val)
{
object(priority) pri;
......@@ -226,6 +288,12 @@ void set_priority(string terminal, int pri_val)
}
}
//. - set_associativity
//. Sets the associativity of a terminal.
//. > terminal
//. Terminal to set the associativity for.
//. > assoc
//. Associativity; negative - left, positive - right, zero - no associativity.
void set_associativity(string terminal, int assoc)
{
object(priority) pri;
......@@ -237,7 +305,14 @@ void set_associativity(string terminal, int assoc)
}
}
void set_symbol_to_string(function(int|string:string) s_to_s)
//. - set_symbol_to_string
//. Sets the symbol to string conversion function.
//. The conversion function is used by the various *_to_string functions
//. to make comprehensible output.
//. > s_to_s
//. Symbol to string conversion function.
//. If zero or not specified, use the built-in function.
void set_symbol_to_string(void|function(int|string:string) s_to_s)
{
if (s_to_s) {
symbol_to_string = s_to_s;
......@@ -246,7 +321,10 @@ void set_symbol_to_string(function(int|string:string) s_to_s)
}
}
/* Add a rule to the grammar */
//. - add_rule
//. Add a rule to the grammar.
//. > r
//. Rule to add.
void add_rule(object(rule) r)
{
array(object(rule)) rules;
......@@ -946,6 +1024,8 @@ static private int repair(object(kernel) state, multiset(int|string) conflicts)
}
}
//. - compile
//. Compiles the grammar into a parser, so that parse() can be called.
int compile()
{
int error = 0; /* No error yet */
......@@ -1161,6 +1241,22 @@ int compile()
return (error);
}
//. - parse
//. Parse the input according to the compiled grammar.
//. The last value reduced is returned.
//. NOTA BENE:
//. The parser must have been compiled (with compile()), and a scanner
//. been set (with set_scanner()) prior to calling this function.
//. BUGS
//. Errors should be throw()n.
//. > scanner
//. The scanner function. It returns the next symbol from the input.
//. It should either return a string (terminal) or an array with
//. a string (terminal) and a mixed (value).
//. EOF is indicated with the empty string.
//. > action_object
//. Object used to resolve those actions that have been specified as
//. strings.
mixed parse(function(void:string|array(string|mixed)) scanner,
void|object action_object)
{
......
/*
* $Id: priority.pike,v 1.1 1997/03/03 23:50:19 grubba Exp $
* $Id: priority.pike,v 1.2 1997/03/30 17:28:27 grubba Exp $
*
* Rule priority specification
*
* Henrik Grubbstrm 1996-12-05
*/
/* Priority value */
//.
//. File: priority.pike
//. RCSID: $Id: priority.pike,v 1.2 1997/03/30 17:28:27 grubba Exp $
//. Author: Henrik Grubbstrm (grubba@infovav.se)
//.
//. Synopsis: Rule priority specification.
//.
//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. Specifies the priority and associativity of a rule.
//.
//. + value
//. Priority value
int value;
/* Associativity
*
* -1 - left
* 0 - none
* +1 - right
*/
//. + assoc
//. Associativity
//.
//. -1 - left
//. 0 - none
//. +1 - right
int assoc;
//. - create
//. Create a new priority object.
//. > p
//. Priority.
//. > a
//. Associativity.
void create(int p, int a)
{
value = p;
......
/*
* $Id: rule.pike,v 1.1 1997/03/03 23:50:21 grubba Exp $
* $Id: rule.pike,v 1.2 1997/03/30 17:28:28 grubba Exp $
*
* A BNF-rule.
*
* Henrik Grubbström 1996-11-24
*/
//.
//. File: rule.pike
//. RCSID: $Id: rule.pike,v 1.2 1997/03/30 17:28:28 grubba Exp $
//. Author: Henrik Grubbström (grubba@infovav.se)
//.
//. Synopsis: Implements a BNF rule.
//.
//. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//.
//. This object is used to represent a BNF-rule in the LR parser.
//.
/*
* Object variables
*/
/* Nonterminal this rule reduces to */
//. + nonterminal
//. Non-terminal this rule reduces to.
int nonterminal;
/* The actual rule */
//. + symbols
//. The actual rule
array(string|int) symbols;
/* Action to do when reducing this rule
*
* function - call this function
* string - call this function by name in the object given to the parser
*/
//. + action
//. Action to do when reducing this rule.
//. function - call this function.
//. string - call this function by name in the object given to the parser.
//. The function is called with arguments corresponding to the values of
//. the elements of the rule. The return value of the function will be
//. the value of this non-terminal. The default rule is to return the first
//. argument.
function|string action;
/* Variables used when compiling */
/* This rule contains tokens */
//. + has_tokens
//. This rule contains tokens
int has_tokens = 0;
/* This rule has this many nonnullable symbols at the moment */
//. + num_nonnullables
//. This rule has this many non-nullable symbols at the moment.
int num_nonnullables = 0;
/*
......@@ -33,13 +52,40 @@ multiset(int) prefix_nonterminals = (<>);
multiset(string) prefix_tokens = (<>);
*/
/* Number of this rule (used for conflict resolving) */
//. + number
//. Sequence number of this rule (used for conflict resolving)
int number = 0;
/*
* Functions
*/
//. - create
//. Create a BNF rule.
//. EXAMPLE:
//. The rule
//.
//. rule : nonterminal ":" symbols ";" { add_rule };
//.
//. might be created as
//.
//. rule(4, ({ 9, ";", 5, ";" }), "add_rule");
//.
//. where 4 corresponds to the nonterminal "rule", 9 to "nonterminal"
//. and 5 to "symbols", and the function "add_rule" is too be called
//. when this rule is reduced.
//. > nt
//. Non-terminal to reduce to.
//. > r
//. Symbol sequence that reduces to nt.
//. > a
//. Action to do when reducing according to this rule.
//. function - Call this function.
//. string - Call this function by name in the object given to the parser.
//. The function is called with arguments corresponding to the values of
//. the elements of the rule. The return value of the function will be
//. the value of this non-terminal. The default rule is to return the first
//. argument.
void create(int nt, array(string|int) r, function|string|void a)
{
mixed symbol;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment