So lets say I have the following grammar:
let_stat = "let" iden [ "=" expr ];
if_stat = "if" expr "->" stat;
stat = let_stat | if_stat;
This would be the following psuedo-ish code:
let_stat parseLetStat() {
if token is "let" {
consume token
if token is identifier {
char *value = consumetoken.value
let_stat let = new let_stat;
let.name = value;
if token is "=" {
let.value = parseExpression;
}
return let
}
}
}
if_stat parseIfStat() {
if token is "if" {
consume token
expression expr = parseExpression;
block block = parseBlock;
if_stat ifstmt = new if_stat
ifstmt.expr = expr
ifstmt.block = block
return ifstmt
}
}
stat parseStatement() {
}
What would the parseStatement
function do? How would it choose which function to call, the if_stat function, or the let_stat function? Or would I throw all the code into one function? I don't quite understand, any help would be great since I'm confused.
To get the children of an element, you use the childNodes property of the element. How it works: First, select the element whose id is container using the querySelector() method. Then, use the childNodes property to get the children of the container elements.
Any subnode of a given node is called a child node, and the given node, in turn, is the child's parent. Sibling nodes are nodes on the same hierarchical level under the same parent node. Nodes higher than a given node in the same lineage are ancestors and those below it are descendants.
The key issue for your specific problem is that when there is alternation in an EBNF rule, the parser for the nonterminal must call all the alternatives and ask each if it recognizes the construct; each subparser has to return a flag indicating yes or no.
What you probably need are general principles for writing a recursive descent parser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With